Select
A dropdown control for selecting one or more options from a list. Supports keyboard navigation, typeahead, groups, and floating positioning.
Anatomy
<Select.Provider bind:value>
<Select.Trigger>
<Select.Value placeholder="Choose..." />
</Select.Trigger>
<Select.Content>
<Select.Viewport>
<Select.Item value="a">Option A</Select.Item>
<Select.Item value="b">Option B</Select.Item>
<Select.Group>
<Select.GroupHeading>Category</Select.GroupHeading>
<Select.Item value="c">Option C</Select.Item>
</Select.Group>
</Select.Viewport>
<Select.Arrow />
</Select.Content>
</Select.Provider>
Parts
| Part |
Element |
Description |
Provider |
none |
Root context. Manages value, open state, highlighted item. |
Trigger |
<button> |
Opens the dropdown on click or keyboard. |
Value |
<div> |
Displays the selected value or placeholder. |
Content |
<div> |
Floating listbox container with dismissal and scroll lock. |
Viewport |
<div> |
Scrollable area inside Content. |
Item |
<div> |
Selectable option. |
Group |
<div> |
Groups related items with an optional heading. |
GroupHeading |
<div> |
Label for a group, linked via aria-labelledby. |
Separator |
<div> |
Visual separator between items or groups. |
Arrow |
<div> |
Floating arrow pointing toward the trigger. |
ARIA
| Part |
Attribute |
Value |
| Trigger |
role |
combobox |
| Trigger |
aria-haspopup |
listbox |
| Trigger |
aria-expanded |
true | false |
| Trigger |
aria-controls |
ID of Content |
| Trigger |
aria-activedescendant |
ID of highlighted Item |
| Trigger |
aria-required |
true (when required) |
| Content |
role |
listbox |
| Content |
aria-multiselectable |
true (when type='multiple') |
| Item |
role |
option |
| Item |
aria-selected |
true | false |
| Group |
role |
group |
| Group |
aria-labelledby |
ID of GroupHeading |
| Separator |
role |
separator |
Data Attributes
| Part |
Attribute |
Values |
| Trigger |
data-select-trigger |
Always present |
| Trigger |
data-state |
open | closed |
| Trigger |
data-disabled |
Present when disabled |
| Trigger |
data-placeholder |
Present when no value selected |
| Value |
data-select-value |
Always present |
| Value |
data-placeholder |
Present when no value selected |
| Content |
data-select-content |
Always present |
| Content |
data-state |
open | closed |
| Content |
data-side |
top | right | bottom | left |
| Content |
data-align |
start | center | end |
| Content |
data-starting-style |
Present during open animation |
| Content |
data-ending-style |
Present during close animation |
| Item |
data-select-item |
Always present |
| Item |
data-state |
checked | unchecked |
| Item |
data-disabled |
Present when disabled |
| Item |
data-value |
The item's value string |
| Item |
data-label |
The item's label text |
Keyboard
On Trigger
| Key |
Action |
ArrowDown / ArrowUp |
Open the dropdown |
Enter / Space |
Toggle the dropdown |
On Content (when open)
| Key |
Action |
ArrowDown |
Move highlight to next item |
ArrowUp |
Move highlight to previous item |
Home |
Move highlight to first item |
End |
Move highlight to last item |
Enter / Space |
Select highlighted item |
Tab |
Close the dropdown |
Escape |
Close the dropdown |
| Character keys |
Typeahead — jump to matching item |
Usage
Basic
<script>
import { Select } from '$soma/components';
let value = $state('');
</script>
<Select.Provider bind:value>
<Select.Trigger>
<Select.Value placeholder="Select a fruit..." />
</Select.Trigger>
<Select.Content>
<Select.Viewport>
<Select.Item value="apple">Apple</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="cherry">Cherry</Select.Item>
</Select.Viewport>
</Select.Content>
</Select.Provider>
Grouped options
<Select.Viewport>
<Select.Group>
<Select.GroupHeading>Fruits</Select.GroupHeading>
<Select.Item value="apple">Apple</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
</Select.Group>
<Select.Separator />
<Select.Group>
<Select.GroupHeading>Vegetables</Select.GroupHeading>
<Select.Item value="carrot">Carrot</Select.Item>
</Select.Group>
</Select.Viewport>
Disabled item
<Select.Item value="premium" disabled>Premium (locked)</Select.Item>
Multiple selection
<Select.Provider bind:value type="multiple">
<!-- Multiple items can be selected -->
</Select.Provider>