XDSSelector@xds/core · Selector
Usage
A dropdown selector for choosing a single value from a list of options. Supports labels, validation, descriptions, and required/optional states. Use it in forms and settings when presenting a moderate number of options.Best practices
| Guidance | Practices |
|---|---|
| Do | Provide a visible label so users understand what they are selecting. |
| Do | Use sections and dividers to organize options when the list exceeds ~8 items. |
| Do | Set a meaningful placeholder that hints at the expected selection (e.g. "Choose a country" not "Select..."). |
| Don't | Use for action menus — use Dropdown Menu for triggering commands or navigation. |
| Don't | Use when there are only two options — use a SegmentedControl or radio buttons instead. |
| Don't | Use Selector for navigation — links should be links, not dropdown options. |
| Don't | Use for yes/no or on/off choices — use Switch or CheckboxInput instead. |
| Don't | Put more than ~20 options without sections — consider Typeahead for large lists. |
Anatomy
| Element | Description | |
|---|---|---|
| Label | Text label displayed above the selector. | |
| Placeholder | Hint text shown when no value is selected. | |
| Description | Helper text providing additional context. | |
| Left Icon | Icon displayed to the left of the selected value. | |
| Value | required | The currently selected item displayed in the selector. |
| List | required | The dropdown list of selectable options. |
Import
tsimport {XDSSelector} from '@xds/core/Selector'
Props
| Prop | Type | Description |
|---|---|---|
labelrequired | string | Label text for accessibility. |
optionsrequired | XDSSelectorOption[] | Array of items — strings, objects with value/label/icon/disabled, dividers ({type: "divider"}), or sections ({type: "section", title, items}). |
value | string | Currently selected value. |
onChange | (value: string) => void | Callback fired when the selection changes. |
hasClear | boolean (default: false) | Shows a clear (×) button when a value is selected. When true, onChange also accepts null to signal the user cleared the selection. |
placeholder | string (default: 'Select...') | Placeholder text shown when no value is selected. |
size | 'sm' | 'md' | 'lg' (default: 'md') | Size variant for the selector. |
isDisabled | boolean | Disables the selector. |
isLabelHidden | boolean | Visually hides the label while keeping it accessible. |
description | string | Helper text displayed below the label. |
isOptional | boolean | Marks the field as optional. |
isRequired | boolean | Marks the field as required. |
status | {type: 'error' | 'warning' | 'success', message?: string} | Validation status with an optional message. |
children | (item: XDSSelectorOptionData) => ReactNode | Custom render function for each item in the dropdown. |
xstyle | StyleXStyles | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value — not an inline style object like style={{}}. |
Sub-components
Selector is a compound component with 2 sub-components.XDSSelector
Dropdown selector for choosing from a list of options.| Prop | Type | Description |
|---|---|---|
labelrequired | string | Label text for accessibility. |
optionsrequired | XDSSelectorOption[] | Array of items — strings, objects with value/label/icon/disabled, dividers ({type: "divider"}), or sections ({type: "section", title, items}). |
value | string | Currently selected value. |
onChange | (value: string) => void | Callback fired when the selection changes. |
hasClear | boolean (default: false) | Shows a clear (×) button when a value is selected. When true, onChange also accepts null to signal the user cleared the selection. |
placeholder | string (default: 'Select...') | Placeholder text shown when no value is selected. |
size | 'sm' | 'md' | 'lg' (default: 'md') | Size variant for the selector. |
isDisabled | boolean | Disables the selector. |
isLabelHidden | boolean | Visually hides the label while keeping it accessible. |
description | string | Helper text displayed below the label. |
isOptional | boolean | Marks the field as optional. |
isRequired | boolean | Marks the field as required. |
status | {type: 'error' | 'warning' | 'success', message?: string} | Validation status with an optional message. |
children | (item: XDSSelectorOptionData) => ReactNode | Custom render function for each item in the dropdown. |
xstyle | StyleXStyles | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value — not an inline style object like style={{}}. |
XDSSelectorOption
Helper component for custom item rendering inside an XDSSelector children render prop.| Prop | Type | Description |
|---|---|---|
labelrequired | ReactNode | Primary label text for the item. |
icon | XDSIconType | Icon displayed before the label. See `npx xds docs icons` for valid semantic names. |
description | ReactNode | Secondary description text displayed below the label. |
Examples
Common configurations, variations, and states.Selector — ClearableSelector with a clear button to reset the selected value.
tsx'use client';import {useState} from 'react';import {XDSSelector} from '@xds/core/Selector';import {XDSCenter} from '@xds/core/Center';export default function SelectorClearable() {const [value, setValue] = useState<string | null>('engineering');return (<XDSCenter width={250}><XDSSelectorlabel="Department"options={[{value: 'engineering', label: 'Engineering'},{value: 'design', label: 'Design'},{value: 'marketing', label: 'Marketing'},{value: 'sales', label: 'Sales'},]}value={value}onChange={setValue}placeholder="Choose a department..."hasClear/></XDSCenter>);}
Selector — Grouped SectionsSelector with options grouped into labeled sections.
tsx'use client';import {useState} from 'react';import {XDSSelector} from '@xds/core/Selector';import {XDSCenter} from '@xds/core/Center';export default function SelectorWithSections() {const [value, setValue] = useState<string | undefined>();return (<XDSCenter width={250}><XDSSelectorlabel="Office"options={[{type: 'section',title: 'North America',options: [{value: 'nyc', label: 'New York'},{value: 'sf', label: 'San Francisco'},{value: 'sea', label: 'Seattle'},],},{type: 'section',title: 'Europe',options: [{value: 'ldn', label: 'London'},{value: 'ber', label: 'Berlin'},],},{type: 'section',title: 'Asia Pacific',options: [{value: 'tyo', label: 'Tokyo'},{value: 'sgp', label: 'Singapore'},],},]}value={value}onChange={setValue}placeholder="Choose an office..."/></XDSCenter>);}
Selector — Validation StatesSelector showing error, warning, and success validation states.
tsx'use client';import {useState} from 'react';import {XDSSelector} from '@xds/core/Selector';import {XDSVStack} from '@xds/core/Layout';import {XDSCenter} from '@xds/core/Center';export default function SelectorWithStatus() {const [value1, setValue1] = useState<string | undefined>();const [value2, setValue2] = useState<string | undefined>('viewer');const [value3, setValue3] = useState<string | undefined>('admin');return (<XDSCenter width={250}><XDSVStack gap={4}><XDSSelectorlabel="Role"options={[{value: 'admin', label: 'Admin'},{value: 'editor', label: 'Editor'},{value: 'viewer', label: 'Viewer'},]}value={value1}onChange={setValue1}placeholder="Choose a role..."status={{type: 'error', message: 'Please select a role'}}/><XDSSelectorlabel="Role"options={[{value: 'admin', label: 'Admin'},{value: 'editor', label: 'Editor'},{value: 'viewer', label: 'Viewer'},]}value={value2}onChange={setValue2}status={{type: 'warning', message: 'Viewer has limited access'}}/><XDSSelectorlabel="Role"options={[{value: 'admin', label: 'Admin'},{value: 'editor', label: 'Editor'},{value: 'viewer', label: 'Viewer'},]}value={value3}onChange={setValue3}status={{type: 'success'}}/></XDSVStack></XDSCenter>);}
Showcase source
tsx'use client';import {XDSSelector} from '@xds/core/Selector';export default function SelectorShowcase() {return (<XDSSelectorlabel="Fruit"isDefaultOpenoptions={['Apple', 'Banana', 'Orange', 'Mango', 'Pineapple']}placeholder="Select a fruit..."onChange={() => {}}/>);}