"use client"; import type { InputHTMLAttributes, ReactNode, SelectHTMLAttributes } from "react"; import { Search, X } from "lucide-react"; import { cn } from "@/lib/utils"; const CHAMP = "h-9 rounded-lg border px-3 text-sm bg-[var(--bg-surface)] border-[var(--border-strong)] text-[var(--text-primary)] " + "placeholder:text-[var(--text-muted)] focus:outline-none focus:border-[var(--accent)] focus:ring-2 focus:ring-[var(--accent-bg)] " + "disabled:opacity-60 disabled:cursor-not-allowed"; /** Libellé au-dessus d'un champ (et non à côté) : plus lisible en colonne étroite. */ export function Label({ children, htmlFor, className }: { children: ReactNode; htmlFor?: string; className?: string }) { return ( ); } export interface SelectOption { value: string; label: string; } interface SelectProps extends Omit, "onChange"> { label?: ReactNode; options: readonly SelectOption[]; onChange: (value: string) => void; /** Option vide en tête (« Tous », « Tous les fournisseurs »…). */ placeholder?: string; } /** Liste déroulante native, au style du thème. */ export function Select({ label, options, onChange, placeholder, className, id, ...props }: SelectProps) { const select = ( ); if (!label) return select; return (
{select}
); } interface SearchInputProps extends Omit, "onChange" | "value"> { value: string; onChange: (value: string) => void; } /** Champ de recherche avec loupe et bouton d'effacement. */ export function SearchInput({ value, onChange, className, placeholder = "Rechercher…", ...props }: SearchInputProps) { return (
onChange(e.target.value)} placeholder={placeholder} className={cn(CHAMP, "w-full min-w-[240px] pl-9 pr-8")} {...props} /> {value && ( )}
); } export function Input({ className, ...props }: InputHTMLAttributes) { return ; }