Default Composition
Select can take anything as a child, however, we strongly recommend that you use SelectOption. It has the same API as a ListCell, but with custom styles specific to usage within a Select. SelectOption also comes with a lot of baked in functionality, like keyboard navigation, accessibility properties, and focus behaviors.
function DefaultSelect() {
const [value, setValue] = useState();
const options = ['Option 1', 'Option 2', 'Option 3', 'Option 4', 'Option 5', 'Option 6'];
return (
<VStack padding={2}>
<OldSelect value={value} placeholder="Choose something..." onChange={setValue}>
{options.map((option) => (
<SelectOption value={option} key={option} title={option} description="Description" />
))}
</OldSelect>
</VStack>
);
}
Value/Label Object Model
Sometimes you may want to surface a label instead of the select value. You can pass a valueLabel prop with the currently selected value's corresponding label, which will appear to be the value of the Select.
function DefaultSelect() {
const [value, setValue] = useState();
const options = [
{ value: '1', label: 'Option 1' },
{ value: '2', label: 'Option 2' },
{ value: '3', label: 'Option 3' },
{ value: '4', label: 'Option 4' },
];
const selectedValueLabel = value && options.find((option) => option.value === value).label;
return (
<VStack padding={2}>
<OldSelect
value={value}
valueLabel={selectedValueLabel}
placeholder="Choose something..."
onChange={setValue}
>
{options.map((option) => (
<SelectOption
value={option.value}
key={option.value}
title={option.label}
description="Description"
/>
))}
</OldSelect>
</VStack>
);
}
The Select trigger can be customized similar to TextInput. These options are also available for mobile implementations.
Label and Helper Text
When space is tight, this brings the label inside of the Input. Should be used with a compact SelectOption.
function LabelHelperTextSelect() {
const [value, setValue] = useState('Option 2');
const options = ['Option 1', 'Option 2', 'Option 3', 'Option 4', 'Option 5', 'Option 6'];
return (
<VStack padding={2}>
<OldSelect
label="Make a selection"
helperText="You can only choose one"
value={value}
onChange={setValue}
startNode={<InputIcon name="calendar" />}
>
{options.map((option) => (
<SelectOption value={option} key={option} title={option} description="Description" />
))}
</OldSelect>
</VStack>
);
}
Compact
When space is tight, this brings the label inside of the Input. Should be used with a compact SelectOption.
function CompactSelect() {
const [value, setValue] = useState('Option 2');
const options = ['Option 1', 'Option 2', 'Option 3', 'Option 4', 'Option 5', 'Option 6'];
return (
<VStack padding={2}>
<OldSelect compact label="Make a selection" value={value} onChange={setValue}>
{options.map((option) => (
<SelectOption
value={option}
key={option}
compact
title={option}
description="Description"
/>
))}
</OldSelect>
</VStack>
);
}
Variants
Variants can be used to surface positive or negative feedback.
function Variant() {
const [value, setValue] = useState('Positive');
const options = ['Positive', 'Negative', 'Primary', 'Secondary', 'Foreground'];
return (
<VStack padding={2}>
<OldSelect
variant={value.toLowerCase()}
label="Make a selection"
helperText="You can only choose one"
value={value}
onChange={setValue}
>
{options.map((option) => (
<SelectOption value={option} key={option} title={option} />
))}
</OldSelect>
</VStack>
);
}
Label Variants
Select supports two label variants: outside (default) and inside. Note that the compact prop, when set to true, will override label variant preference.
WarningWhen using the inside label variant, you should always include a placeholder prop.
<VStack gap={3}>
<VStack>
<Text as="p">
<strong>Outside label (default):</strong>
</Text>
<OldSelect placeholder="Choose an option">
<SelectOption value="option1" title="Option 1" description="Description" />
<SelectOption value="option2" title="Option 2" description="Description" />
<SelectOption value="option3" title="Option 3" description="Description" />
</OldSelect>
</VStack>
<VStack>
<Text as="p">
<strong>Inside label:</strong>
</Text>
<OldSelect label="Choose Option" labelVariant="inside" placeholder="Select from list">
<SelectOption value="option1" title="Option 1" description="Description" />
<SelectOption value="option2" title="Option 2" description="Description" />
<SelectOption value="option3" title="Option 3" description="Description" />
</OldSelect>
</VStack>
<VStack>
<Text as="p">
<strong>Inside label (with start content):</strong>
</Text>
<OldSelect
label="Filter Options"
labelVariant="inside"
startNode={<InputIcon name="search" />}
placeholder="Search and select"
>
<SelectOption value="option1" title="Option 1" description="Description" />
<SelectOption value="option2" title="Option 2" description="Description" />
<SelectOption value="option3" title="Option 3" description="Description" />
</OldSelect>
</VStack>
</VStack>