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 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 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
classNamestringAdditional CSS class names applied to the field root.
data-testidstringTest ID applied to the combobox button.
descriptionReactNodeSupporting text displayed below the label.
hasClearbooleanfalseWhether to show a clear button when a value is selected.
htmlNamestringHTML 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.
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*stringField label.
labelIconIconComponentIcon shown before the label.
labelTooltipReactNodeTooltip content shown next to the label.
onChange*( value: string | null, option: SelectOptionData<TAuxiliaryData> | null, ) => voidCalled 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>) => ReactNodeCustom render function for selectable options.
searchPlaceholderstring'Search...'Search input placeholder.
size"sm" | "md" | "lg"'md'Select size.
startIconIconComponentStart icon rendered in the trigger.
statusInputStatusValidation status displayed below the selector.
styleCSSPropertiesInline styles applied to the field root.
value*string | nullSelected option value.
variant"button" | "ghost" | "outline"'outline'Visual style of the selector trigger.
isOptionalfalse
isRequiredfalse

When isOptional: true, isRequired: false

PropTypeDefaultDescription
classNamestringAdditional CSS class names applied to the field root.
data-testidstringTest ID applied to the combobox button.
descriptionReactNodeSupporting text displayed below the label.
hasClearbooleanfalseWhether to show a clear button when a value is selected.
htmlNamestringHTML 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.
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*stringField label.
labelIconIconComponentIcon shown before the label.
labelTooltipReactNodeTooltip content shown next to the label.
onChange*( value: string | null, option: SelectOptionData<TAuxiliaryData> | null, ) => voidCalled 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>) => ReactNodeCustom render function for selectable options.
searchPlaceholderstring'Search...'Search input placeholder.
size"sm" | "md" | "lg"'md'Select size.
startIconIconComponentStart icon rendered in the trigger.
statusInputStatusValidation status displayed below the selector.
styleCSSPropertiesInline styles applied to the field root.
value*string | nullSelected option value.
variant"button" | "ghost" | "outline"'outline'Visual style of the selector trigger.
isOptional*true
isRequiredfalse

When isOptional: false, isRequired: true

PropTypeDefaultDescription
classNamestringAdditional CSS class names applied to the field root.
data-testidstringTest ID applied to the combobox button.
descriptionReactNodeSupporting text displayed below the label.
hasClearbooleanfalseWhether to show a clear button when a value is selected.
htmlNamestringHTML 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.
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*stringField label.
labelIconIconComponentIcon shown before the label.
labelTooltipReactNodeTooltip content shown next to the label.
onChange*( value: string | null, option: SelectOptionData<TAuxiliaryData> | null, ) => voidCalled 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>) => ReactNodeCustom render function for selectable options.
searchPlaceholderstring'Search...'Search input placeholder.
size"sm" | "md" | "lg"'md'Select size.
startIconIconComponentStart icon rendered in the trigger.
statusInputStatusValidation status displayed below the selector.
styleCSSPropertiesInline styles applied to the field root.
value*string | nullSelected option value.
variant"button" | "ghost" | "outline"'outline'Visual style of the selector trigger.
isOptionalfalse
isRequired*true

Helper layout for custom Select option rendering.

PropTypeDefaultDescription
classNamestringAdditional CSS class names applied to the option layout.
data-testidstringTest ID applied to the option layout.
descriptionReactNodeSupporting text displayed below the label.
endContentReactNodeTrailing content.
iconIconComponentIcon displayed before the label.
label*ReactNodePrimary label.
labelTooltipReactNodeTooltip content shown next to the label.
refRef<HTMLSpanElement>Ref forwarded to the layout root.
styleCSSPropertiesInline styles applied to the layout root.