Skip to content

Commit

Permalink
implemenying custom hook
Browse files Browse the repository at this point in the history
  • Loading branch information
snmln committed Dec 19, 2024
1 parent 72575ff commit 5acc803
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ export const createDynamicNavMenuList = (
isOpen?: boolean[],
setIsOpen?: SetState<boolean[]>
): JSX.Element[] => {
const setDropDownState = () => {
if (isOpen !== undefined && setIsOpen !== undefined) {
return setIsOpen(() => isOpen.fill(false));
}
};
return navItems.map((item, index) => {
switch (item.type) {
case NavItemType.DROPDOWN:
Expand All @@ -28,8 +23,7 @@ export const createDynamicNavMenuList = (
isOpen,
setIsOpen,
index,
linkProperties,
setDropDownState
linkProperties
}}
/>
);
Expand All @@ -38,15 +32,10 @@ export const createDynamicNavMenuList = (
return <NavItemInternalLink {...{ item, linkProperties }} />;

case NavItemType.EXTERNAL_LINK:
return (
<NavItemExternalLink
item={item}
setDropDownState={setDropDownState}
/>
);
return <NavItemExternalLink item={item} />;

case NavItemType.ACTION:
return <NavItemCTA item={item} setDropDownState={setDropDownState} />;
return <NavItemCTA item={item} />;

default:
return <></>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
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;
isOpen: boolean[];
setIsOpen: SetState<boolean[]>;
index: number;
linkProperties: LinkProperties;
setDropDownState: () => void;
}

export const NavDropDownButton = ({
item,
isOpen,
setIsOpen,
index,
linkProperties,
setDropDownState
linkProperties
}: NavDropDownButtonProps) => {
const onToggle = (index: number, setIsOpen: SetState<boolean[]>): void => {
setIsOpen((prevIsOpen) => {
Expand All @@ -34,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 (
<React.Fragment key={item.id}>
<div key={item.id} ref={dropdownRef}>
<USWDSNavDropDownButton
onToggle={() => onToggle(index, setIsOpen)}
menuId={item.title}
Expand All @@ -49,8 +57,7 @@ export const NavDropDownButton = ({
items={submenuItems}
isOpen={isOpen[index]}
id={`${item.id}-dropdown`}
onClick={setDropDownState()}
/>
</React.Fragment>
</div>
);
};
15 changes: 15 additions & 0 deletions app/scripts/utils/use-click-outside.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useEffect, useRef } from 'react';
export const useClickOutside = (onClose: () => void) => {
const ref = useRef<HTMLDivElement>(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;
};

0 comments on commit 5acc803

Please sign in to comment.