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

GuidancePractices
DoProvide a visible label so users understand what they are selecting.
DoUse sections and dividers to organize options when the list exceeds ~8 items.
DoSet a meaningful placeholder that hints at the expected selection (e.g. "Choose a country" not "Select...").
Don'tUse for action menus — use Dropdown Menu for triggering commands or navigation.
Don'tUse when there are only two options — use a SegmentedControl or radio buttons instead.
Don'tUse Selector for navigation — links should be links, not dropdown options.
Don'tUse for yes/no or on/off choices — use Switch or CheckboxInput instead.
Don'tPut more than ~20 options without sections — consider Typeahead for large lists.

Anatomy

ElementDescription
LabelText label displayed above the selector.
PlaceholderHint text shown when no value is selected.
DescriptionHelper text providing additional context.
Left IconIcon displayed to the left of the selected value.
ValuerequiredThe currently selected item displayed in the selector.
ListrequiredThe dropdown list of selectable options.

Import

ts
import {XDSSelector} from '@xds/core/Selector'

Props

PropTypeDescription
labelrequired
stringLabel 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
stringCurrently selected value.
onChange
(value: string) => voidCallback 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
booleanDisables the selector.
isLabelHidden
booleanVisually hides the label while keeping it accessible.
description
stringHelper text displayed below the label.
isOptional
booleanMarks the field as optional.
isRequired
booleanMarks the field as required.
status
{type: 'error' | 'warning' | 'success', message?: string}Validation status with an optional message.
children
(item: XDSSelectorOptionData) => ReactNodeCustom render function for each item in the dropdown.
xstyle
StyleXStylesStyleX 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.
PropTypeDescription
labelrequired
stringLabel 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
stringCurrently selected value.
onChange
(value: string) => voidCallback 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
booleanDisables the selector.
isLabelHidden
booleanVisually hides the label while keeping it accessible.
description
stringHelper text displayed below the label.
isOptional
booleanMarks the field as optional.
isRequired
booleanMarks the field as required.
status
{type: 'error' | 'warning' | 'success', message?: string}Validation status with an optional message.
children
(item: XDSSelectorOptionData) => ReactNodeCustom render function for each item in the dropdown.
xstyle
StyleXStylesStyleX 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.
PropTypeDescription
labelrequired
ReactNodePrimary label text for the item.
icon
XDSIconTypeIcon displayed before the label. See `npx xds docs icons` for valid semantic names.
description
ReactNodeSecondary 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}>
<XDSSelector
label="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}>
<XDSSelector
label="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}>
<XDSSelector
label="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'}}
/>
<XDSSelector
label="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'}}
/>
<XDSSelector
label="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 (
<XDSSelector
label="Fruit"
isDefaultOpen
options={['Apple', 'Banana', 'Orange', 'Mango', 'Pineapple']}
placeholder="Select a fruit..."
onChange={() => {}}
/>
);
}