mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-23 23:11: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