1- import { createContext , useContext , useState } from 'react'
1+ import { createContext , useContext , useEffect , useRef , useState } from 'react'
22
33import clsx from 'clsx'
44import { twMerge } from 'tailwind-merge'
@@ -25,23 +25,32 @@ const useDropdownContext = () => {
2525
2626const Dropdown = ( { children, className } : BaseProps ) : JSX . Element => {
2727 const [ isOpen , setIsOpen ] = useState ( false )
28+ const dropdownRef = useRef < HTMLDivElement > ( null )
2829
2930 const toggle = ( ) => setIsOpen ( ! isOpen )
3031 const close = ( ) => setIsOpen ( false )
3132
3233 const dropdownClass = twMerge ( 'relative' , className )
3334
34- const handleBlur = ( event : React . FocusEvent < HTMLDivElement > ) => {
35- const relatedTarget = event . relatedTarget as HTMLElement
36-
37- if ( ! relatedTarget || ! event . currentTarget . contains ( relatedTarget ) ) {
35+ const handleClickOutside = ( event : MouseEvent ) => {
36+ if (
37+ dropdownRef . current &&
38+ ! dropdownRef . current . contains ( event . target as Node )
39+ ) {
3840 close ( )
3941 }
4042 }
4143
44+ useEffect ( ( ) => {
45+ document . addEventListener ( 'mousedown' , handleClickOutside )
46+ return ( ) => {
47+ document . removeEventListener ( 'mousedown' , handleClickOutside )
48+ }
49+ } , [ ] )
50+
4251 return (
4352 < DropdownContext . Provider value = { { isOpen, toggle, close } } >
44- < div className = { dropdownClass } onBlur = { handleBlur } >
53+ < div ref = { dropdownRef } className = { dropdownClass } tabIndex = { - 1 } >
4554 { children }
4655 </ div >
4756 </ DropdownContext . Provider >
0 commit comments