Skip to content

Select

Single-select dropdown field.

function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function EmptySelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>(null);
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<EmptySelectStory {...args} />
function EmptySelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>(null);
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<EmptySelectStory {...args} />
function TriggerVariantsStory(args: React.ComponentProps<typeof Select>) {
const [ghostValue, setGhostValue] = useState<string | null>('ada');
const [buttonValue, setButtonValue] = useState<string | null>('grace');
return (
<VStack gap={2} width="full">
<Toolbar
dividers={['bottom']}
label="Ghost trigger example"
size="sm"
startContent={
<>
<Button icon={Filter} label="Filter" variant="ghost" />
<Select
{...args}
isLabelHidden
label="Assignee filter"
onChange={setGhostValue}
value={ghostValue}
variant="ghost"
/>
</>
}
/>
<Toolbar
dividers={['bottom']}
label="Button trigger example"
size="sm"
startContent={
<>
<Button icon={Filter} label="Filter" variant="secondary" />
<Select
{...args}
isLabelHidden
label="Assignee filter"
onChange={setButtonValue}
value={buttonValue}
variant="button"
/>
</>
}
/>
</VStack>
);
}
<TriggerVariantsStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<VStack gap={4}>
<SelectStory {...args} label="Check at end (default)" />
<SelectStory {...args} indicatorPosition="start" label="Check at start" />
</VStack>
function CustomOptionsStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return (
<Select
{...args}
hasSearch
onChange={setValue}
renderOption={option => (
<SelectOption
description={`${option.value}@example.com`}
icon={User}
label={option.label ?? option.value}
/>
)}
value={value}
/>
);
}
<CustomOptionsStory {...args} />
Selected payload: ada@example.com (Mathematician)
function AuxiliaryDataStory() {
const [value, setValue] = useState<string | null>('ada');
const [selectedData, setSelectedData] = useState<PersonAuxiliaryData | null>(
peopleOptionsWithAuxiliaryData[0]?.auxiliaryData ?? null,
);
return (
<VStack align="start" gap={2}>
<Select<PersonAuxiliaryData>
hasClear
label="Assignee"
onChange={(nextValue, option) => {
setValue(nextValue);
setSelectedData(option?.auxiliaryData ?? null);
}}
options={peopleOptionsWithAuxiliaryData}
renderOption={option => (
<SelectOption
description={option.auxiliaryData?.role}
label={option.label ?? option.value}
/>
)}
value={value}
/>
<Text color="secondary" type="supporting">
{selectedData == null
? 'No payload selected'
: `Selected payload: ${selectedData.email} (${selectedData.role})`}
</Text>
</VStack>
);
}
<AuxiliaryDataStory />
function OptionLabelTooltipsStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return (
<Select
{...args}
onChange={setValue}
renderOption={option => (
<SelectOption
label={option.label ?? option.value}
labelTooltip={`More information about ${option.label ?? option.value}`}
/>
)}
value={value}
/>
);
}
<OptionLabelTooltipsStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function EmptySelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>(null);
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<EmptySelectStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function SizesStory(args: React.ComponentProps<typeof Select>) {
const [small, setSmall] = useState<string | null>('ada');
const [medium, setMedium] = useState<string | null>('grace');
const [large, setLarge] = useState<string | null>('katherine');
return (
<div style={{display: 'grid', gap: 16}}>
<Select
{...args}
label="Small"
onChange={setSmall}
size="sm"
value={small}
/>
<Select {...args} label="Medium" onChange={setMedium} value={medium} />
<Select
{...args}
label="Large"
onChange={setLarge}
size="lg"
value={large}
/>
</div>
);
}
<SizesStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />
function EmptySelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>(null);
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<EmptySelectStory {...args} />
function EmptySelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>(null);
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<EmptySelectStory {...args} />
function SelectStory(args: React.ComponentProps<typeof Select>) {
const [value, setValue] = useState<string | null>('ada');
return <Select {...args} hasClear onChange={setValue} value={value} />;
}
<SelectStory {...args} />

