| | import { useEffect, RefObject } from 'react'; |
| | type Handler = () => void; |
| |
|
| | export default function useOnClickOutside( |
| | ref: RefObject<HTMLElement>, |
| | handler: Handler, |
| | excludeIds: string[], |
| | customCondition?: (target: EventTarget | Element | null) => boolean, |
| | ): void { |
| | useEffect(() => { |
| | const handleClickOutside = (event: MouseEvent) => { |
| | const target = event.target as Node | null; |
| |
|
| | if (target && 'id' in target && excludeIds.includes((target as HTMLElement).id)) { |
| | return; |
| | } |
| |
|
| | if ( |
| | target?.parentNode && |
| | 'id' in target.parentNode && |
| | excludeIds.includes((target.parentNode as HTMLElement).id) |
| | ) { |
| | return; |
| | } |
| |
|
| | if (customCondition && customCondition(target)) { |
| | return; |
| | } |
| |
|
| | if (ref.current && !ref.current.contains(target)) { |
| | handler(); |
| | } |
| | }; |
| |
|
| | document.addEventListener('mousedown', handleClickOutside); |
| | return () => { |
| | document.removeEventListener('mousedown', handleClickOutside); |
| | }; |
| | |
| | }, [ref, handler]); |
| | } |
| |
|