UNPKG

@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
// 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