Single-select dropdown field.

When isOptional: false, isRequired: false

PropTypeDefaultDescription
classNamestring—Additional CSS class names applied to the field root.
data-testidstring—Test ID applied to the combobox button.
descriptionReactNode—Supporting text displayed below the label.
emptyOptionsTextstring'No options'Text shown in the menu when there are no options at all.
emptySearchResultsTextstring'No results found'Text shown in the menu when the search query matches no options.
hasClearbooleanfalseWhether to show a clear button when a value is selected.
htmlNamestring—HTML name attribute for native form submission.
hasEntriesOnFocusbooleanfalseWhether focusing the trigger opens the option list. Pointer presses keep their ordinary click-to-toggle behaviour.
hasSearchbooleanfalseWhether to show search input in the dropdown.
indicatorPosition"start" | "end"'end'Which logical edge of each option shows the selected check. start reserves the check column on every option so labels stay aligned.
isDisabledbooleanfalseWhether the selector is disabled.
isLabelHiddenbooleanfalseWhether to visually hide the label.
isLoadingbooleanfalseWhether the selector is loading.
isReadOnlybooleanfalseWhether the value is displayed without allowing focus or interaction.
label*string—Field label.
labelEndReactNode—Content shown at the end of the label row, such as a link. It renders outside the label, so it does not focus the control or change its accessible name. It stays visible when isLabelHidden is true.
labelIconIconComponent—Icon shown before the label.
labelTooltipReactNode—Tooltip content shown next to the label.
onChange*( value: string | null, option: SelectOptionData<TAuxiliaryData> | null, ) => void—Called when selection changes. The selected option is provided as the second argument, or null when the selection is cleared.
options*ReadonlyArray<SelectOptionDefinition<TAuxiliaryData>>—Options to display.
placeholderstring'Select...'Placeholder shown when no option is selected.
refRef<HTMLButtonElement>—Ref forwarded to the combobox button.
renderOption(option: SelectOptionData<TAuxiliaryData>) => ReactNode—Custom render function for selectable options.
searchPlaceholderstring'Search...'Search input placeholder.
size"sm" | "md" | "lg"'md'Select size.
startIconIconComponent—Start icon rendered in the trigger.
statusInputStatus—Validation status displayed below the selector.
styleCSSProperties—Inline styles applied to the field root.
value*string | null—Selected option value.
variant"button" | "ghost" | "outline"'outline'Visual style of the selector trigger.
isOptionalfalse—
isRequiredfalse—

When isOptional: true, isRequired: false

PropTypeDefaultDescription
classNamestring—Additional CSS class names applied to the field root.
data-testidstring—Test ID applied to the combobox button.
descriptionReactNode—Supporting text displayed below the label.
emptyOptionsTextstring'No options'Text shown in the menu when there are no options at all.
emptySearchResultsTextstring'No results found'Text shown in the menu when the search query matches no options.
hasClearbooleanfalseWhether to show a clear button when a value is selected.
htmlNamestring—HTML name attribute for native form submission.
hasEntriesOnFocusbooleanfalseWhether focusing the trigger opens the option list. Pointer presses keep their ordinary click-to-toggle behaviour.
hasSearchbooleanfalseWhether to show search input in the dropdown.
indicatorPosition"start" | "end"'end'Which logical edge of each option shows the selected check. start reserves the check column on every option so labels stay aligned.
isDisabledbooleanfalseWhether the selector is disabled.
isLabelHiddenbooleanfalseWhether to visually hide the label.
isLoadingbooleanfalseWhether the selector is loading.
isReadOnlybooleanfalseWhether the value is displayed without allowing focus or interaction.
label*string—Field label.
labelEndReactNode—Content shown at the end of the label row, such as a link. It renders outside the label, so it does not focus the control or change its accessible name. It stays visible when isLabelHidden is true.
labelIconIconComponent—Icon shown before the label.
labelTooltipReactNode—Tooltip content shown next to the label.
onChange*( value: string | null, option: SelectOptionData<TAuxiliaryData> | null, ) => void—Called when selection changes. The selected option is provided as the second argument, or null when the selection is cleared.
options*ReadonlyArray<SelectOptionDefinition<TAuxiliaryData>>—Options to display.
placeholderstring'Select...'Placeholder shown when no option is selected.
refRef<HTMLButtonElement>—Ref forwarded to the combobox button.
renderOption(option: SelectOptionData<TAuxiliaryData>) => ReactNode—Custom render function for selectable options.
searchPlaceholderstring'Search...'Search input placeholder.
size"sm" | "md" | "lg"'md'Select size.
startIconIconComponent—Start icon rendered in the trigger.
statusInputStatus—Validation status displayed below the selector.
styleCSSProperties—Inline styles applied to the field root.
value*string | null—Selected option value.
variant"button" | "ghost" | "outline"'outline'Visual style of the selector trigger.
isOptional*true—
isRequiredfalse—

