Skip to content

Commit

Permalink
[#524] Menu 컴포넌트 개선 (#525)
Browse files Browse the repository at this point in the history
* feat: useOutsideClickRef hook 구현

* fix: menu 컴포넌트 style 수정, 외부 클릭시 close
  • Loading branch information
gxxrxn committed Jun 17, 2024
1 parent a1673f6 commit 52687da
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
42 changes: 42 additions & 0 deletions src/hooks/useOutsideClickRef.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { RefObject, useEffect, useRef } from 'react';

const useOutsideClickRef = <T extends HTMLElement = HTMLElement>(
handler: () => void
) => {
const ref = useRef<T>(null);

useEffect(() => {
const onClick = (event: MouseEvent) => {
if (ref && isValidEvent(event, ref)) {
handler();
}
};

const doc = getOwnerDocument(ref.current);

doc.addEventListener('click', onClick);

return () => {
doc.removeEventListener('click', onClick);
};
}, [handler]);

return ref;
};

const isValidEvent = (event: Event, ref: RefObject<HTMLElement>) => {
const target = event.target as HTMLElement;

if (target) {
const doc = getOwnerDocument(target);
if (!doc.contains(target)) return false;
}

return !ref.current?.contains(target);
};

const getOwnerDocument = (node?: Element | null): Document => {
return node?.ownerDocument ?? document;
};

export default useOutsideClickRef;
9 changes: 7 additions & 2 deletions src/v1/base/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import {
useMemo,
useState,
} from 'react';

import { IconHamburger } from '@public/icons';
import useOutsideClickRef from '@/hooks/useOutsideClickRef';

import BottomSheet from './BottomSheet';

type MenuContextValue = {
Expand All @@ -23,8 +26,10 @@ const Menu = ({ children }: { children?: React.ReactNode }) => {
const toggle = useCallback(() => setOpen(prev => !prev), []);
const value = useMemo(() => ({ isOpen, toggle }), [isOpen, toggle]);

const ref = useOutsideClickRef<HTMLDivElement>(() => setOpen(false));

return (
<div className="relative">
<div className="relative" ref={ref}>
<MenuContext.Provider value={value}>{children}</MenuContext.Provider>
</div>
);
Expand Down Expand Up @@ -57,7 +62,7 @@ const DropdownList = ({ children }: { children?: React.ReactNode }) => {
return (
<>
{isOpen && (
<ul className="absolute right-0 top-[3rem] min-w-[10rem] rounded-[0.5rem] py-[0.5rem] shadow-[0_0_15px_rgba(0,0,0,0.05),0_1px_2px_rgba(0,0,0,0.1)]">
<ul className="absolute right-0 top-[3rem] z-50 min-w-[10rem] rounded-[0.5rem] bg-white py-[0.5rem] shadow-[0_0_15px_rgba(0,0,0,0.05),0_1px_2px_rgba(0,0,0,0.1)]">
{children}
</ul>
)}
Expand Down

0 comments on commit 52687da

Please sign in to comment.