UNPKG

@massds/mayflower-react

Version:

React versions of Mayflower design system UI components

828 lines (816 loc) 39.7 kB
"use strict"; exports.__esModule = true; exports["default"] = exports.HamburgerUtilityNav = exports.HamburgerUtilityItem = exports.HamburgerSkipNav = exports.HamburgerSiteLogo = exports.HamburgerNavSearch = exports.HamburgerNavItem = exports.HamburgerMobileNavSearch = exports.HamburgerMobileLogoWrapper = exports.HamburgerMainNav = exports.HamburgerLogoWrapper = exports.HamburgerContext = exports.HamburgerContainer = void 0; var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _index = _interopRequireDefault(require("../NavContainer/index.js")); var _IconSearch = _interopRequireDefault(require("../Icon/IconSearch.js")); var _IconHome = _interopRequireDefault(require("../Icon/IconHome.js")); var _index2 = _interopRequireDefault(require("../SiteLogo/index.js")); var _index3 = _interopRequireDefault(require("../ButtonWithIcon/index.js")); var _getFallbackComponent = _interopRequireDefault(require("../utilities/getFallbackComponent.js")); var _hooks = require("../HamburgerNav/hooks.js"); var _useWindowWidth = _interopRequireDefault(require("../hooks/use-window-width.js")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } var HamburgerContext = exports.HamburgerContext = /*#__PURE__*/_react["default"].createContext(); var HamburgerNav = function HamburgerNav(_ref) { var UtilityNav = _ref.UtilityNav, UtilityItem = _ref.UtilityItem, MainNav = _ref.MainNav, NavItem = _ref.NavItem, NavSearch = _ref.NavSearch, Logo = _ref.Logo, _ref$siteName = _ref.siteName, siteName = _ref$siteName === void 0 ? 'Mass.gov' : _ref$siteName, _ref$mainItems = _ref.mainItems, mainItems = _ref$mainItems === void 0 ? [] : _ref$mainItems, _ref$homeLink = _ref.homeLink, homeLink = _ref$homeLink === void 0 ? {} : _ref$homeLink, _ref$utilityItems = _ref.utilityItems, utilityItems = _ref$utilityItems === void 0 ? [] : _ref$utilityItems, _ref$headerType = _ref.headerType, headerType = _ref$headerType === void 0 ? 'hamburger' : _ref$headerType; var windowWidth = (0, _useWindowWidth["default"])(); var isMobileWindow = windowWidth !== null && windowWidth < 840; // desktop breakpoint var isSmallMobileWindow = windowWidth !== null && windowWidth < 621; // css breakpoint $bp-small-max var RenderedMainNav = (0, _getFallbackComponent["default"])(MainNav, HamburgerMainNav); var RenderedUtilityNav; var navSearch = null; var utilityNav = null; var mainNav = null; var RenderedNavSearch = (0, _getFallbackComponent["default"])(NavSearch, HamburgerNavSearch); var RenderedLogo = (0, _getFallbackComponent["default"])(Logo, HamburgerSiteLogo); // If UtilityItem is undefined, UtilityNav will fallback to HamburgerUtilityItem. var RenderedUtilityItem = (0, _getFallbackComponent["default"])(UtilityItem, HamburgerUtilityItem); // If NavItem is undefined, HamburgerMainNav falls back to HamburgerNavItem. var RenderedNavItem = (0, _getFallbackComponent["default"])(NavItem, HamburgerNavItem); var logo = RenderedLogo !== null ? /*#__PURE__*/_react["default"].createElement(RenderedLogo, null) : null; var menuButtonRef = _react["default"].useRef(); var alertOffset = _react["default"].useRef(); var _React$useState = _react["default"].useState(false), menuOpen = _React$useState[0], setMenuOpen = _React$useState[1]; var commonCloseMenuTasks = _react["default"].useCallback(function () { var menuButton = menuButtonRef.current; if (menuButton) { var body = document.querySelector('body'); var hamburgerMenuContainer = document.querySelector('.ma__header__hamburger__nav-container'); var searchInput = document.querySelector('.ma__header__hamburger__nav-container .ma__header-search__input'); var feedbackButton = document.querySelector('.ma__fixed-feedback-button'); var menuOverlay = document.querySelector('.menu-overlay'); var alertOverlay = document.querySelector('.alert-overlay'); var jumpToSearchButton = document.querySelector('.js-header-search-access-button'); body.classList.remove('show-menu'); setMenuOpen(false); if (document.querySelector('html.stickyTOCtmp')) { document.querySelector('html.stickyTOCtmp').classList.add('stickyTOC'); document.querySelector('html.stickyTOCtmp').classList.remove('stickyTOCtmp'); } menuButton.setAttribute('aria-expanded', 'false'); menuButton.setAttribute('aria-label', 'main menu for mass.gov'); if (hamburgerMenuContainer && hamburgerMenuContainer.hasAttribute('style')) { hamburgerMenuContainer.removeAttribute('style'); } if (searchInput && searchInput.hasAttribute('autofocus')) { searchInput.removeAttribute('autofocus'); } if (feedbackButton) { feedbackButton.classList.remove('hide-button'); } if (jumpToSearchButton) { jumpToSearchButton.setAttribute('aria-expanded', 'false'); } if (menuOverlay) { menuOverlay.classList.remove('overlay-open'); } if (alertOverlay) { alertOverlay.classList.remove('overlay-open'); alertOverlay.removeAttribute('style'); } } }, [menuButtonRef]); var closeMenu = _react["default"].useCallback(function () { var menuButton = menuButtonRef.current; var body = document.querySelector('body'); var alertlOffsetPosition = alertOffset.current; if (window && menuButton) { var width = body.clientWidth; commonCloseMenuTasks(); menuButton.setAttribute('aria-pressed', 'false'); // Set focus on the menu button. setTimeout(function () { menuButton.focus(); }, 100); if (width > 840) { var directLink = document.querySelector('.js-utility-nav--wide .ma__utility-nav__item .direct-link'); if (directLink && directLink.hasAttribute('tabindex')) { var googleTeMenuValue = document.querySelector('.js-utility-nav--wide .ma__utility-nav__item .goog-te-menu-value'); var jsUtilNavToggle = document.querySelector('.js-utility-nav--wide .ma__utility-nav__item .js-util-nav-toggle'); var searchAccessButton = document.querySelector('.js-header-search-access-button'); if (googleTeMenuValue) { googleTeMenuValue.removeAttribute('tabindex'); } if (directLink) { directLink.removeAttribute('tabindex'); } if (jsUtilNavToggle) { jsUtilNavToggle.removeAttribute('tabindex'); } if (searchAccessButton) { searchAccessButton.removeAttribute('tabindex'); } } } if (body.style.position === 'fixed') { // At the same time, the alert needs to be scrolled up to the position again to retain the page elements position. body.removeAttribute('style'); body.style.position = 'relative'; window.scrollTo(0, alertlOffsetPosition); } } }, [menuButtonRef, alertOffset, commonCloseMenuTasks]); if (isMobileWindow) { RenderedUtilityNav = (0, _getFallbackComponent["default"])(UtilityNav, HamburgerUtilityNav); mainNav = RenderedMainNav !== null ? /*#__PURE__*/_react["default"].createElement(RenderedMainNav, { NavItem: RenderedNavItem, items: mainItems, onCloseMenu: closeMenu }) : null; utilityNav = RenderedUtilityNav !== null ? /*#__PURE__*/_react["default"].createElement(RenderedUtilityNav, { items: utilityItems, narrow: true, UtilityItem: RenderedUtilityItem }) : null; navSearch = RenderedNavSearch !== null ? /*#__PURE__*/_react["default"].createElement(RenderedNavSearch, null) : null; } else { RenderedUtilityNav = (0, _getFallbackComponent["default"])(UtilityNav, HamburgerUtilityNav); utilityNav = RenderedUtilityNav !== null ? /*#__PURE__*/_react["default"].createElement(RenderedUtilityNav, { items: utilityItems, narrow: true, UtilityItem: RenderedUtilityItem }) : null; navSearch = RenderedNavSearch !== null ? /*#__PURE__*/_react["default"].createElement(RenderedNavSearch, null) : null; mainNav = RenderedMainNav !== null ? /*#__PURE__*/_react["default"].createElement(RenderedMainNav, { NavItem: RenderedNavItem, items: mainItems }) : null; } var openMenu = _react["default"].useCallback(function () { var menuButton = menuButtonRef.current; if (menuButton) { var heightAboveMenuContainer; var emergencyAlertsHeight; var alertOffsetAdjusted = 0; var body = document.querySelector('body'); var feedbackButton = document.querySelector('.ma__fixed-feedback-button'); var jumpToSearchButton = document.querySelector('.js-header-search-access-button'); var menuOverlay = document.querySelector('.menu-overlay'); var alertOverlay = document.querySelector('.alert-overlay'); var lockPage = function lockPage() { var alertlOffsetPosition = alertOffset.current; if (document.querySelector('.ma__emergency-alerts')) { body.style.top = "-" + alertlOffsetPosition + "px"; } else { body.style.top = 0; } var hamburgerMenuContainer = document.querySelector('.ma__header__hamburger__nav-container'); heightAboveMenuContainer = hamburgerMenuContainer.getBoundingClientRect().top; }; if (document.querySelector('html.stickyTOC')) { document.querySelector('html.stickyTOC').classList.add('stickyTOCtmp'); document.querySelector('html.stickyTOC').classList.remove('stickyTOC'); } // Start open menu tasks. body.classList.add('show-menu'); setMenuOpen(true); menuButton.setAttribute('aria-expanded', 'true'); menuButton.setAttribute('aria-label', 'main menu for mass.gov'); if (feedbackButton) { feedbackButton.classList.add('hide-button'); } if (jumpToSearchButton) { jumpToSearchButton.setAttribute('aria-expanded', 'true'); jumpToSearchButton.setAttribute('tabIndex', -1); } menuButton.setAttribute('aria-pressed', 'true'); var alertsHeader = document.querySelector('.ma__emergency-alerts__header'); body.style.position = 'fixed'; if (alertsHeader !== null) { var emergencyAlerts = document.querySelector('.ma__emergency-alerts'); emergencyAlertsHeight = emergencyAlerts.offsetHeight; alertOffsetAdjusted = alertsHeader.offsetHeight / 2; alertOffset.current = emergencyAlertsHeight - alertOffsetAdjusted; lockPage(); var hamburgerNavOffset = document.querySelector('.ma__header__hamburger__nav').offsetHeight; var hamburgerMenuContainer = document.querySelector('.ma__header__hamburger__nav-container'); heightAboveMenuContainer = alertOffsetAdjusted + hamburgerNavOffset; hamburgerMenuContainer.style.height = "calc(100vh - " + heightAboveMenuContainer + "px)"; } if (menuOverlay) { menuOverlay.classList.add('overlay-open'); menuOverlay.onclick = function () { closeMenu(); }; } if (alertOverlay) { if (document.querySelector('.ma__emergency-alerts')) { alertOverlay.classList.add('overlay-open'); } } } }, [menuButtonRef, alertOffset]); var toggleMenu = _react["default"].useCallback(function () { var body = document.querySelector('body'); var isMenuOpen = body.classList.contains('show-menu'); var hamburgerMenuContainer = document.querySelector('.ma__header__hamburger__nav-container'); if (hamburgerMenuContainer) { // To prevent null in the original mobile main nav. if (isMenuOpen) { // This control the visibility of the dropdown to keyboard and screen reader users while maintaining the show/hide animation effect. // .toggleAttribute() doesn't work with ios11. hamburgerMenuContainer.setAttribute('aria-hidden', ''); closeMenu(); setTimeout(function () { document.querySelector('.js-header-menu-button').focus(); }, 100); } else { hamburgerMenuContainer.removeAttribute('aria-hidden'); openMenu(); // Set buttons between menu button and hamburger menu unfocusable to set focus on the first focusable item in the menu at next tabbing. var googleTeMenuValue = document.querySelector('.js-utility-nav--wide .ma__utility-nav__item .goog-te-menu-value'); var directLink = document.querySelector('.js-utility-nav--wide .ma__utility-nav__item .direct-link'); var jsUtilNavToggle = document.querySelector('.js-utility-nav--wide .ma__utility-nav__item .js-util-nav-toggle'); if (googleTeMenuValue) { googleTeMenuValue.setAttribute('tabindex', '-1'); } if (directLink) { directLink.setAttribute('tabindex', '-1'); } if (jsUtilNavToggle) { jsUtilNavToggle.setAttribute('tabindex', '-1'); } } } }, [openMenu, closeMenu]); // Enables menu open/close events. (0, _hooks.useMenuButtonEffects)(menuButtonRef, toggleMenu); // Enables keyboard control of menu. if (typeof document !== 'undefined') { // check document for SSR var hamburgerNavContainer = document.querySelector('.ma__header__hamburger__nav-container'); var topLevelSelectors = ''; if (isSmallMobileWindow) { topLevelSelectors = '#header-mobile-search, #header-mobile-search + button, .ma__main__hamburger-nav__top-link, .goog-te-gadget a, .ma__header__hamburger__utility-nav .ma__utility-nav__link'; } else { // Header search input and search button that are not displayed inside the main nav mobile tray when the window width is greater than 620px. topLevelSelectors = '.ma__main__hamburger-nav__top-link, .goog-te-gadget a, .ma__header__hamburger__utility-nav .ma__utility-nav__link'; } var topLevelLinks = hamburgerNavContainer && hamburgerNavContainer.querySelectorAll(topLevelSelectors); (0, _hooks.useHamburgerNavKeydown)(closeMenu, topLevelLinks); } // Enables jump to search events. (0, _hooks.useJumpToSearch)(openMenu); var renderHomeLink = homeLink && homeLink.text && homeLink.url; return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(HamburgerContext.Provider, { value: { openMenu: openMenu, closeMenu: closeMenu, toggleMenu: toggleMenu } }, /*#__PURE__*/_react["default"].createElement("nav", { className: "ma__header__hamburger__nav", "aria-label": headerType === 'mixed' && !isMobileWindow ? 'Language options and quick access links' : 'main navigation', id: "hamburger-main-navigation" }, /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header__hamburger-wrapper" }, /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header__hamburger__button-container js-sticky-header" }, mainItems.length > 0 && !renderHomeLink && /*#__PURE__*/_react["default"].createElement("button", { ref: menuButtonRef, type: "button", "aria-expanded": "false", className: "ma__header__hamburger__menu-button js-header-menu-button" }, /*#__PURE__*/_react["default"].createElement("span", { className: "ma__header__hamburger__menu-icon" }), /*#__PURE__*/_react["default"].createElement("span", { className: "ma__header__hamburger__menu-text--mobile js-header__menu-text--mobile " + (menuOpen ? '' : 'show') }, siteName), /*#__PURE__*/_react["default"].createElement("span", { className: "ma__header__hamburger__menu-text js-header__menu-text " + (menuOpen ? '' : 'show') }, "Menu"), /*#__PURE__*/_react["default"].createElement("span", { className: "ma__header__hamburger__menu-text--close js-header__menu-text--close " + (menuOpen ? 'show' : '') }, "Close", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ma__visually-hidden" }, "menu"))), renderHomeLink && /*#__PURE__*/_react["default"].createElement("a", { className: "ma__header__hamburger__menu-home-link", href: homeLink.url }, /*#__PURE__*/_react["default"].createElement(_IconHome["default"], { height: 20, width: 20 }), /*#__PURE__*/_react["default"].createElement("span", null, homeLink.text)), navSearch && /*#__PURE__*/_react["default"].createElement("button", { type: "button", "aria-expanded": "false", className: "ma__header__hamburger__search-access-button js-header-search-access-button" }, /*#__PURE__*/_react["default"].createElement("span", { className: "ma__visually-hidden" }, "Access to search"), /*#__PURE__*/_react["default"].createElement(_IconSearch["default"], null))), RenderedUtilityNav !== null && /*#__PURE__*/_react["default"].createElement(RenderedUtilityNav, { items: utilityItems, UtilityItem: RenderedUtilityItem, narrow: false }), (headerType !== 'mixed' || headerType === 'mixed' && isMobileWindow) && mainItems.length ? /*#__PURE__*/_react["default"].createElement(_index["default"], { logo: logo, mainNav: mainNav, utilityNav: utilityNav, navSearch: navSearch, className: "ma__header__hamburger__nav-container" }) : null))), /*#__PURE__*/_react["default"].createElement("div", { className: "menu-overlay" })); }; HamburgerNav.propTypes = process.env.NODE_ENV !== "production" ? { /** An uninstantiated component which handles displaying the utility nav. */ UtilityNav: _propTypes["default"].elementType, /** An uninstantiated component which handles displaying individual items within the utility nav. */ UtilityItem: _propTypes["default"].elementType, /** An uninstantiated component which handles displaying menu portion of the header. */ MainNav: _propTypes["default"].elementType, /** An uninstantiated component which handles displaying individual menu items within the menu. */ NavItem: _propTypes["default"].elementType, /** An uninstantiated component which handles displaying the site logo. */ Logo: _propTypes["default"].elementType, /** Override default siteName rendered as the hamburger menu toggle button text and aria-label on mobile, or fallback link */ siteName: _propTypes["default"].string, /** An uninstantiated component which handles search functionality. */ NavSearch: _propTypes["default"].elementType, /** An array of items used to create the menu. */ mainItems: _propTypes["default"].arrayOf(_propTypes["default"].shape({ href: _propTypes["default"].string, text: _propTypes["default"].string, active: _propTypes["default"].bool, subNav: _propTypes["default"].arrayOf(_propTypes["default"].shape({ href: _propTypes["default"].string, text: _propTypes["default"].string })) })), /** Render a link to home site in place of the hamburger menu. */ homeLink: _propTypes["default"].shape({ text: _propTypes["default"].string, url: _propTypes["default"].string }), /** An array of uninstantiated components to render within the utility navigation. */ utilityItems: _propTypes["default"].arrayOf(_propTypes["default"].elementType), /** A string that represents the type of header this component is displayed in. This is needed for figuring out when to display using slim or not. Currently only supports hamburger and mixed. */ headerType: _propTypes["default"].string } : {}; var HamburgerMainNav = exports.HamburgerMainNav = function HamburgerMainNav(_ref2) { var NavItem = _ref2.NavItem, _ref2$items = _ref2.items, items = _ref2$items === void 0 ? [] : _ref2$items, onCloseMenu = _ref2.onCloseMenu; var RenderedNavItem = (0, _getFallbackComponent["default"])(NavItem, HamburgerNavItem); return /*#__PURE__*/_react["default"].createElement("div", { className: "ma__main__hamburger-nav" }, /*#__PURE__*/_react["default"].createElement("ul", { role: "menubar", className: "ma__main__hamburger-nav__items js-main-nav-hamburger" }, items.map(function (item, itemIndex) { return ( /*#__PURE__*/ // eslint-disable-next-line react/no-array-index-key _react["default"].createElement(RenderedNavItem, _extends({ key: "hamburger-nav-navitem--" + itemIndex }, item, { index: itemIndex, onCloseMenu: onCloseMenu })) ); }))); }; HamburgerMainNav.propTypes = process.env.NODE_ENV !== "production" ? { /** An uninstantiated component which handles displaying individual menu items within the menu. */ NavItem: _propTypes["default"].elementType, /** An array of items used to create the menu. */ items: _propTypes["default"].arrayOf(_propTypes["default"].shape({ href: _propTypes["default"].string, text: _propTypes["default"].string, active: _propTypes["default"].bool, subNav: _propTypes["default"].arrayOf(_propTypes["default"].shape({ href: _propTypes["default"].string, text: _propTypes["default"].string })) })), /** Function to close the hamburger menu, passed down from the HamburgerNav . */ onCloseMenu: _propTypes["default"].func } : {}; var HamburgerNavItem = exports.HamburgerNavItem = function HamburgerNavItem(_ref3) { var href = _ref3.href, text = _ref3.text, active = _ref3.active, _ref3$subNav = _ref3.subNav, subNav = _ref3$subNav === void 0 ? [] : _ref3$subNav, index = _ref3.index, onCloseMenu = _ref3.onCloseMenu; var hasSubNav = subNav && subNav.length > 0; var classes = (0, _classnames["default"])('ma__main__hamburger-nav__item js-main-nav-hamburger-toggle', { 'has-subnav': hasSubNav, 'is-active': active }); // This is the same logic as twig for when covid background displays. var isCovid = text.toLowerCase().includes('covid'); var topNavLinkclasses = (0, _classnames["default"])('ma__main__hamburger-nav__top-link', { ' cv-alternate-style': isCovid }); var itemRef = _react["default"].useRef(); var buttonRef = _react["default"].useRef(); var contentRef = _react["default"].useRef(); var ulRef = _react["default"].useRef(); _react["default"].useEffect(function () { var item = itemRef.current; var itemButton = buttonRef.current; var contentDiv = contentRef.current; var subItems = ulRef.current; if (subItems) { subItems.style.opacity = '0'; } var closeNarrowUtilContent = function closeNarrowUtilContent() { var utilNarrowButton = document.querySelector('.ma__header__hamburger__utility-nav--narrow button.js-util-nav-toggle'); var utilNarrowContent = utilNarrowButton ? utilNarrowButton.nextElementSibling : null; var utilNarrowContainer = utilNarrowContent ? utilNarrowContent.querySelector('.ma__utility-nav__container') : null; if (utilNarrowContent) { var thisNavContainer = utilNarrowButton.closest('.ma__utility-nav__item'); utilNarrowButton.setAttribute('aria-expanded', 'false'); utilNarrowContent.setAttribute('aria-hidden', 'true'); thisNavContainer.style.pointerEvents = 'none'; setTimeout(function () { thisNavContainer.removeAttribute('style'); }, 700); utilNarrowContent.style.maxHeight = '0'; utilNarrowContainer.style.opacity = '0'; setTimeout(function () { utilNarrowContent.classList.add('is-closed'); }, 500); } }; var anotherCloseSubMenus = function anotherCloseSubMenus(menuItem) { var menuItems = document.querySelectorAll('.js-main-nav-hamburger-toggle'); menuItems.forEach(function (li) { if (menuItem !== li && li.classList.contains('submenu-open')) { li.classList.remove('submenu-open'); li.querySelector('.js-main-nav-hamburger__top-link').setAttribute('aria-expanded', 'false'); // eslint-disable-next-line no-param-reassign li.style.pointerEvents = 'none'; /** Slide up. */ // eslint-disable-next-line no-param-reassign li.querySelector('.js-main-nav-hamburger-content').style.height = '0'; // eslint-disable-next-line no-param-reassign li.querySelector('.js-main-nav-hamburger__container').style.opacity = '0'; setTimeout(function () { li.removeAttribute('style'); li.querySelector('.js-main-nav-hamburger-content').classList.add('is-closed'); }, 500); } }); }; var openThisSubMenu = function openThisSubMenu() { // If submenu is closed, open the submenu item.classList.add('submenu-open'); itemButton.setAttribute('aria-expanded', 'true'); item.style.pointerEvents = 'none'; /** Show the subMenu content. */ contentDiv.classList.remove('is-closed'); contentDiv.style.height = 'auto'; /** Get the computed height of the subMenu. */ var height = contentDiv.clientHeight + "px"; /** Set the height of the submenu as 0px, */ /** so we can trigger the slide down animation. */ contentDiv.style.height = '0'; setTimeout(function () { item.removeAttribute('style'); contentDiv.style.height = height; item.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'start' }); if (subItems) { subItems.style.opacity = '1'; } }, 500); /** Close Utility menu content when a sub menu is open. */ var body = document.querySelector('body'); var width = body.clientWidth; if (width < 840) { closeNarrowUtilContent(); } }; var itemButtonClick = function itemButtonClick() { // close all other submenus anotherCloseSubMenus(item); // toggle the selected submenu if (item.classList.contains('submenu-open')) { // If submenu is already open, close the submenu item.classList.remove('submenu-open'); itemButton.setAttribute('aria-expanded', 'false'); item.style.pointerEvents = 'none'; contentDiv.style.height = '0'; if (subItems) { subItems.style.opacity = '0'; } // Set a little bit of delay to run // The open/close submenu animation is CSS. // Unable to confirm the completion of the animation in JS. // Unable to use callback in this case. setTimeout(function () { item.removeAttribute('style'); item.querySelector('.js-main-nav-hamburger-content').classList.add('is-closed'); }, 500); } else { // If submenu is closed, open the submenu openThisSubMenu(); } }; var itemButtonKeyDown = function itemButtonKeyDown(e) { // Easy access to the key that was pressed. var key = e.key, code = e.code; var action = { tab: key === 'Tab', // tab esc: key === 'Esc' || key === 'Escape', // esc left: key === 'Left' || key === 'ArrowLeft', // left arrow right: key === 'Right' || key === 'ArrowRight', // right arrow up: key === 'Up' || key === 'ArrowUp', // up arrow down: key === 'Down' || key === 'ArrowDown', // down arrow space: key === ' ' || code === 'Space', // space enter: key === 'Enter' // enter }; var focusedElement = document.activeElement; // Navigate into or within a submenu using the up/down arrow keys. if ((action.up || action.down) && subItems) { var dropdownLinks = subItems.querySelectorAll('.js-main-nav-hamburger__subitem .js-main-nav-hamburger__link'); var dropdownLinksLength = dropdownLinks.length; var focusIndexInDropdown = Array.from(dropdownLinks).findIndex(function (link) { return link === focusedElement; }); if (item.classList.contains('submenu-open')) { // ArrowUp focus on the previous submenu item // ArrowDown focus on the next submenu item focusIndexInDropdown += action.up ? -1 : 1; // Wrap around if at the end of the submenu. focusIndexInDropdown = (focusIndexInDropdown % dropdownLinksLength + dropdownLinksLength) % dropdownLinksLength; dropdownLinks[focusIndexInDropdown].focus(); } else { // Close all other submenus and open the selected submenu if it's not open already. anotherCloseSubMenus(); openThisSubMenu(); if (action.up) { // arrowUp set focus to the last item focusIndexInDropdown = dropdownLinksLength - 1; } else { // arrowDown set focus to the first item focusIndexInDropdown = 0; } dropdownLinks[focusIndexInDropdown].focus(); } } if (action.esc) { // If the main nav item is open, escape key closes the accordion and sets focus on the main nav toggle button if (item.classList.contains('submenu-open')) { anotherCloseSubMenus(); itemButton.focus(); } // Hamburger menu escape is handled in useHamburgerNavKeydown hook } }; if (itemButton) { itemButton.addEventListener('click', itemButtonClick); item.addEventListener('keydown', itemButtonKeyDown); } return function () { if (itemButton) { itemButton.removeEventListener('click', itemButtonClick); item.removeEventListener('keydown', itemButtonKeyDown); } }; }, [itemRef, buttonRef, contentRef, ulRef]); return /*#__PURE__*/_react["default"].createElement("li", { ref: itemRef, role: "menuitem", className: classes, tabIndex: "-1" }, hasSubNav ? /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("button", { ref: buttonRef, type: "button", id: "button-mobile-" + index, className: "ma__main__hamburger-nav__top-link js-main-nav-hamburger__top-link", "aria-haspopup": "true", tabIndex: "0" }, /*#__PURE__*/_react["default"].createElement("span", { className: "visually-hidden show-label" }, "Show the sub topics of "), text, /*#__PURE__*/_react["default"].createElement("span", { className: "toggle-indicator", "aria-hidden": "true" })), /*#__PURE__*/_react["default"].createElement("div", { ref: contentRef, className: "ma__main__hamburger-nav__subitems js-main-nav-hamburger-content is-closed" }, /*#__PURE__*/_react["default"].createElement("ul", { ref: ulRef, id: "menu-mobile-" + index, role: "menu", "aria-labelledby": "button-mobile-" + index, className: "ma__main__hamburger-nav__container js-main-nav-hamburger__container" }, subNav.map(function (item, itemIndex) { return ( /*#__PURE__*/ // eslint-disable-next-line react/no-array-index-key _react["default"].createElement("li", { key: "hamburger-nav-subitem--" + index + "-" + itemIndex, role: "none", className: "ma__main__hamburger-nav__subitem js-main-nav-hamburger__subitem" }, /*#__PURE__*/_react["default"].createElement("a", { href: item.href, role: "menuitem", className: "ma__main__hamburger-nav__link js-main-nav-hamburger__link", onClick: onCloseMenu }, item.text)) ); })))) : /*#__PURE__*/_react["default"].createElement("a", { href: href, className: topNavLinkclasses, tabIndex: "0", onClick: onCloseMenu }, text)); }; HamburgerNavItem.propTypes = process.env.NODE_ENV !== "production" ? { href: _propTypes["default"].string, text: _propTypes["default"].string, active: _propTypes["default"].bool, subNav: _propTypes["default"].arrayOf(_propTypes["default"].shape({ href: _propTypes["default"].string, text: _propTypes["default"].string })), index: _propTypes["default"].oneOfType([_propTypes["default"].number, _propTypes["default"].string]), /** Function to close the hamburger menu, passed down from the HamburgerNav. */ onCloseMenu: _propTypes["default"].func } : {}; var HamburgerUtilityItem = exports.HamburgerUtilityItem = function HamburgerUtilityItem(_ref4) { var children = _ref4.children; return /*#__PURE__*/_react["default"].createElement("li", { className: "ma__utility-nav__item" }, children); }; HamburgerUtilityItem.propTypes = process.env.NODE_ENV !== "production" ? { children: _propTypes["default"].node } : {}; var HamburgerUtilityNav = exports.HamburgerUtilityNav = function HamburgerUtilityNav(_ref5) { var UtilityItem = _ref5.UtilityItem, _ref5$items = _ref5.items, items = _ref5$items === void 0 ? [] : _ref5$items, _ref5$narrow = _ref5.narrow, narrow = _ref5$narrow === void 0 ? true : _ref5$narrow; var RenderedUtilityItem = (0, _getFallbackComponent["default"])(UtilityItem, HamburgerUtilityItem); var wrapperClassName = (0, _classnames["default"])('ma__header__hamburger__utility-nav', { 'ma__header__hamburger__utility-nav--narrow js-utility-nav--narrow': narrow, 'ma__header__hamburger__utility-nav--wide js-utility-nav--wide': !narrow }); return /*#__PURE__*/_react["default"].createElement("div", { className: wrapperClassName }, items.length > 0 && /*#__PURE__*/_react["default"].createElement("div", { className: "ma__utility-nav js-util-nav" }, /*#__PURE__*/_react["default"].createElement("ul", { className: "ma__utility-nav__items" }, items.map(function (ItemComponent, index) { return ( /*#__PURE__*/ // eslint-disable-next-line react/no-array-index-key _react["default"].createElement(RenderedUtilityItem, { key: "header-hamburger-utility-item-" + index }, /*#__PURE__*/_react["default"].createElement(ItemComponent, { narrow: narrow })) ); })))); }; HamburgerUtilityNav.propTypes = process.env.NODE_ENV !== "production" ? { /** An uninstantiated component which handles displaying individual items within the utility nav. */ UtilityItem: _propTypes["default"].elementType, /** An array of uninstantiated components to render within the utility navigation. */ items: _propTypes["default"].arrayOf(_propTypes["default"].elementType), /** A boolean representing when the UtilityNav is being displayed within a narrow screen. */ narrow: _propTypes["default"].bool } : {}; var HamburgerNavSearch = exports.HamburgerNavSearch = function HamburgerNavSearch() { return /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header__hamburger__search ma__header__hamburger__search-bar js-header-search-menu" }, /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header-search" }, /*#__PURE__*/_react["default"].createElement("form", { action: "#", className: "ma__form js-header-search-form", role: "search" }, /*#__PURE__*/_react["default"].createElement("label", { htmlFor: "nav-search", className: "ma__header-search__label" }, "Search terms"), /*#__PURE__*/_react["default"].createElement("input", { id: "nav-search", className: "ma__header-search__input", placeholder: "Search Mass.gov", type: "search", inputMode: "search" }), /*#__PURE__*/_react["default"].createElement(_index3["default"], { usage: "secondary", icon: /*#__PURE__*/_react["default"].createElement(_IconSearch["default"], null), text: "Search" })))); }; // eslint-disable-next-line react/prop-types var HamburgerLogoWrapper = exports.HamburgerLogoWrapper = function HamburgerLogoWrapper(_ref6) { var children = _ref6.children; return /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header__hamburger__logo" }, children); }; var HamburgerSiteLogo = exports.HamburgerSiteLogo = function HamburgerSiteLogo(_ref7) { var Wrapper = _ref7.Wrapper; var DefaultWrapper = (0, _getFallbackComponent["default"])(Wrapper, HamburgerLogoWrapper); var logoProps = { url: { domain: 'https://www.mass.gov/' }, image: { src: 'https://unpkg.com/@massds/mayflower-assets/static/images/logo/stateseal.png', width: 45, height: 45 }, siteName: 'Mass.gov', title: 'Mass.gov homepage', Wrapper: DefaultWrapper }; return /*#__PURE__*/_react["default"].createElement(_index2["default"], logoProps); }; HamburgerSiteLogo.propTypes = process.env.NODE_ENV !== "production" ? { /** An uninstantiated component which handles displaying the wrapper around the site logo, if any. */ Wrapper: _propTypes["default"].elementType } : {}; // eslint-disable-next-line react/prop-types var HamburgerMobileLogoWrapper = exports.HamburgerMobileLogoWrapper = function HamburgerMobileLogoWrapper(_ref8) { var children = _ref8.children; return /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header__hamburger__logo ma__header__hamburger__logo--mobile" }, children); }; var HamburgerSkipNav = exports.HamburgerSkipNav = function HamburgerSkipNav() { return /*#__PURE__*/_react["default"].createElement("a", { className: "ma__header__hamburger__skip-nav", href: "#main-content" }, "skip to main content"); }; var HamburgerContainer = exports.HamburgerContainer = function HamburgerContainer(_ref9) { var Logo = _ref9.Logo, NavSearch = _ref9.NavSearch; var RenderedLogo = Logo !== null ? Logo : null; var RenderedNavSearch = (0, _getFallbackComponent["default"])(NavSearch, HamburgerNavSearch); return /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header__container" }, RenderedLogo !== null && /*#__PURE__*/_react["default"].createElement(RenderedLogo, null), RenderedNavSearch !== null && /*#__PURE__*/_react["default"].createElement(RenderedNavSearch, null)); }; HamburgerContainer.propTypes = process.env.NODE_ENV !== "production" ? { /** An uninstantiated component which handles displaying the site logo. */ Logo: _propTypes["default"].elementType, /** An uninstantiated component which handles search functionality. */ NavSearch: _propTypes["default"].elementType } : {}; // For some reason, Header Hamburger has its own Nav Search... // This appears to be the same version from HeaderMixed. var HamburgerMobileNavSearch = exports.HamburgerMobileNavSearch = function HamburgerMobileNavSearch() { return /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header__nav-search js-header__nav-search" }, /*#__PURE__*/_react["default"].createElement("div", { className: "ma__header-search" }, /*#__PURE__*/_react["default"].createElement("form", { action: "#", className: "ma__form js-header-search-form", role: "search" }, /*#__PURE__*/_react["default"].createElement("label", { htmlFor: "nav-search", className: "ma__header-search__label" }, "Search terms"), /*#__PURE__*/_react["default"].createElement("input", { id: "nav-search", className: "ma__header-search__input", placeholder: "Search Mass.gov", type: "search", inputMode: "search" }), /*#__PURE__*/_react["default"].createElement(_index3["default"], { usage: "secondary", icon: /*#__PURE__*/_react["default"].createElement(_IconSearch["default"], null), text: "Search" })))); }; var _default = exports["default"] = HamburgerNav;