@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
85 lines • 6.74 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useEffect, useRef } from 'react';
import clsx from 'clsx';
import { useResizeObserver } from '@awsui/component-toolkit/internal';
import { createWidgetizedComponent } from '../../../internal/widgets';
import { BreadcrumbsSlot } from '../skeleton/breadcrumbs';
import { ToolbarSkeleton } from '../skeleton/slot-skeletons';
import { ToolbarSlot } from '../skeleton/slot-wrappers';
import { DrawerTriggers } from './drawer-triggers';
import TriggerButton from './trigger-button';
import testutilStyles from '../../test-classes/styles.css.js';
import styles from './styles.css.js';
export function AppLayoutToolbarImplementation({ appLayoutInternals,
// the value could be undefined if this component is loaded as a widget by a different app layout version
// not testable in a single-version setup
toolbarProps = {}, }) {
var _a, _b, _c;
const { breadcrumbs, discoveredBreadcrumbs, verticalOffsets, isMobile, toolbarState, setToolbarState, setToolbarHeight, } = appLayoutInternals;
const { ariaLabels, activeDrawerId, drawers, drawersFocusRef, onActiveDrawerChange, globalDrawersFocusControl, globalDrawers, activeGlobalDrawersIds, onActiveGlobalDrawersChange, hasNavigation, navigationOpen, navigationFocusRef, onNavigationToggle, hasSplitPanel, splitPanelFocusRef, splitPanelToggleProps, onSplitPanelToggle, } = toolbarProps;
// TODO: expose configuration property
const pinnedToolbar = true;
const ref = useRef(null);
useResizeObserver(ref, entry => setToolbarHeight(entry.borderBoxHeight));
useEffect(() => {
return () => {
setToolbarHeight(0);
};
// unmount effect only
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
let lastScrollY = window.scrollY;
/* istanbul ignore next not testable in JSDOM */
const updateScrollDirection = () => {
if (pinnedToolbar) {
setToolbarState('show');
return;
}
const scrollY = window.scrollY;
// 80 is an arbitrary number to have a pause before the toolbar scrolls out of view at the top of the page
const direction = scrollY > lastScrollY && scrollY > 80 ? 'hide' : 'show';
// 2 as a buffer to avoid mistaking minor accidental mouse moves as scroll
if (direction !== toolbarState && (scrollY - lastScrollY > 2 || scrollY - lastScrollY < -2)) {
setToolbarState(direction);
}
lastScrollY = scrollY > 0 ? scrollY : 0;
};
window.addEventListener('scroll', updateScrollDirection);
return () => {
window.removeEventListener('scroll', updateScrollDirection);
};
}, [pinnedToolbar, setToolbarState, toolbarState]);
const anyPanelOpenInMobile = !!isMobile && (!!activeDrawerId || (!!navigationOpen && !!hasNavigation));
useEffect(() => {
if (anyPanelOpenInMobile) {
document.body.classList.add(styles['block-body-scroll']);
}
else {
document.body.classList.remove(styles['block-body-scroll']);
}
return () => {
document.body.classList.remove(styles['block-body-scroll']);
};
}, [anyPanelOpenInMobile]);
const toolbarHidden = toolbarState === 'hide' && !pinnedToolbar;
const navLandmarkAttributes = navigationOpen
? { role: 'presentation' }
: { role: 'navigation', 'aria-label': ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.navigation };
return (React.createElement(ToolbarSlot, { ref: ref, className: clsx(styles['universal-toolbar'], testutilStyles.toolbar, {
[testutilStyles['mobile-bar']]: isMobile,
[styles['toolbar-hidden']]: toolbarHidden,
}), style: {
insetBlockStart: toolbarHidden ? '-60px' : verticalOffsets.toolbar,
} },
React.createElement("div", { className: styles['toolbar-container'] },
hasNavigation && (React.createElement("nav", Object.assign({}, navLandmarkAttributes, { className: clsx(styles['universal-toolbar-nav']) }),
React.createElement(TriggerButton, { ariaLabel: (_a = ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.navigationToggle) !== null && _a !== void 0 ? _a : undefined, ariaExpanded: false, iconName: "menu", className: testutilStyles['navigation-toggle'], onClick: () => onNavigationToggle === null || onNavigationToggle === void 0 ? void 0 : onNavigationToggle(!navigationOpen), ref: navigationFocusRef, selected: navigationOpen, disabled: anyPanelOpenInMobile }))),
(breadcrumbs || discoveredBreadcrumbs) && (React.createElement("div", { className: clsx(styles['universal-toolbar-breadcrumbs'], testutilStyles.breadcrumbs) },
React.createElement(BreadcrumbsSlot, { ownBreadcrumbs: appLayoutInternals.breadcrumbs, discoveredBreadcrumbs: appLayoutInternals.discoveredBreadcrumbs }))),
((drawers === null || drawers === void 0 ? void 0 : drawers.length) || (globalDrawers === null || globalDrawers === void 0 ? void 0 : globalDrawers.length) || (hasSplitPanel && (splitPanelToggleProps === null || splitPanelToggleProps === void 0 ? void 0 : splitPanelToggleProps.displayed))) && (React.createElement("div", { className: clsx(styles['universal-toolbar-drawers']) },
React.createElement(DrawerTriggers, { ariaLabels: ariaLabels, activeDrawerId: activeDrawerId !== null && activeDrawerId !== void 0 ? activeDrawerId : null, drawers: (_b = drawers === null || drawers === void 0 ? void 0 : drawers.filter(item => !!item.trigger)) !== null && _b !== void 0 ? _b : [], drawersFocusRef: drawersFocusRef, onActiveDrawerChange: onActiveDrawerChange, splitPanelToggleProps: (splitPanelToggleProps === null || splitPanelToggleProps === void 0 ? void 0 : splitPanelToggleProps.displayed) ? splitPanelToggleProps : undefined, splitPanelFocusRef: splitPanelFocusRef, onSplitPanelToggle: onSplitPanelToggle, disabled: anyPanelOpenInMobile, globalDrawersFocusControl: globalDrawersFocusControl, globalDrawers: (_c = globalDrawers === null || globalDrawers === void 0 ? void 0 : globalDrawers.filter(item => !!item.trigger)) !== null && _c !== void 0 ? _c : [], activeGlobalDrawersIds: activeGlobalDrawersIds !== null && activeGlobalDrawersIds !== void 0 ? activeGlobalDrawersIds : [], onActiveGlobalDrawersChange: onActiveGlobalDrawersChange }))))));
}
export const createWidgetizedAppLayoutToolbar = createWidgetizedComponent(AppLayoutToolbarImplementation, ToolbarSkeleton);
//# sourceMappingURL=index.js.map