diff --git a/app/scripts/components/common/page-header/nav/nav-dropdown-button.tsx b/app/scripts/components/common/page-header/nav/nav-dropdown-button.tsx index f76d5f9b9..5b7f1f5c6 100644 --- a/app/scripts/components/common/page-header/nav/nav-dropdown-button.tsx +++ b/app/scripts/components/common/page-header/nav/nav-dropdown-button.tsx @@ -1,10 +1,11 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import { USWDSNavDropDownButton } from '../../uswds/header/nav-drop-down-button'; import { USWDSMenu } from '../../uswds/header/menu'; import { DropdownNavLink } from '../types'; import { createDynamicNavMenuList } from './create-dynamic-nav-menu-list'; import { SetState } from '$types/aliases'; import { LinkProperties } from '$types/veda'; +import { useClickOutside } from '$utils/use-click-outside'; interface NavDropDownButtonProps { item: DropdownNavLink; @@ -32,11 +33,20 @@ export const NavDropDownButton = ({ return newIsOpen; }); }; - + const handleClickOutside = useCallback(() => { + if (isOpen[index]) { + setIsOpen((prevIsOpen) => { + const newIsOpen = [...prevIsOpen]; + newIsOpen[index] = false; + return newIsOpen; + }); + } + }, [index, isOpen, setIsOpen]); + const dropdownRef = useClickOutside(handleClickOutside); const submenuItems = createDynamicNavMenuList(item.children, linkProperties); return ( - +
onToggle(index, setIsOpen)} menuId={item.title} @@ -48,6 +58,6 @@ export const NavDropDownButton = ({ isOpen={isOpen[index]} id={`${item.id}-dropdown`} /> - +
); }; diff --git a/app/scripts/utils/use-click-outside.ts b/app/scripts/utils/use-click-outside.ts new file mode 100644 index 000000000..4c0247903 --- /dev/null +++ b/app/scripts/utils/use-click-outside.ts @@ -0,0 +1,15 @@ +import { useEffect, useRef } from 'react'; +export const useClickOutside = (onClose: () => void) => { + const ref = useRef(null); + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (ref.current && !ref.current.contains(event.target as Node)) { + onClose(); + } + }; + document.addEventListener('click', handleClickOutside, true); + return () => + document.removeEventListener('click', handleClickOutside, true); + }, [onClose]); + return ref; +}; \ No newline at end of file