89 lines
2.8 KiB
TypeScript

import { useState, useRef, useEffect } from 'react';
interface DropdownOption {
id: number;
nom: string;
}
interface DropdownProps {
options: DropdownOption[];
onSelect: (id: number | '') => void;
label: string;
}
const Dropdown: React.FC<DropdownProps> = ({ options, onSelect, label }) => {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState<DropdownOption | null>(null);
const dropdownRef = useRef<HTMLDivElement>(null);
// ferme le dropdown si on clique en dehors
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
const handleOptionSelect = (option: DropdownOption | null) => {
setSelectedOption(option);
onSelect(option ? option.id : '');
setIsOpen(false);
};
return (
<div ref={dropdownRef} className="relative w-full">
<button
type="button"
onClick={() => setIsOpen(!isOpen)}
className="w-full flex items-center justify-between px-4 py-2.5 bg-card border border-border rounded-lg shadow-sm hover:border-primary/50 transition-colors"
>
<span className="text-sm font-medium truncate">
{selectedOption ? selectedOption.nom : label}
</span>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className={`w-5 h-5 ml-2 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}
>
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
</svg>
</button>
{isOpen && (
<div className="absolute z-10 mt-1 w-full bg-card border border-border rounded-lg shadow-lg overflow-hidden animate-in fade-in-10 slide-in-from-top-5">
<ul className="py-1 max-h-60 overflow-auto bg-background/80 backdrop-blur-md">
<li>
<button
onClick={() => handleOptionSelect(null)}
className="w-full text-left px-4 py-2 text-sm hover:bg-primary/10 transition-colors "
>
Tous
</button>
</li>
{options.map((option) => (
<li key={option.id}>
<button
onClick={() => handleOptionSelect(option)}
className="w-full text-left px-4 py-2 text-sm "
>
{option.nom}
</button>
</li>
))}
</ul>
</div>
)}
</div>
);
};
export default Dropdown;