@xo-union/tk-component-header-nav
Version:
171 lines (167 loc) • 7.44 kB
JavaScript
"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;