label | string · requiredLabel text for accessibility. |
|---|
options | SelectorOption[] · requiredArray of items: strings, objects with value/label/description/icon/disabled, dividers ({type: "divider"}), or sections ({type: "section", title, options}). |
|---|
value | stringCurrently selected value. |
|---|
onChange | (value: string) => voidCallback fired when the selection changes. |
|---|
hasClear | boolean · default falseShows a clear (×) button when a value is selected. When true, onChange also accepts null to signal the user cleared the selection. |
|---|
hasSearch | boolean · default falseWhether to show a search input for filtering options. As the user types, the match count (or "No results found") is announced to screen readers via a polite live region. The search field has built-in affordances: a leading magnifier icon and, once a query is typed, a trailing clear (✕) button that resets the query and returns focus to the input. |
|---|
searchPlaceholder | string · default 'Search...'Placeholder text for the search input. |
|---|
emptyText | ReactNode · default 'No options'Content shown in the dropdown panel when there are no options to show, and announced in a polite live region when the panel opens (a string override is announced verbatim; a richer node falls back to the default text). Not shown while isLoading. |
|---|
emptySearchText | ReactNode · default 'No results found'Content shown in the dropdown panel when a search query matches no options, and announced in a polite live region at the same time (a string override is announced verbatim; a richer node falls back to the default text). |
|---|
placeholder | string · default 'Select...'Placeholder text shown when no value is selected. |
|---|
size | 'sm' | 'md' | 'lg' · default 'md'Size variant for the selector. |
|---|
variant | 'input' | 'ghost' · default 'input'Visual trigger style. input is the bordered input treatment for forms; ghost is borderless and matches ghost buttons for toolbar usage. |
|---|
isDisabled | boolean · default falseDisables the selector. |
|---|
isReadOnly | boolean · default falseMakes the selector read-only: the selected value stays visible, focusable, and included in form submission, and retains its combobox identity with aria-readonly. The selection surface, clear action, and disclosure indicator are removed. Unlike isDisabled, the control is not dimmed. isDisabled takes precedence when both are set. |
|---|
htmlName | stringThe HTML name attribute for form submissions. Renders a hidden input carrying the selected value, like a native select. |
|---|
disabledMessage | stringExplains why the selector is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the trigger focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled Selector in Tooltip. Disabled controls swallow the hover events an external Tooltip needs. |
|---|
isLabelHidden | boolean · default falseVisually hides the label while keeping it accessible. |
|---|
description | stringHelper text displayed below the label. |
|---|
isOptional | boolean · default falseMarks the field as optional. |
|---|
isRequired | boolean · default falseMarks the field as required. |
|---|
status | {type: 'error' | 'warning' | 'success', message?: string}Validation status with an optional message. |
|---|
statusVariant | 'attached' | 'detached' | 'tooltip' · default 'attached' for input selectors; 'detached' for ghost selectorsHow the status message is placed relative to the input. attached overlaps directly below the bordered input and is only valid for the input variant; ghost selectors detach attached status messages by default. Use tooltip for compact toolbar controls. |
|---|
renderOption | (option: SelectorOptionData) => ReactNodeCustom render function for each selectable option in the dropdown. Use this instead of JSX children; dividers and sections are rendered by the selector. |
|---|
renderValue | (option: SelectorOptionData) => ReactNodeCustom render function for the selected option inside the closed trigger. The trigger is sized by padding, so it is the size token for a one-line value (28/32/36) and exactly one text line taller for a two-line one (48/52/56), always on the 4px rhythm, always aligned with the buttons and inputs beside it. Inside an InputGroup the group owns the row height: a SelectorOption folds onto one line and ellipsizes, and any taller node is cut off at the row. |
|---|
indicatorPosition | 'start' | 'end' · default 'end'Which logical edge of the option row carries a rendered selection mark. An empty mark consumes no space, so selected and unselected labels may shift or have different available width. end is the house convention shared with Typeahead and CommandPalette. |
|---|
presentation | 'popover' | 'bottom-sheet' | 'adaptive' · default 'popover'How the option list is presented. adaptive uses a bottom sheet on compact touch screens and an anchored popover otherwise. |
|---|
width | SizeValueWidth of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned. |
|---|
startIcon | IconType | ReactNodeIcon displayed at the start of the selector trigger. |
|---|
isLoading | boolean · default falseShows a loading spinner in the trigger. |
|---|
xstyle | StyleXStylesStyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}. |
|---|