UNPKG

@massds/mayflower-react

Version:

React versions of Mayflower design system UI components

266 lines (241 loc) 11.1 kB
import React from "react"; import propTypes from "prop-types"; import GoogleTranslateElement from "../GoogleTranslateElement/index.mjs"; import DecorativeLink from "../DecorativeLink/index.mjs"; import IconBuilding from "../Icon/IconBuilding.mjs"; import IconLogin from "../Icon/IconLogin.mjs"; import useWindowWidth from "../hooks/use-window-width.mjs"; import UtilityNavData from "./UtilityNav.data"; const PanelItem = (_ref) => { let narrow = _ref.narrow, _ref$title = _ref.title, title = _ref$title === void 0 ? '' : _ref$title, CustomIcon = _ref.CustomIcon, _ref$description = _ref.description, description = _ref$description === void 0 ? '' : _ref$description, _ref$ariaLabel = _ref.ariaLabel, ariaLabel = _ref$ariaLabel === void 0 ? '' : _ref$ariaLabel, _ref$links = _ref.links, links = _ref$links === void 0 ? [] : _ref$links; const windowWidth = useWindowWidth(); const isMobileWindow = windowWidth !== null && windowWidth < 860; const loginToggleRef = React.useRef(); const loginContentRef = React.useRef(); const loginCloseRef = React.useRef(); const loginContainerRef = React.useRef(); React.useEffect(() => { const utilButton = loginToggleRef.current; const utilCloseButton = loginCloseRef.current; const utilContent = loginContentRef.current; const utilContainer = utilContent ? loginContainerRef.current : null; const closeUtilWideContent = () => { // Content state utilContent.style.height = '0'; utilContent.style.opacity = '0'; utilContent.classList.add('is-closed'); utilContent.setAttribute('aria-hidden', 'true'); // Close button state utilCloseButton.setAttribute('aria-expanded', 'false'); // Utility button state utilButton.setAttribute('aria-expanded', 'false'); utilButton.setAttribute('aria-pressed', 'false'); const closestHamburgerNav = utilButton.closest('.ma__header__hamburger__nav'); if (closestHamburgerNav) { closestHamburgerNav.classList.toggle('util-nav-content-open'); } }; const closeNarrowUtilContent = () => { const thisNavContainer = utilButton.closest('.ma__utility-nav__item'); utilButton.setAttribute('aria-expanded', 'false'); utilContent.setAttribute('aria-hidden', 'true'); thisNavContainer.style.pointerEvents = 'none'; setTimeout(() => { thisNavContainer.removeAttribute('style'); }, 700); utilContent.style.maxHeight = '0'; utilContainer.style.opacity = '0'; setTimeout(() => { utilContent.classList.add('is-closed'); }, 500); }; const utilButtonNarrowClick = e => { const thisButton = e.target.closest('.js-util-nav-toggle'); const thisNavContainer = e.target.closest('.ma__utility-nav__item'); const utilNarrowContent = thisButton.nextElementSibling; if (utilNarrowContent.classList.contains('is-closed')) { // TO OPEN closeSubMenu(); thisButton.setAttribute('aria-expanded', 'true'); utilNarrowContent.removeAttribute('aria-hidden'); thisNavContainer.style.pointerEvents = 'none'; /** Slide down. */ thisNavContainer.removeAttribute('style'); /** Show the content. */ utilNarrowContent.classList.remove('is-closed'); utilNarrowContent.style.maxHeight = 'auto'; /** Get the computed height of the content. */ const contentHeight = utilContent.querySelector('.ma__utility-nav__content-body').clientHeight + "px"; /** Set the height of the submenu as 0px, */ /** so we can trigger the slide down animation. */ utilContent.style.maxHeight = '0'; utilContent.style.Height = '0'; // These height settings display the bottom border of the parent li at the correct spot. utilContent.style.height = contentHeight; utilContainer.style.height = contentHeight; utilContent.style.maxHeight = contentHeight; utilContainer.style.opacity = '1'; } else { closeNarrowUtilContent(); } }; const utilButtonWideClick = e => { const thisWideButton = e.target.closest('.js-util-nav-toggle'); const thisWideContent = thisWideButton.nextElementSibling; if (thisWideContent.classList.contains('is-closed')) { const closestHamburgerNav = thisWideButton.closest('.ma__header__hamburger__nav'); if (closestHamburgerNav) { closestHamburgerNav.classList.add('util-nav-content-open'); } thisWideContent.classList.remove('is-closed'); thisWideContent.removeAttribute('aria-hidden'); thisWideContent.removeAttribute('style'); thisWideContent.style.height = 'auto'; thisWideContent.style.opacity = '1'; // Button State thisWideButton.setAttribute('aria-expanded', 'true'); thisWideButton.setAttribute('aria-pressed', 'true'); } thisWideButton.setAttribute('aria-expanded', 'true'); thisWideButton.setAttribute('aria-pressed', 'true'); }; function closeSubMenu() { const openSubMenu = document.querySelector('.submenu-open'); if (openSubMenu) { const openSubMenuButton = openSubMenu.querySelector('.js-main-nav-hamburger__top-link'); const openSubMenuContent = openSubMenu.querySelector('.js-main-nav-hamburger-content'); const openSubMenuContainer = openSubMenu.querySelector('.js-main-nav-hamburger__container'); openSubMenuButton.setAttribute('aria-expanded', 'false'); openSubMenuContent.style.height = '0'; openSubMenuContainer.style.opacity = '0'; openSubMenuContent.classList.add('is-closed'); openSubMenu.removeAttribute('style'); openSubMenu.classList.remove('submenu-open'); } } if (utilButton && utilCloseButton && utilContent && utilContainer) { // Open if (!isMobileWindow) { utilContent.removeAttribute('style'); utilContainer.removeAttribute('style'); utilButton.addEventListener('click', utilButtonWideClick); utilCloseButton.addEventListener('click', closeUtilWideContent); } else { utilContent.style.maxHeight = '0'; utilContainer.style.opacity = '0'; utilButton.addEventListener('click', utilButtonNarrowClick); } } return () => { utilButton.removeEventListener('click', utilButtonWideClick); utilCloseButton.removeEventListener('click', closeUtilWideContent); utilButton.removeEventListener('click', utilButtonNarrowClick); }; }, [isMobileWindow, narrow, loginToggleRef, loginCloseRef, loginContentRef, loginContainerRef]); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("button", { ref: loginToggleRef, type: "button", className: "ma__utility-nav__link js-util-nav-toggle", "aria-haspopup": "true", "aria-label": ariaLabel, "aria-expanded": "false" }, CustomIcon && /*#__PURE__*/React.createElement(CustomIcon, null), title && title.length > 0 && /*#__PURE__*/React.createElement("span", null, title), /*#__PURE__*/React.createElement("span", { className: "toggle-indicator", "aria-hidden": "true" })), /*#__PURE__*/React.createElement("div", { ref: loginContentRef, "aria-hidden": "true", className: "ma__utility-nav__content js-util-nav-content is-closed" }, /*#__PURE__*/React.createElement("div", { ref: loginContainerRef, className: "ma__utility-nav__container" }, /*#__PURE__*/React.createElement("div", { className: "ma__utility-nav__content-title" }, /*#__PURE__*/React.createElement("button", { ref: loginCloseRef, type: "button", className: "ma__utility-nav__close js-close-util-nav" }, /*#__PURE__*/React.createElement("span", null, "Close"), /*#__PURE__*/React.createElement("span", { className: "ma__utility-nav__close-icon", "aria-hidden": "true" }, "+")), CustomIcon && /*#__PURE__*/React.createElement(CustomIcon, null), title && title.length > 0 && /*#__PURE__*/React.createElement("h2", null, title)), /*#__PURE__*/React.createElement("div", { className: "ma__utility-nav__content-body" }, /*#__PURE__*/React.createElement("div", { className: "ma__utility-panel" }, description && description.length > 0 && /*#__PURE__*/React.createElement("div", { className: "ma__utility-panel__description ma__utility-panel__description--full" }, /*#__PURE__*/React.createElement("div", { className: "ma__rich-text" }, /*#__PURE__*/React.createElement("p", null, description))), /*#__PURE__*/React.createElement("ul", { className: "ma__utility-panel__items" }, links.length > 0 && links.map((link, i) => /*#__PURE__*/React.createElement("li", { className: "ma__utility-panel__item js-clickable", key: "util_panel_item_" + i }, /*#__PURE__*/React.createElement(DecorativeLink, link))))))))); }; PanelItem.propTypes = process.env.NODE_ENV !== "production" ? { narrow: propTypes.bool, title: propTypes.string, CustomIcon: propTypes.elementType, description: propTypes.string, ariaLabel: propTypes.string, links: propTypes.arrayOf(propTypes.object) } : {}; export const LoginItem = (_ref2) => { let _ref2$data = _ref2.data, data = _ref2$data === void 0 ? UtilityNavData.loginItem : _ref2$data; const _data$panel = data.panel, links = _data$panel.links, description = _data$panel.description, text = data.text, ariaLabel = data.ariaLabel; return /*#__PURE__*/React.createElement(PanelItem, { links: links, title: text, CustomIcon: IconLogin, description: description, ariaLabel: ariaLabel }); }; LoginItem.propTypes = process.env.NODE_ENV !== "production" ? { data: propTypes.shape({ panel: propTypes.shape({ description: propTypes.string, links: propTypes.arrayOf(propTypes.object) }), text: propTypes.string, ariaLabel: propTypes.string }) } : {}; export const TranslateItem = () => { const windowWidth = useWindowWidth(); return /*#__PURE__*/React.createElement(React.Fragment, null, windowWidth && windowWidth > 840 && /*#__PURE__*/React.createElement("div", { className: "ma__utility-nav__translate" }, /*#__PURE__*/React.createElement(GoogleTranslateElement, { id: "google-translate-id" }))); }; export const StateItem = (_ref3) => { let _ref3$data = _ref3.data, data = _ref3$data === void 0 ? UtilityNavData.stateItem : _ref3$data; const link = data.link, ariaLabel = data.ariaLabel, text = data.text; return /*#__PURE__*/React.createElement("a", { className: "ma__utility-nav__link direct-link", href: link, "aria-label": ariaLabel }, /*#__PURE__*/React.createElement(IconBuilding, null), /*#__PURE__*/React.createElement("span", null, text)); }; StateItem.propTypes = process.env.NODE_ENV !== "production" ? { data: propTypes.shape({ link: propTypes.string, text: propTypes.string, ariaLabel: propTypes.string }) } : {};