Update shared components (ComingSoon, SelectTrigger, AnnouncementBanner, modals, social cards). Add usePatina hook. Refine API services, error handling, query invalidation, state management. Update i18n strings (en/fr/es). Update routing and app configuration. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
import { ChevronDown, X } from 'lucide-react';
|
|
import { Button } from '../button';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface SelectTriggerProps {
|
|
displayValue: string;
|
|
placeholder: string;
|
|
value?: string | string[];
|
|
multiple: boolean;
|
|
disabled: boolean;
|
|
open: boolean;
|
|
className?: string;
|
|
ariaLabel?: string;
|
|
ariaLabelledBy?: string;
|
|
onClear: (e: React.MouseEvent) => void;
|
|
}
|
|
|
|
export function SelectTrigger({
|
|
displayValue,
|
|
placeholder,
|
|
value,
|
|
multiple,
|
|
disabled,
|
|
open,
|
|
className,
|
|
ariaLabel,
|
|
ariaLabelledBy,
|
|
onClear,
|
|
}: SelectTriggerProps) {
|
|
const hasValue =
|
|
value &&
|
|
((Array.isArray(value) && value.length > 0) || !Array.isArray(value));
|
|
const showPlaceholder = multiple ? !hasValue : !displayValue;
|
|
|
|
return (
|
|
<Button
|
|
variant="outline"
|
|
disabled={disabled}
|
|
className={cn(
|
|
'w-full justify-between',
|
|
showPlaceholder ? 'text-muted-foreground' : '',
|
|
className,
|
|
)}
|
|
type="button"
|
|
aria-label={ariaLabel}
|
|
aria-labelledby={ariaLabelledBy}
|
|
aria-haspopup="listbox"
|
|
aria-expanded={open}
|
|
>
|
|
<span className="truncate">{showPlaceholder ? placeholder : displayValue}</span>
|
|
<div className="flex items-center gap-1 ml-2">
|
|
{hasValue && (
|
|
<span
|
|
role="button"
|
|
tabIndex={0}
|
|
onClick={onClear}
|
|
onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClear?.(e as unknown as React.MouseEvent); } }}
|
|
className="shrink-0 opacity-50 hover:opacity-100 transition-opacity cursor-pointer"
|
|
aria-label="Effacer la sélection"
|
|
>
|
|
<X className="h-4 w-4" />
|
|
</span>
|
|
)}
|
|
<ChevronDown className="h-4 w-4 shrink-0 opacity-50" />
|
|
</div>
|
|
</Button>
|
|
);
|
|
}
|