UNPKG

@xo-union/tk-component-header-nav

Version:
171 lines (167 loc) • 7.44 kB
"use strict"; var _Object$defineProperty = require("@babel/runtime-corejs3/core-js/object/define-property"); var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); _Object$defineProperty(exports, "__esModule", { value: true }); exports.useMegaMenuLayout = exports.useMegaMenuID = exports.SharedMegaMenuContainer = exports.MegaMenu = void 0; var _setTimeout2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js/set-timeout")); var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _tkComponentIcons = _interopRequireDefault(require("@xo-union/tk-component-icons")); var _componentBlankButton = _interopRequireDefault(require("@xo-union/component-blank-button")); var _tkUiTypography = require("@xo-union/tk-ui-typography"); var _reactFocusLock = _interopRequireDefault(require("react-focus-lock")); var _tkComponentPicture = require("@xo-union/tk-component-picture"); var _reactCssModules = require("@xo-union/react-css-modules"); var _classnames = _interopRequireDefault(require("classnames")); var _tkComponentGrid = require("@xo-union/tk-component-grid"); var _uiAccessibility = require("@xo-union/ui-accessibility"); var _validateLayoutCjs = _interopRequireDefault(require("./validateLayout.cjs.js")); var _ContextCjs = require("../Context.cjs.js"); var _MenuSectionsCjs = require("./MenuSections.cjs.js"); // eslint-disable-line no-restricted-imports const MegaMenuIDContext = /*#__PURE__*/_react.default.createContext(); const MegaMenuLayoutContext = /*#__PURE__*/_react.default.createContext(); const useMegaMenuLayout = () => _react.default.useContext(MegaMenuLayoutContext); exports.useMegaMenuLayout = useMegaMenuLayout; const useMegaMenuID = () => { const result = _react.default.useContext(MegaMenuIDContext); if (!result) { throw new Error('`useMegaMenuID` must be used somewhere in the tree created by `MegaMenu`'); } return result; }; exports.useMegaMenuID = useMegaMenuID; const BackToMainMenuButton = /*#__PURE__*/_react.default.forwardRef((props, ref) => { const { classes } = (0, _ContextCjs.useHeaderNavContext)(); const menuID = useMegaMenuID(); return /*#__PURE__*/_react.default.createElement("div", { className: classes['back-to-main-menu-container'] }, /*#__PURE__*/_react.default.createElement(_componentBlankButton.default, (0, _extends2.default)({ ref: ref, className: classes['back-to-main-menu-button'], type: "button", "aria-controls": `header-${menuID}-mega-menu-popup` }, props), /*#__PURE__*/_react.default.createElement(_tkUiTypography.Body2, { className: (0, _classnames.default)(classes['back-to-main-menu-button-mobile-content'], classes['hide-in-desktop']) }, /*#__PURE__*/_react.default.createElement(_tkComponentIcons.default, { size: "sm", name: "caret_left", "aria-hidden": "true" }), /*#__PURE__*/_react.default.createElement("span", { className: classes['back-to-main-menu-button-text'] }, "Back to Main menu")), /*#__PURE__*/_react.default.createElement("div", { className: classes['hide-in-mobile'] }, /*#__PURE__*/_react.default.createElement(_tkComponentIcons.default, { size: "sm", name: "close", "aria-label": "close menu" })))); }); /* eslint-disable react/require-default-props */ const MegaMenu = _ref => { let { layout, children, menuID, containerProps } = _ref; const { classes, mobileMedia, navMenuSelectors, navMenuActions } = (0, _ContextCjs.useHeaderNavContext)(); const isActive = navMenuSelectors.isMenuActive(menuID); const backButtonRef = _react.default.useRef(); const containerRef = _react.default.useRef(); (0, _tkComponentPicture.useImageLazyLoadingBoundary)({ containerRef, enabled: isActive }); _react.default.useEffect(() => { let timeout; if (isActive && mobileMedia.yes) { timeout = (0, _setTimeout2.default)(() => { backButtonRef.current.focus(); }, 300); } return () => clearTimeout(timeout); }, [isActive]); // eslint-disable-line react-hooks/exhaustive-deps const menuIDClassName = `${menuID}-menu-container`; (0, _validateLayoutCjs.default)(menuID, layout); return /*#__PURE__*/_react.default.createElement(MegaMenuIDContext.Provider, { value: menuID }, /*#__PURE__*/_react.default.createElement(MegaMenuLayoutContext.Provider, { value: layout }, /*#__PURE__*/_react.default.createElement(_tkComponentGrid.FullBleedContainer, (0, _extends2.default)({}, containerProps, { as: _MenuSectionsCjs.MenuPopUp, ref: containerRef, id: `header-${menuID}-mega-menu-popup`, "aria-labelledby": `header-${menuID}-mega-menu-heading`, classes: (0, _reactCssModules.compose)({ 'full-bleed-container': (0, _classnames.default)(classes['mega-menu-dropdown'], isActive && classes['is-active'], menuIDClassName in classes && classes[menuIDClassName]) }) }), /*#__PURE__*/_react.default.createElement(_tkComponentGrid.TopLevelContainer, { classes: (0, _reactCssModules.compose)({ 'top-level-container': (0, _classnames.default)(classes['mega-menu-content']) }) }, /*#__PURE__*/_react.default.createElement(_tkComponentGrid.Row, null, /*#__PURE__*/_react.default.createElement(_tkComponentGrid.Column, { xs: "12" }, /*#__PURE__*/_react.default.createElement(BackToMainMenuButton, { ref: backButtonRef, onClick: navMenuActions.closeMenu })), children))))); }; exports.MegaMenu = MegaMenu; process.env.NODE_ENV !== "production" ? MegaMenu.propTypes = { children: _propTypes.default.node, menuID: _propTypes.default.string, containerProps: _propTypes.default.shape({}), layout: _propTypes.default.shape({ alignSectionsBreakpoint: _propTypes.default.oneOf(['xs', 'sm', 'md', 'lg', 'xl', 'xxl']).isRequired, featuredSection: _propTypes.default.shape({ unitSize: _propTypes.default.oneOf(['sm', 'lg', 'xl']).isRequired, numberOfColumns: _propTypes.default.shape({ xs: _propTypes.default.oneOf([1, 2]), md: _propTypes.default.oneOf([2, 4]), lg: _propTypes.default.oneOf([1, 2]) }).isRequired }).isRequired, linkColumnProps: _propTypes.default.shape({}) }).isRequired } : void 0; const SharedMegaMenuContainer = _ref2 => { let { children } = _ref2; const { mobileMedia, navMenuActions, navMenuState, navMenuRefs } = (0, _ContextCjs.useHeaderNavContext)(); const isAnyMegaMenuOpenOnDesktop = navMenuState.isAnyMegaMenuOpen && mobileMedia.no; const focusLockEnabled = isAnyMegaMenuOpenOnDesktop && navMenuState.wasOpenedWithKeyboard; (0, _uiAccessibility.useOutsideClickEffect)({ enabled: isAnyMegaMenuOpenOnDesktop, onClickOutside: () => { navMenuActions.closeLast({ returnFocus: false }); } }, [navMenuRefs.megaMenuContainerRef, navMenuRefs.getButtonRef()]); return /*#__PURE__*/_react.default.createElement(_reactFocusLock.default, { disabled: !focusLockEnabled, ref: navMenuRefs.megaMenuContainerRef }, children); }; /* eslint-enable react/require-default-props */ exports.SharedMegaMenuContainer = SharedMegaMenuContainer; process.env.NODE_ENV !== "production" ? SharedMegaMenuContainer.propTypes = { children: _propTypes.default.node } : void 0;