import React, { useEffect, useRef } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; import { useAppNavContext } from './context'; export interface IAppNavMenu { className?: string; useRouter?: boolean; [x: string]: any; } export const AppNavMenu: React.FC = (props) => { const { updated, setToggled } = useAppNavContext(); const { children, className = '', useRouter = false, ...otherProps } = props; const refMenu = useRef(null); let history: any; let location: any; if (useRouter) { if (useHistory() && useLocation()) { history = useHistory(); location = useLocation(); } else { console.error('Remember to wrap the AppNav inside of a Router component from react-router-dom'); } } function removeActiveClassOnChildren(element: HTMLElement) { element.querySelectorAll('li').forEach((li: HTMLElement) => li.classList.remove('is-active')); } function findActiveLink() { const menu = refMenu.current; let path: string; if (useRouter) { path = location.pathname; } else { path = document.location.pathname; } removeActiveClassOnChildren(menu); let a = menu.querySelector(`a[href*="${path}"]`); let li = a && a.closest('li'); if (li) { if (li.dataset.child) { const closestParent = li.parentElement.parentElement; closestParent.classList.add('is-active'); li.classList.add('is-active'); } else { li.classList.add('is-active'); } } } function handleRouting(link: string) { if (useRouter) { setToggled(false); history.push(link); } else { document.location.href = link; } } function handleMenuClicks(e: any) { const menu = refMenu.current; const a = e.target.closest('a'); const li = a.parentElement; if (!li) { return; } if (li.dataset.parent) { if (li.classList.contains('is-active')) { li.classList.remove('is-active'); } else { removeActiveClassOnChildren(menu); li.classList.add('is-active'); } } else if (li.dataset.child) { if (useRouter) { const closestParent = li.parentElement.parentElement; removeActiveClassOnChildren(closestParent); li.classList.add('is-active'); } handleRouting(a.pathname); } else { if (useRouter) { removeActiveClassOnChildren(menu); li.classList.add('is-active'); } handleRouting(a.pathname); } } useEffect(() => { if (refMenu.current) { findActiveLink(); } }, [location]); useEffect(() => { if (updated !== 0) { findActiveLink(); } }, [updated]); return ( ); };