Files
n3wt-school/Front-End/src/components/DropdownMenu.js
2025-04-15 19:41:42 +02:00

81 lines
2.3 KiB
JavaScript

// Composant générique pour les menus dropdown
import { useRouter } from 'next/navigation';
import React, { useState, useEffect, useRef } from 'react';
const DropdownMenu = ({
buttonContent,
items,
buttonClassName,
menuClassName,
dropdownOpen: propDropdownOpen,
setDropdownOpen: propSetDropdownOpen,
}) => {
const [dropdownOpen, setDropdownOpen] = useState(false);
const menuRef = useRef(null);
const router = useRouter();
const isControlled =
propDropdownOpen !== undefined && propSetDropdownOpen !== undefined;
const actualDropdownOpen = isControlled ? propDropdownOpen : dropdownOpen;
const actualSetDropdownOpen = isControlled
? propSetDropdownOpen
: setDropdownOpen;
const handleClickOutside = (event) => {
if (menuRef.current && !menuRef.current.contains(event.target)) {
actualSetDropdownOpen(false);
}
};
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
const renderMenuItem = (item, index) => {
// Si l'élément est de type 'info', afficher simplement le contenu
if (item.type === 'info') {
return <div key={index}>{item.content}</div>;
}
// Si l'élément est de type 'separator', afficher le séparateur
if (item.type === 'separator') {
return <div key={index}>{item.content}</div>;
}
// Par défaut ou si l'élément est de type 'item', afficher un bouton cliquable
return (
<button
key={index}
className="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2"
onClick={() => {
item.onClick();
actualSetDropdownOpen(false);
}}
>
{item.icon && <item.icon className="w-4 h-4" />}
<span className="flex items-center justify-center">{item.label}</span>
</button>
);
};
return (
<div className="relative" ref={menuRef}>
<button
className={buttonClassName}
onClick={() => actualSetDropdownOpen(!actualDropdownOpen)}
>
{buttonContent}
</button>
{actualDropdownOpen && (
<div className={menuClassName}>
{items.map((item, index) => renderMenuItem(item, index))}
</div>
)}
</div>
);
};
export default DropdownMenu;