When isOptional: false, isRequired: true

PropTypeDefaultDescription
classNamestring—Additional CSS class names applied to the field root.
data-testidstring—Test ID applied to the combobox button.
descriptionReactNode—Supporting text displayed below the label.
emptyOptionsTextstring'No options'Text shown in the menu when there are no options at all.
emptySearchResultsTextstring'No results found'Text shown in the menu when the search query matches no options.
hasClearbooleanfalseWhether to show a clear button when a value is selected.
htmlNamestring—HTML name attribute for native form submission.
hasEntriesOnFocusbooleanfalseWhether focusing the trigger opens the option list. Pointer presses keep their ordinary click-to-toggle behaviour.
hasSearchbooleanfalseWhether to show search input in the dropdown.
indicatorPosition"start" | "end"'end'Which logical edge of each option shows the selected check. start reserves the check column on every option so labels stay aligned.
isDisabledbooleanfalseWhether the selector is disabled.
isLabelHiddenbooleanfalseWhether to visually hide the label.
isLoadingbooleanfalseWhether the selector is loading.
isReadOnlybooleanfalseWhether the value is displayed without allowing focus or interaction.
label*string—Field label.
labelEndReactNode—Content shown at the end of the label row, such as a link. It renders outside the label, so it does not focus the control or change its accessible name. It stays visible when isLabelHidden is true.
labelIconIconComponent—Icon shown before the label.
labelTooltipReactNode—Tooltip content shown next to the label.
onChange*( value: string | null, option: SelectOptionData<TAuxiliaryData> | null, ) => void—Called when selection changes. The selected option is provided as the second argument, or null when the selection is cleared.
options*ReadonlyArray<SelectOptionDefinition<TAuxiliaryData>>—Options to display.
placeholderstring'Select...'Placeholder shown when no option is selected.
refRef<HTMLButtonElement>—Ref forwarded to the combobox button.
renderOption(option: SelectOptionData<TAuxiliaryData>) => ReactNode—Custom render function for selectable options.
searchPlaceholderstring'Search...'Search input placeholder.
size"sm" | "md" | "lg"'md'Select size.
startIconIconComponent—Start icon rendered in the trigger.
statusInputStatus—Validation status displayed below the selector.
styleCSSProperties—Inline styles applied to the field root.
value*string | null—Selected option value.
variant"button" | "ghost" | "outline"'outline'Visual style of the selector trigger.
isOptionalfalse—
isRequired*true—

Helper layout for custom Select option rendering.

PropTypeDefaultDescription
classNamestring—Additional CSS class names applied to the option layout.
data-testidstring—Test ID applied to the option layout.
descriptionReactNode—Supporting text displayed below the label.
endContentReactNode—Trailing content.
iconIconComponent—Icon displayed before the label.
label*ReactNode—Primary label.
labelTooltipReactNode—Tooltip content shown next to the label.
refRef<HTMLSpanElement>—Ref forwarded to the layout root.
styleCSSProperties—Inline styles applied to the layout root.