import { CSSProperties } from 'react'; import { FormValidator } from '../../services/formValidation/index.js'; import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js'; import { Presentation } from '../configProvider/presentation.types.js'; export type MultiSelectValue = string | number; export interface MultiSelectItem { key: MultiSelectValue; /** Visible text. A string, not a `ReactNode`, because it also renders inside a `Chip`. */ label: string; /** Disable just this option. */ disabled?: boolean; } export type MultiSelectSlots = 'root' | 'label' | 'fieldset' | 'control' | 'values' | 'chip' | 'placeholder' | 'clearButton' | 'icon' | 'panel' | 'search' | 'options' | 'option' | 'optionCheck' | 'optionLabel' | 'empty'; /** Text MultiSelect renders of its own, for translating it. */ export interface MultiSelectLabels { /** Button that empties the selection, read out by screen readers. */ clearSelection?: string; /** Entry that creates a value from what was typed (default `Add ""`). */ create?: (value: string) => string; /** Placeholder in the search field (default `Search…`). */ searchPlaceholder?: string; /** Shown when nothing matches the search (default `No matches`). */ empty?: string; } export interface MultiSelectProps extends Omit, 'onChange' | 'value' | 'defaultValue'> { /** The selectable options. */ items: MultiSelectItem[]; /** Controlled selection. Omit for uncontrolled. */ value?: MultiSelectValue[]; /** Initial selection when uncontrolled (default `[]`). */ defaultValue?: MultiSelectValue[]; /** Fires with the full new selection, in the order the items were picked. */ onChange?: (value: MultiSelectValue[]) => void; /** Field label. Rests inside the control and floats up into the border notch, like `Input`. */ label?: string; /** Keep the label floating even when the field is empty and unfocused (default `false`). */ alwaysFloatLabel?: boolean; /** Shown while nothing is selected. With a `label`, only once the label has floated clear. */ placeholder?: string; /** Show a search box in the panel that filters the options (default `false`). */ searchable?: boolean; /** * Let the user add a value that isn't in `items` by typing it and picking the "add" row that * appears. Implies `searchable`, since the search box is where the value is typed. The new * value becomes its own key, so `onChange` reports it as a plain string. */ allowCustomValues?: boolean; /** Cap the number of selections. Unselected options disable once the cap is reached. */ maxSelected?: number; /** Show a button that clears the whole selection (default `true`). */ clearable?: boolean; disabled?: boolean; /** Show the selection but allow no changes, without the dimming `disabled` applies. */ readOnly?: boolean; /** Where the panel opens: anchored to the control, as a bottom sheet, or a sheet only on a * small touch screen. Forwarded to `Popover`. */ presentation?: Presentation; formValidator?: FormValidator | null; /** Manual error message shown in a tooltip (used when there's no `formValidator`). */ errorMessage?: string; /** Manual valid state when not using a `formValidator` (default `true`). */ isValid?: boolean; className?: string; style?: CSSProperties; classNames?: SlotClassNames; styles?: SlotStyles; /** Overrides the text MultiSelect renders of its own. Merged per key. */ labels?: MultiSelectLabels; }