Skip to content

Commit 5484dd0

Browse files
committed
[#97] ✨ make sure dropdown to close when clicked outside of the menu
1 parent a901256 commit 5484dd0

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

src/components/common/dropdown/Dropdown.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createContext, useContext, useState } from 'react'
1+
import { createContext, useContext, useEffect, useRef, useState } from 'react'
22

33
import clsx from 'clsx'
44
import { twMerge } from 'tailwind-merge'
@@ -25,23 +25,32 @@ const useDropdownContext = () => {
2525

2626
const 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

Comments
 (0)