"use client"; import * as React from "react"; import { Check, ChevronsUpDown, Search } from "lucide-react"; import { cn } from "@/lib/utils"; interface Supplier { code: string; nom: string; } interface SupplierComboboxProps { fournisseurs: Supplier[]; selectedCode: string | null; onSelect: (code: string) => void; className?: string; /** Libellé du bouton quand rien n'est choisi. */ placeholder?: string; } /** Nombre de fournisseurs listés : la liste complète (plusieurs milliers) figeait l'ouverture. */ const AFFICHAGE_MAX = 50; /** Choix d'un fournisseur, avec recherche par nom ou par code. */ export function SupplierCombobox({ fournisseurs, selectedCode, onSelect, className, placeholder = "Choisir un fournisseur…" }: SupplierComboboxProps) { const [open, setOpen] = React.useState(false); const [search, setSearch] = React.useState(""); const containerRef = React.useRef(null); const selectedSupplier = fournisseurs.find((f) => f.code === selectedCode); const { affiches, total } = React.useMemo(() => { const s = search.trim().toLowerCase(); const trouves = s ? fournisseurs.filter((f) => f.nom.toLowerCase().includes(s) || f.code.toLowerCase().includes(s)) : fournisseurs; return { affiches: trouves.slice(0, AFFICHAGE_MAX), total: trouves.length }; }, [fournisseurs, search]); // Fermeture au clic à l'extérieur React.useEffect(() => { function handleClickOutside(event: MouseEvent) { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setOpen(false); } } document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, []); return (
{open && (
setSearch(e.target.value)} className="w-full border-none bg-transparent py-1 text-sm text-[var(--text-primary)] outline-none placeholder:text-[var(--text-muted)]" />
{affiches.length === 0 ? (
Aucun fournisseur ne correspond.
) : ( affiches.map((f) => ( )) )} {total > affiches.length && (
{affiches.length} premiers sur {total.toLocaleString("fr-FR")} — précisez la recherche
)}
)}
); }