import type { ReactNode } from "react"; import type { ControlSize } from "../../Theme/tokens/primitives/controlSizes"; /** SelectV2 option shape; adds optional `icon`/`description`/`isDisabled` beyond the plain id/label pair. */ export type OptionProp = { /** Unique value of the option; what `value` selects by. */ id: string | number; /** Text shown in the row and the trigger; the search filter matches against it. */ label: string | number; /** Optional leading icon/avatar for this option's row (and the trigger, when selected). */ icon?: ReactNode; /** Optional secondary line under the label (e.g. an email under a name); not matched by the search filter. */ description?: string; /** Row is shown dimmed and clicks/Enter on it are ignored. */ isDisabled?: boolean; }; /** sm/md/lg subset kept for existing importers; the `size` prop takes the full `ControlSize` scale. */ export type SelectV2Size = "sm" | "md" | "lg"; type SelectV2CommonProps = { /** Choices in display order. */ options: OptionProp[]; /** DOM id of the trigger; the label's `for` and the message ids derive from it. Auto-generated when omitted. */ id?: string; /** Submits the selection with a surrounding `
` via hidden input(s) — one per value in multi mode. */ name?: string; /** Trigger text when nothing is selected. Defaults to "Select Option". */ placeholder?: string; /** Label above the trigger. */ label?: string; /** Marks the field invalid and swaps `helperText` for `errorMessage`. */ error?: boolean; /** Rendered only while `error` is true. */ errorMessage?: string; /** Hint under the field; hidden while `error` is true. */ helperText?: string; /** Disables the trigger; the popup cannot open. */ isDisabled?: boolean; /** Shows the value but never opens; exposed as `aria-readonly`. */ isReadOnly?: boolean; /** Label asterisk + `aria-required` only; never blocks an empty submit. */ isRequired?: boolean; /** Field control scale (xs 32 · sm 38 · md 40 · lg 48px). Defaults to `sm`. */ size?: ControlSize; /** Shows a type-ahead filter input at the top of the popup. Defaults to true. */ isSearchable?: boolean; /** Width applied to the trigger + popup. Defaults to 100% of the container. */ width?: string | number; /** Inline style on the wrapping FormControl (label + trigger + message). */ formControlStyle?: React.CSSProperties; /** Fires when the popup closes, not on DOM blur; stays silent while multi-select keeps it open. */ onBlur?: () => void; /** Fires when the popup opens, not on DOM focus of the trigger. */ onFocus?: () => void; /** Forwarded to the trigger button — lets call sites keep existing RTL/e2e queries when migrating from `Select`. */ "data-testid"?: string; /** Forwarded to the trigger button — for a labelless select (no `label` prop) that still needs an accessible name. */ "aria-label"?: string; /** Full control over an option row's contents; receives `isSelected`/`isActive` to mirror the built-in states. */ renderOption?: (option: OptionProp, state: { isSelected: boolean; isActive: boolean; }) => ReactNode; /** Custom trigger content when a value (or values) is selected. Falls back to label text / icon. */ renderValue?: (selected: OptionProp[]) => ReactNode; /** Max popup height before the option list scrolls. Defaults to "16rem". */ maxMenuHeight?: string; /** Opens the popup on mount (inline-edit cells); click-away still closes it and fires `onBlur`. */ defaultOpen?: boolean; /** Shows a loading row under the options and marks the listbox `aria-busy`. */ isLoading?: boolean; /** Text of the loading row. Defaults to "Loading...". */ loadingText?: string; /** Fires when the list is scrolled to its end and `isLoading` is false — append the next page to `options`. */ onLoadMore?: () => void; /** Fires with the filter text on every keystroke, for server-side search; local label filtering still applies. */ onSearchChange?: (query: string) => void; }; /** Single-select arm of `SelectV2Props`; `isMulti` false/absent discriminates it from the multi variant. */ /** @deprecated Use `SelectSingleProps` (`native={false}`). */ export type SelectV2SingleProps = SelectV2CommonProps & { /** False or absent selects this single-select variant. */ isMulti?: false; /** Selected option `id`; compared as strings, so `1` matches `"1"`. */ value?: string | number; /** The canonical change callback for every picker in this library. */ onChange: (selectedOption: OptionProp | undefined) => void; }; /** Multi-select arm of `SelectV2Props`; `isMulti: true` discriminates it and makes `value` an array. */ /** @deprecated Use `SelectMultiProps` (`native={false}`). */ export type SelectV2MultiProps = SelectV2CommonProps & { /** True makes `value` an array and `onChange` receive the full selection. */ isMulti: true; /** Selected option ids; ids with no matching option are dropped from the display. */ value?: (string | number)[]; /** The canonical change callback; receives the full selection. */ onChange: (selectedOptions: OptionProp[]) => void; /** Feeds the trigger's aria-label summary once chips are collapsed. Defaults to 2. */ maxLabelsBeforeSummary?: number; /** Chips shown before the rest collapse into a "+N" chip. Defaults to 6. */ maxVisibleChips?: number; }; /** Props for `SelectV2`; a discriminated union on `isMulti` between the single and multi variants. */ /** @deprecated Use `SelectProps` with `native={false}`; `SelectV2` forwards every prop to `Select` unchanged. */ export type SelectV2Props = SelectV2SingleProps | SelectV2MultiProps; export {};