UNPKG

laif-ds

Version:

Design System di Laif con componenti React basati su principi di Atomic Design

147 lines (116 loc) 6 kB
# MultipleSelector (Deprecated) ## Overview Tag-style multi-select built on `cmdk` and `Popover` with search, grouping, creatable options, and badges for selections. - ⚠️ This component is deprecated. Prefer `AppSelect` for new code. --- ## Types ```ts // Deprecated interface. Prefer AppSelect options. export interface Option { value: string; label: string; disable?: boolean; fixed?: boolean; // fixed option that can't be removed [key: string]: string | boolean | undefined; // for grouping keys } ``` --- ## Props (highlights) | Prop | Type | Default | Description | | ----------------------------- | -------------------------------------- | ------------------------------- | ----------- | | `value` | `Option[]` | `[]` | Controlled selected options. | | `defaultOptions` | `Option[]` | `[]` | Initial options to display. | | `options` | `Option[]` | `undefined` | Manually controlled options (when not using search). | | `placeholder` | `string` | `"Cerca..."` | Input placeholder. | | `onSearch` | `(q: string) => Promise<Option[]>` | `undefined` | Async search. Debounced by `delay`. | | `onSearchSync` | `(q: string) => Option[]` | `undefined` | Sync search alternative. | | `delay` | `number` | `500` | Debounce ms for `onSearch`. | | `triggerSearchOnFocus` | `boolean` | `false` | Trigger search when input focuses. | | `onChange` | `(opts: Option[]) => void` | `undefined` | Fired on selection change. | | `maxSelected` | `number` | `Number.MAX_SAFE_INTEGER` | Selection limit. | | `onMaxSelected` | `(limit: number) => void` | `undefined` | Called when limit reached. | | `groupBy` | `string` | `undefined` | Group options by key. | | `disabled` | `boolean` | `false` | Disable interactions. | | `hidePlaceholderWhenSelected` | `boolean` | `true` | Hide placeholder when badges exist. | | `selectFirstItem` | `boolean` | `true` | Cmdk behavior workaround. | | `creatable` | `boolean` | `false` | Allow creating new option if not found. | | `hideClearAllButton` | `boolean` | `false` | Hide the clear-all icon. | | `className` | `string` | `""` | Trigger wrapper classes. | | `badgeClassName` | `string` | `""` | Badge classes. | | `label` | `string | React.ReactNode` | `undefined` | Optional label above control. | Also exposes `commandProps` and `inputProps` to pass through to internal `Command` and search input. --- ## Behavior - **Search**: Use `onSearch` (async) or `onSearchSync` (sync). Debounced input. - **Grouping**: Provide `groupBy` key to group options. - **Creatable**: When enabled, offers "Create \"query\"" item when not found. - **Badges**: Selected options render as removable badges. `fixed` badges cannot be removed. - **Limits**: Enforces `maxSelected`; calls `onMaxSelected` when exceeded. - **Clear all**: Built-in clear-all icon (hidden with `hideClearAllButton`). - **Disabled**: Disables input and badge removal. --- ## Examples ### Default ```tsx import { MultipleSelector } from "laif-ds"; export function DefaultMulti() { return ( <div className="w-[400px]"> <MultipleSelector placeholder="Seleziona dei tag..." defaultOptions={[ { value: "react", label: "React" }, { value: "typescript", label: "TypeScript" }, ]} /> </div> ); } ``` ### Grouped Options ```tsx import { MultipleSelector } from "laif-ds"; const frameworks = [ { value: "react", label: "React", category: "Frontend" }, { value: "node", label: "Node.js", category: "Backend" }, ]; export function Grouped() { return ( <div className="w-[400px]"> <MultipleSelector placeholder="Seleziona dei framework..." defaultOptions={frameworks} groupBy="category" /> </div> ); } ``` ### Async Search ```tsx import { MultipleSelector } from "laif-ds"; async function mockSearch(query: string) { await new Promise((r) => setTimeout(r, 300)); const tags = [ { value: "react", label: "React" }, { value: "typescript", label: "TypeScript" }, ]; return tags.filter((t) => t.label.toLowerCase().includes(query.toLowerCase())); } export function AsyncSearch() { return ( <div className="w-[400px]"> <MultipleSelector placeholder="Cerca dei tag..." onSearch={mockSearch} delay={300} triggerSearchOnFocus /> </div> ); } ``` --- ## Notes - **Use AppSelect**: Prefer `AppSelect` for multiselect scenarios. - **A11y**: The trigger is keyboard-accessible; ensure label association when using `label`.