import type React from "react"; import type { ComboboxContent } from "src/primitives/Combobox"; import type { FieldLabel } from "src/primitives/Field"; export interface OptionBase { /** Display text for the option. */ label: string; /** Unique value for the option. */ value: string; /** Whether the option is disabled. */ disabled?: boolean; } export interface OptionGroup { /** Group heading text. */ label: string; /** Options within this group. */ options: OptionBase[]; } export type Option = OptionBase | OptionGroup; export declare function isOptionGroup(opt: Option): opt is OptionGroup; export type SelectOptionBase = OptionBase; export type SelectOptionGroup = OptionGroup; export type SelectOption = Option; type SelectSize = "small" | "medium" | "large"; interface SelectSharedProps { /** Unique identifier for the select. Auto-generated if omitted. */ id?: string; /** Name attribute forwarded to the underlying input. */ name?: string; /** Size of the trigger. */ size?: SelectSize; /** Label displayed above the select. */ label?: string; /** Error message displayed below the select. */ error?: string; /** Help text displayed below the select. */ helpText?: React.ReactNode; /** Placeholder text when no value is selected. */ placeholder?: string; /** Flat or grouped option list. */ options?: SelectOption[]; /** Disable the select. */ isDisabled?: boolean; /** Mark as required. */ required?: boolean; /** * Enable search/filtering of options by typing in the input. * When false, the input is hidden and the trigger shows the selected label. * @default true */ isSearchable?: boolean; /** Whether the first matching item is highlighted automatically. @default true */ autoHighlight?: boolean; /** Callback fired when the dropdown opens or closes. */ onOpenChange?: (open: boolean) => void; /** * Positioning strategy for the dropdown content. * @deprecated The Combobox primitive always uses popper-style positioning. * Use `contentProps.side` and `contentProps.align` for positioning control. */ position?: "item-aligned" | "popper"; /** Show a clear/reset button when a value is selected. */ isClearable?: boolean; /** * Allow creating new options by typing a value that doesn't exist. * Works in both single and multi mode. */ isCreatable?: boolean; /** * Callback fired when a new option is created via the "Create X" item. * The parent should update the `options` list to include the new value. */ onCreateOption?: (inputValue: string) => void; /** * Customize the label for the "Create" option in the dropdown. * @default (inputValue) => `Create "${inputValue}"` */ formatCreateLabel?: (inputValue: string) => string; /** * Async function that fetches options based on the current input value. * Works in both single and multi mode. */ loadOptions?: (inputValue: string) => Promise; /** * Options to show before the user types anything. * When `true`, `loadOptions("")` is called on mount. * @default false */ defaultOptions?: boolean | SelectOptionBase[]; /** * Cache results from `loadOptions` so repeated queries are instant. * @default false */ cacheOptions?: boolean; /** Text shown while `loadOptions` is fetching. @default "Loading…" */ loadingMessage?: string; /** Text displayed when no options match. @default "No results found." */ emptyMessage?: string; /** * Enable lazy loading of options as the user scrolls. * @default false */ isAsyncLoadOptionEnabled?: boolean; /** Callback to load the next batch of options (lazy loading). */ fetchMore?: () => void; /** Total number of options on the server (lazy loading). */ totalOptionsCount?: number; /** Custom data-testid prefix for the component tree. */ dataTestId?: string; /** Props forwarded to the FieldLabel. */ labelProps?: Omit, "htmlFor" | "children">; /** Props forwarded to the ComboboxContent. */ contentProps?: Omit, "anchor" | "children">; /** Additional CSS class names for the outermost wrapper. */ className?: string; /** Additional CSS class names for the input/trigger element. */ inputClassName?: string; /** Children rendered inside the dropdown (overrides `options`). */ children?: React.ReactNode; /** * Customize how each option is rendered. Receives the matched option (looked * up from `options` by value) and returns a ReactNode. Used in the dropdown * list and in the trigger (single-select label / multi-select chips). * String filtering still uses `option.label` for searchable behavior. */ formatOptionLabel?: (option: SelectOptionBase) => React.ReactNode; /** * Extract the value string from a raw option object. Use when your options * are not already in `{ value, label }` shape (for example `{ id, name }`). * Called for each entry in `options`, each group child, `defaultOptions`, and * the array returned from `loadOptions`. Without this prop the option must * already have a `value` field. */ getOptionValue?: (option: any) => string; /** * Extract the label string from a raw option object. Pairs with * `getOptionValue` to support custom option shapes without forcing * call-site `.map` boilerplate. Without this prop the option must already * have a `label` field. */ getOptionLabel?: (option: any) => string; /** * Customize how the selected value is rendered in the trigger only. When * provided, takes precedence over `formatOptionLabel` for the trigger; * dropdown rows still use `formatOptionLabel` (or the default label). * Single-select only. Useful when the trigger needs a compact representation * (e.g. flag-only) while options show fuller content (flag + name). */ formatTriggerLabel?: (option: SelectOptionBase) => React.ReactNode; } interface SingleSelectProps extends SelectSharedProps { /** When true, multiple values can be selected and the trigger shows chips. @default false */ isMulti?: false; /** Controlled selected value. */ value?: string; /** Default selected value (uncontrolled). */ defaultValue?: string; /** Callback fired when value changes. */ onChange?: (value: string) => void; } interface MultiSelectVariantProps extends SelectSharedProps { /** When true, multiple values can be selected and the trigger shows chips. */ isMulti: true; /** Controlled selected values. */ value?: string[]; /** Default selected values (uncontrolled). */ defaultValue?: string[]; /** Callback fired when selected values change. */ onChange?: (values: string[]) => void; /** Additional CSS class names for the chips container. */ chipsClassName?: string; /** Hide the remove button on individual chips. */ hideChipRemove?: boolean; } export type SelectProps = SingleSelectProps | MultiSelectVariantProps; export type MultiSelectProps = Extract; export {};