Select
Single-select dropdown field.
Examples
Section titled “Examples”Default
Section titled “Default”Clear Assignee
function SelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>('ada'); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<SelectStory {...args} />Searchable
Section titled “Searchable”Clear Assignee
function SelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>('ada'); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<SelectStory {...args} />Entries On Focus
Section titled “Entries On Focus”function EmptySelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>(null); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<EmptySelectStory {...args} />Trigger Variants
Section titled “Trigger Variants”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} />Custom Options
Section titled “Custom Options”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} />Auxiliary Data
Section titled “Auxiliary Data”Clear Assignee
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 />Option Label Tooltips
Section titled “Option Label Tooltips”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} />Disabled
Section titled “Disabled”function SelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>('ada'); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<SelectStory {...args} />Loading
Section titled “Loading”Clear Assignee
function SelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>('ada'); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<SelectStory {...args} />Many Options
Section titled “Many Options”function EmptySelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>(null); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<EmptySelectStory {...args} />Sections And Dividers
Section titled “Sections And Dividers”Clear Assignee
function SelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>('ada'); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<SelectStory {...args} />Validation Status
Section titled “Validation Status”Clear Assignee
Choose an assignee before continuing.
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} />With Start Icon
Section titled “With Start Icon”Clear Assignee
function SelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>('ada'); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<SelectStory {...args} />Hidden Label
Section titled “Hidden Label”Clear Assignee
function SelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>('ada'); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<SelectStory {...args} />Custom Placeholder
Section titled “Custom Placeholder”function EmptySelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>(null); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<EmptySelectStory {...args} />Disabled Options
Section titled “Disabled Options”function EmptySelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>(null); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<EmptySelectStory {...args} />Read Only
Section titled “Read Only”function SelectStory(args: React.ComponentProps<typeof Select>) { const [value, setValue] = useState<string | null>('ada'); return <Select {...args} hasClear onChange={setValue} value={value} />;}
<SelectStory {...args} />Select
Section titled “Select”Single-select dropdown field.
When isOptional: false, isRequired: false
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the field root. |
data-testid | string | — | Test ID applied to the combobox button. |
description | ReactNode | — | Supporting text displayed below the label. |
hasClear | boolean | false | Whether to show a clear button when a value is selected. |
htmlName | string | — | HTML name attribute for native form submission. |
hasEntriesOnFocus | boolean | false | Whether focusing the trigger opens the option list. Pointer presses keep their ordinary click-to-toggle behaviour. |
hasSearch | boolean | false | Whether to show search input in the dropdown. |
isDisabled | boolean | false | Whether the selector is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
isLoading | boolean | false | Whether the selector is loading. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
label* | string | — | Field label. |
labelIcon | IconComponent | — | Icon shown before the label. |
labelTooltip | ReactNode | — | 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. |
placeholder | string | 'Select...' | Placeholder shown when no option is selected. |
ref | Ref<HTMLButtonElement> | — | Ref forwarded to the combobox button. |
renderOption | (option: SelectOptionData<TAuxiliaryData>) => ReactNode | — | Custom render function for selectable options. |
searchPlaceholder | string | 'Search...' | Search input placeholder. |
size | "sm" | "md" | "lg" | 'md' | Select size. |
startIcon | IconComponent | — | Start icon rendered in the trigger. |
status | InputStatus | — | Validation status displayed below the selector. |
style | CSSProperties | — | 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 | false | — | |
isRequired | false | — |
When isOptional: true, isRequired: false
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the field root. |
data-testid | string | — | Test ID applied to the combobox button. |
description | ReactNode | — | Supporting text displayed below the label. |
hasClear | boolean | false | Whether to show a clear button when a value is selected. |
htmlName | string | — | HTML name attribute for native form submission. |
hasEntriesOnFocus | boolean | false | Whether focusing the trigger opens the option list. Pointer presses keep their ordinary click-to-toggle behaviour. |
hasSearch | boolean | false | Whether to show search input in the dropdown. |
isDisabled | boolean | false | Whether the selector is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
isLoading | boolean | false | Whether the selector is loading. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
label* | string | — | Field label. |
labelIcon | IconComponent | — | Icon shown before the label. |
labelTooltip | ReactNode | — | 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. |
placeholder | string | 'Select...' | Placeholder shown when no option is selected. |
ref | Ref<HTMLButtonElement> | — | Ref forwarded to the combobox button. |
renderOption | (option: SelectOptionData<TAuxiliaryData>) => ReactNode | — | Custom render function for selectable options. |
searchPlaceholder | string | 'Search...' | Search input placeholder. |
size | "sm" | "md" | "lg" | 'md' | Select size. |
startIcon | IconComponent | — | Start icon rendered in the trigger. |
status | InputStatus | — | Validation status displayed below the selector. |
style | CSSProperties | — | 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 | — | |
isRequired | false | — |
When isOptional: false, isRequired: true
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the field root. |
data-testid | string | — | Test ID applied to the combobox button. |
description | ReactNode | — | Supporting text displayed below the label. |
hasClear | boolean | false | Whether to show a clear button when a value is selected. |
htmlName | string | — | HTML name attribute for native form submission. |
hasEntriesOnFocus | boolean | false | Whether focusing the trigger opens the option list. Pointer presses keep their ordinary click-to-toggle behaviour. |
hasSearch | boolean | false | Whether to show search input in the dropdown. |
isDisabled | boolean | false | Whether the selector is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
isLoading | boolean | false | Whether the selector is loading. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
label* | string | — | Field label. |
labelIcon | IconComponent | — | Icon shown before the label. |
labelTooltip | ReactNode | — | 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. |
placeholder | string | 'Select...' | Placeholder shown when no option is selected. |
ref | Ref<HTMLButtonElement> | — | Ref forwarded to the combobox button. |
renderOption | (option: SelectOptionData<TAuxiliaryData>) => ReactNode | — | Custom render function for selectable options. |
searchPlaceholder | string | 'Search...' | Search input placeholder. |
size | "sm" | "md" | "lg" | 'md' | Select size. |
startIcon | IconComponent | — | Start icon rendered in the trigger. |
status | InputStatus | — | Validation status displayed below the selector. |
style | CSSProperties | — | 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 | false | — | |
isRequired* | true | — |
SelectOption
Section titled “SelectOption”Helper layout for custom Select option rendering.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the option layout. |
data-testid | string | — | Test ID applied to the option layout. |
description | ReactNode | — | Supporting text displayed below the label. |
endContent | ReactNode | — | Trailing content. |
icon | IconComponent | — | Icon displayed before the label. |
label* | ReactNode | — | Primary label. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
ref | Ref<HTMLSpanElement> | — | Ref forwarded to the layout root. |
style | CSSProperties | — | Inline styles applied to the layout root. |