mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-23 06:51:12 +02:00
add dropdown file
This commit is contained in:
71
src/components/Dropdown.jsx
Normal file
71
src/components/Dropdown.jsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { useState, useRef, useEffect } from 'preact/hooks';
|
||||
|
||||
const DropdownMenu = ({
|
||||
btnProps = {},
|
||||
btnContent,
|
||||
menuItems,
|
||||
position = 'top'
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const triggerRef = useRef(null);
|
||||
const menuRef = useRef(null);
|
||||
|
||||
const toggleDropdown = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
const handleClickOutside = event => {
|
||||
if (
|
||||
menuRef.current &&
|
||||
!menuRef.current.contains(event.target) &&
|
||||
!triggerRef.current.contains(event.target)
|
||||
) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', handleClickOutside);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="dropdown">
|
||||
<button
|
||||
ref={triggerRef}
|
||||
onClick={toggleDropdown}
|
||||
aria-haspopup="true"
|
||||
aria-expanded={isOpen}
|
||||
{...btnProps}
|
||||
className={`dropdown-trigger ${btnProps?.className}`}
|
||||
>
|
||||
{btnContent}
|
||||
</button>
|
||||
{isOpen && (
|
||||
<ul
|
||||
ref={menuRef}
|
||||
role="menu"
|
||||
className={`popup dropdown-menu dropdown-menu-${position}`}
|
||||
>
|
||||
{menuItems.map((item, index) => (
|
||||
<li key={index} role="menuitem">
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
item.onClick();
|
||||
}}
|
||||
className="dropdown-item"
|
||||
>
|
||||
{item.label}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { DropdownMenu };
|
Reference in New Issue
Block a user