@awsui/components-react
Version:
On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en
107 lines • 7.43 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React from 'react';
import clsx from 'clsx';
import { InternalButton } from '../../button/internal';
import { Transition } from '../../internal/components/transition';
import customCssProps from '../../internal/generated/custom-css-properties';
import { useAppLayoutInternals } from './context';
import TriggerButton from './trigger-button';
import splitPanelTestUtilStyles from '../../split-panel/test-classes/styles.css.js';
import testutilStyles from '../test-classes/styles.css.js';
import styles from './styles.css.js';
/**
* The Tools component consists of the following elements:
* the container, or root element, that sits as a direct child to the Layout grid definition;
* the split panel, which exists only if there is a split panel in side position;
* the tools, or drawer, that contains the hide tools form and the children passed through the API;
* the show tools form that contains the triggers for both the drawer and the
* split panel in large viewports;
*/
export default function Tools({ children }) {
const { ariaLabels, disableBodyScroll, drawers, handleSplitPanelClick, handleToolsClick, hasDrawerViewportOverlay, isMobile, isSplitPanelOpen, isToolsOpen, loseToolsFocus, splitPanel, splitPanelControlId, splitPanelDisplayed, splitPanelPosition, splitPanelRefs, splitPanelToggle, tools, toolsControlId, toolsHide, toolsRefs, toolsWidth, headerVariant, } = useAppLayoutInternals();
const hasSplitPanel = !!splitPanel && splitPanelPosition === 'side';
const hasToolsForm = getToolsFormStatus(hasSplitPanel && splitPanelDisplayed, isMobile, isSplitPanelOpen, isToolsOpen, toolsHide);
const hasToolsFormPersistence = getToolsFormPersistence(hasSplitPanel, isSplitPanelOpen, isToolsOpen, toolsHide);
const isUnfocusable = hasDrawerViewportOverlay && !isToolsOpen;
/**
* If the drawers property is defined the SplitPanel will be mounted and rendered
* by the Drawers component.
*/
if ((toolsHide && !hasSplitPanel) || drawers) {
return null;
}
return (React.createElement(Transition, { in: isToolsOpen !== null && isToolsOpen !== void 0 ? isToolsOpen : false }, (state, transitionEventsRef) => {
var _a, _b, _c;
return (React.createElement("div", { className: clsx(styles['tools-container'], {
[styles['disable-body-scroll']]: disableBodyScroll,
[styles.unfocusable]: isUnfocusable,
}), style: {
[customCssProps.toolsAnimationStartingOpacity]: `${hasSplitPanel && isSplitPanelOpen ? 1 : 0}`,
[customCssProps.toolsWidth]: `${toolsWidth}px`,
}, onBlur: e => {
if (!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) {
loseToolsFocus();
}
} },
children,
!toolsHide && (React.createElement("aside", { id: toolsControlId, "aria-hidden": !isToolsOpen ? true : false, "aria-label": (_a = ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.tools) !== null && _a !== void 0 ? _a : undefined, className: clsx(styles.tools, {
[styles.animating]: state === 'entering',
[styles['has-tools-form-persistence']]: hasToolsFormPersistence,
[styles['is-tools-open']]: isToolsOpen,
[testutilStyles['drawer-closed']]: !isToolsOpen,
}, testutilStyles.tools), ref: state !== 'exiting' ? transitionEventsRef : undefined },
React.createElement("div", { className: styles['animated-content'] },
React.createElement("div", { className: styles['hide-tools'] },
React.createElement(InternalButton, { ariaLabel: (_b = ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.toolsClose) !== null && _b !== void 0 ? _b : undefined, iconName: isMobile ? 'close' : 'angle-right', onClick: () => handleToolsClick(false), variant: "icon", formAction: "none", className: testutilStyles['tools-close'], ref: toolsRefs.close })),
tools))),
!isMobile && (React.createElement("aside", { "aria-hidden": !hasToolsForm ? true : false, "aria-label": (_c = ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.tools) !== null && _c !== void 0 ? _c : undefined, className: clsx(styles['show-tools'], {
[styles.animating]: state === 'exiting',
[styles['has-tools-form']]: hasToolsForm,
[styles['has-tools-form-persistence']]: hasToolsFormPersistence,
}), ref: state === 'exiting' ? transitionEventsRef : undefined, "data-testid": "side-split-panel-drawer" },
!toolsHide && (React.createElement(TriggerButton, { ariaLabel: ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.toolsToggle, ariaControls: toolsControlId, ariaExpanded: isToolsOpen, iconName: "status-info", onClick: () => handleToolsClick(!isToolsOpen), selected: hasSplitPanel && isToolsOpen, className: testutilStyles['tools-toggle'], ref: toolsRefs.toggle, highContrastHeader: headerVariant === 'high-contrast' })),
hasSplitPanel && splitPanelToggle.displayed && (React.createElement(TriggerButton, { ariaLabel: splitPanelToggle.ariaLabel, ariaControls: splitPanelControlId, ariaExpanded: !!isSplitPanelOpen, iconName: "view-vertical", onClick: () => handleSplitPanelClick(), selected: hasSplitPanel && isSplitPanelOpen, className: splitPanelTestUtilStyles['open-button'], ref: splitPanelRefs.toggle, highContrastHeader: headerVariant === 'high-contrast' }))))));
}));
}
/**
* By default the Tools form is styled as display: none; This behavior should
* be unchanged in mobile viewports where the Tools form is always suppressed.
* In large viewports, however the Tools form and its corresponding buttons
* should be present in the UI under the below circumstances.
*/
function getToolsFormStatus(hasSplitPanel, isMobile, isSplitPanelOpen, isToolsOpen, toolsHide) {
let hasToolsForm = false;
if (!isMobile) {
// Both the Split Panel and Tools button are needed
if (hasSplitPanel && !toolsHide) {
hasToolsForm = true;
}
// The Split Panel button is needed
if (hasSplitPanel && !isSplitPanelOpen && toolsHide) {
hasToolsForm = true;
}
// The Tools button is needed
if (!hasSplitPanel && !toolsHide && !isToolsOpen) {
hasToolsForm = true;
}
}
return hasToolsForm;
}
/**
* Under two scenarios the Tools form that contains the triggers
* for the Tools content and the Split Panel may be persistent
* in the UI (as opposed to disappearing when one of the drawers
* is open). This will also add a white background as opposed to the
* default transparent background. The buttons will present and in a
* selected / not selected state.
*/
function getToolsFormPersistence(hasSplitPanel, isSplitPanelOpen, isToolsOpen, toolsHide) {
let hasToolsFormPersistence = false;
// Both Tools and Split Panel exist and one or both is open
if (hasSplitPanel && !toolsHide && (isSplitPanelOpen || isToolsOpen)) {
hasToolsFormPersistence = true;
}
return hasToolsFormPersistence;
}
//# sourceMappingURL=tools.js.map