import { ReactNode, Ref, MouseEvent } from 'react'; import { ButtonSize } from './Button.js'; import { PopoverOffset, PopoverPosition } from './Popover.js'; interface SelectOptionRenderParams { value: T; index: number; selected: boolean; } import { Color } from '../types.js'; import { ButtonProps } from './Button.js'; import { ShortcutSize } from './Shortcut.js'; import { SurfaceVariant } from './Surface.js'; /** * Props shared by both select modes. `value`, `multiple`, and `onChange` are * added by the mode-specific interfaces below so `onChange` can be typed * precisely per mode (single → `V`, multiple → `V[]`). */ interface SelectBaseProps { /** Placeholder node shown in the trigger when `value` is empty and no `children` are provided. */ placeholder?: ReactNode; /** Title shown at the top of the popover (above the search bar, if any). */ title?: string; /** All available options. Compared against `value` via `getOptionValue` (default: identity). */ options?: T[]; /** Visually dim the trigger and prevent the popover from opening. */ disabled?: boolean; /** Show the trigger with the current value but block opening the popover. */ readOnly?: boolean; /** Accent color for the trigger button. Forwarded to `Button.color`. */ color?: Color; /** Pill-style trigger button. Forwarded to `Button.rounded`. */ rounded?: boolean; /** Render the trigger button's surface outline ring. Forwarded to `Button.outline`. */ outline?: boolean; /** Trigger button size. Forwarded to `Button.size`. */ size?: ButtonSize; /** Extra classes for the trigger button. */ className?: string; /** Extra classes for the trigger button's inner content row. */ contentClassName?: string; /** Extra classes for the value display inside the trigger button. */ valueClassName?: string; /** * Trigger button surface type, forwarded to the underlying `Button.surface`: `'surface'` (default) for a regular button, `'cut'` for an inset/recessed look. */ surface?: 'surface' | 'cut'; /** Reverse the visual order of `icon` ↔ value inside the trigger button. */ reverse?: boolean; /** Icon node rendered inside the trigger button. */ icon?: ReactNode; /** Extra classes for the icon wrapper. */ iconClassName?: string; /** Show the chevron-down indicator on the right of the trigger. Default `true`. */ dropdownIcon?: boolean; /** Forwarded to the trigger `Button` - allows wrapping the value across multiple lines. */ multiline?: boolean; /** Extra classes applied to the value/placeholder container inside the trigger. */ placeholderClassName?: string; /** * Custom node rendered inside the trigger button in place of `String(value) || placeholder`. * * Use to render a richer value display (e.g. with icons or formatting). */ children?: ReactNode; /** Slot rendered inside the popover, **above** the option list (after title/search field). */ beforeOptions?: ReactNode; /** Slot rendered inside the popover, **below** the option list. */ afterOptions?: ReactNode; /** Render a search bar at the top of the popover. Pair with `onSearch` to filter options. */ search?: boolean; /** Default `'Search'`. */ searchPlaceholder?: string; /** Empty-state text. Default `'Nothing found'`. */ searchNotFound?: string; /** Auto-focus the search input when the popover opens (skipped on iOS/Android to avoid keyboard popup). */ searchFocus?: boolean; /** * Filter callback invoked with the current query - return the filtered list of options. * * The Select does not maintain any internal filter state; callers control matching. */ onSearch?: (query: string) => T[]; /** Accent color for the popover. Forwarded to `Popover.color`. */ popoverColor?: Color; /** Default `'bottom-end'`. */ popoverPosition?: PopoverPosition; /** Default `['-50%', 4]` - half-width inward shift on the cross axis, 4px main-axis gap. */ popoverOffset?: PopoverOffset; /** Default `'w-auto min-w-[160px]'`. */ popoverClassName?: string; /** * Surface level for the popover. * * Default same as Popover's `surfaceLevel` prop. */ popoverSurfaceLevel?: number | string; /** * External anchor ref. When provided, the trigger button is **not rendered** - useful when the popover should anchor to an existing element controlled by the caller (the caller is then responsible for the trigger and `popoverState` wiring). */ anchorRef?: React.RefObject; /** Controlled popover open state. Pair with `onPopoverState`. */ popoverState?: boolean; /** Fires whenever the popover open state changes. Acts as the controlled setter when `popoverState` is provided, and as an observer otherwise. */ onPopoverState?: (state: boolean) => void; /** Fires when the trigger button is clicked (before the popover state toggles). */ onClick?: (e: MouseEvent) => void; /** * Show numeric quick-pick hints (0–9) next to options, and bind `0`–`9` keys to select them. * * Default `true`. See `noneOptionValue` for how the digits map to options. */ keyboardHints?: boolean; /** `variant` forwarded to the per-option `Shortcut` hint. Default `'transparent'`. */ keyboardHintsVariant?: SurfaceVariant; /** `outline` forwarded to the per-option `Shortcut` hint. Default `false`. */ keyboardHintsOutline?: boolean; /** Extra classes for the per-option `Shortcut` hint's key element. */ keyboardHintsClassName?: string; /** `size` forwarded to the per-option `Shortcut` hint. Default `'md'`. */ keyboardHintsSize?: ShortcutSize; /** Default color for the per-option indicator (Radio/Checkbox). Overridden per-option by `optionIndicatorColor`. */ indicatorColor?: Color; /** Per-option indicator color. Return `undefined` to fall back to `indicatorColor`. */ optionIndicatorColor?: (params: SelectOptionRenderParams) => Color | undefined; /** Custom "is this option selected?" predicate - overrides the built-in equality check. */ isChecked?: (value: T) => boolean; /** Predicate that disables individual options - dims them and prevents selection. */ isOptionDisabled?: (value: T) => boolean; /** * Extracts the comparable key `V` from each option. Default: identity (`V = T`). * * Required when options are objects and `value` should be a key (e.g. `id`) * rather than a full option reference. */ getOptionValue?: (option: T) => V; /** Slot rendered above each option (e.g. group header before the first item in a section). */ renderBeforeOption?: (value: T, index: number) => ReactNode; /** Slot rendered below each option. */ renderAfterOption?: (value: T, index: number) => ReactNode; /** Custom option label renderer. Default: `String(value)`. */ renderOption?: (params: SelectOptionRenderParams) => ReactNode; /** Subtext rendered under the option label. */ renderOptionInfo?: (params: SelectOptionRenderParams) => ReactNode; /** * Value of the "none/initial" option that should be mapped to the 0 key. * * If set, this option gets hint "0" and remaining options get 1-9 in order. * * If not set, straight ordering: 1, 2, 3, ..., 9, 0 (for 10th). */ noneOptionValue?: V; /** Close the popover after a single-select pick. Default `true`. Has no effect when `multiple`. */ closeOnSelect?: boolean; /** Scroll the popover so the currently selected option is centered when it opens. */ scrollToSelected?: boolean; /** Forwarded to the trigger button. Ignored when `anchorRef` is provided (no trigger is rendered). */ ref?: Ref; } /** * The `multiple`/`value`/`onChange` trio, discriminated on the inferred * `Multiple` flag so `value` and `onChange` are scalar `V` in single-select and * `V[]` in multi-select. * * `Multiple` is inferred from the `multiple` prop (omitted or `false` → single, * `true` → multi). `T`/`V` are inferred from `options`/`getOptionValue`, never * from `value`, so a `value` of `V[]` can't pollute `V` the way a plain * discriminated union of interfaces would. */ interface SelectSelectionProps { /** Multi-select mode - uses `Checkbox` instead of `Radio` and emits `V[]` to `onChange`. */ multiple?: Multiple; /** * Selected value(s) — always the **key** type `V`, not the full option `T`. * Scalar `V` in single-select, `V[]` when `multiple`. When options are objects * and `getOptionValue` extracts a key (e.g. `id`), store that key in state, * not the object itself. */ value?: Multiple extends true ? V[] : V; /** Fires after a selection. Receives the selected key `V`, or the full `V[]` when `multiple`. */ onChange?: (value: Multiple extends true ? V[] : V) => void; } export type SelectProps = SelectBaseProps & SelectSelectionProps & Omit | keyof SelectSelectionProps>; /** Shape of `Select` defaults that can be supplied via `CladdProvider`'s `defaults` prop. */ export type SelectDefaultProps = Partial>; export declare function Select(props: SelectProps): import("react/jsx-runtime").JSX.Element; export {}; //# sourceMappingURL=Select.d.ts.map