UNPKG

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

Version:
116 lines (115 loc) 3.64 kB
import _setTimeout from "@babel/runtime-corejs3/core-js/set-timeout"; import React, { useRef } from "react"; import { useMobileMedia } from "@xo-union/tk-ui-breakpoints"; import { useClickZoneEffect } from "@tkww/orion-web-lib-react"; import { useToggle, useNamedToggle } from "./useToggle.js"; import { menuTypes } from "./types.js"; const useOutsideClick = (isHamburgerOpenInMobile, actions, refs) => { useClickZoneEffect({ enabled: isHamburgerOpenInMobile, onClickOutside: () => { actions.closeHamburger(); }, relatedRefs: [refs.topLevelNavRef, refs.megaMenuContainerRef, refs.mobileAppBarItemsRef] }); }; const useNavigationMenus = _ref => { let { activeProduct, __openOnLoad__ } = _ref; const [isHamburgerOpen, hamburgerActions] = useToggle(Boolean(__openOnLoad__)); const [openMenuID, menuActions] = useNamedToggle(__openOnLoad__); const [openDevice, openDeviceActions] = useNamedToggle(); const returnFocusRef = React.useRef(); const buttonRefs = React.useRef({}); const mobileMedia = useMobileMedia(); React.useEffect(() => { const timeout = _setTimeout(() => { if (!isHamburgerOpen) { menuActions.off(); } }, 300); return () => { clearTimeout(timeout); }; }, [isHamburgerOpen]); // eslint-disable-line react-hooks/exhaustive-deps const closeMenu = function () { let { returnFocus = true } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; const returnFocusElement = returnFocusRef.current; returnFocusRef.current = null; if (returnFocusElement && returnFocus) { const timeout = mobileMedia.yes ? 300 : 0; _setTimeout(() => { returnFocusElement.focus(); }, timeout); } openDeviceActions.off(); menuActions.off(); }; const actions = { openMenu: (menuID, _ref2) => { let { returnFocusElement, device } = _ref2; returnFocusRef.current = returnFocusElement; menuActions.on(menuID); openDeviceActions.on(device); hamburgerActions.on(); }, closeMenu, toggleHamburger: () => { if (activeProduct) { menuActions.on(activeProduct); openDeviceActions.on(null); } hamburgerActions.toggle(); }, closeHamburger: () => { hamburgerActions.off(); }, closeAll: options => { closeMenu(options); hamburgerActions.off(); }, closeLast: options => { if (openMenuID) { closeMenu(options); return; } hamburgerActions.off(); } }; const isAnyMenuOpen = openMenuID !== null; const isHamburgerOpenInMobile = mobileMedia.yes && isHamburgerOpen; const state = { isHamburgerOpen, isAnyMenuOpen, isAnyMegaMenuOpen: isAnyMenuOpen && openMenuID !== menuTypes.ACCOUNT_SETTINGS, wasOpenedWithKeyboard: openDevice === 'keyboard', isHamburgerOpenInMobile }; const selectors = { isMenuActive: menuID => menuID === openMenuID }; const refs = { topLevelNavRef: useRef(null), megaMenuContainerRef: useRef(null), mobileAppBarItemsRef: useRef(null), getButtonRef: function () { let menuID = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : openMenuID; if (buttonRefs.current[menuID]) { return buttonRefs.current[menuID]; } const ref = /*#__PURE__*/React.createRef(); buttonRefs.current[menuID] = ref; return buttonRefs.current[menuID]; } }; useOutsideClick(isHamburgerOpenInMobile, actions, refs); return [state, actions, selectors, refs]; }; export default useNavigationMenus;