Select

Displays a list of options for the user to pick from, triggered by a button.

Anatomy

Import and assemble the component:

1import { Select } from "@raystack/apsara";
2
3<Select>
4 <Select.Label />
5 <Select.Trigger>
6 <Select.Value />
7 </Select.Trigger>
8 <Select.Content>
9 <Select.Status />
10 <Select.Empty />
11 <Select.Group>
12 <Select.GroupLabel />
13 <Select.Item />
14 </Select.Group>
15 <Select.Separator />
16 </Select.Content>
17</Select>

Usage

Appearance first, meaning size and variant, then how many items can be chosen, and who owns the value.

Basic Select

A trigger and a list of items. Select.Value renders the current selection in the trigger. A check mark shows the selected item in the list. In multiple mode, each item has a checkbox instead.

Each Select.Item registers its label and icon, so Select.Value shows them for the selected value, even before the list first opens. You can also pass items to the root, as { value, label }[] or a value-to-label record. Use it for search by label, or for values whose item is not rendered.

1<Select>
2 <Select.Trigger aria-label="Fruit selection">
3 <Select.Value placeholder="Select a fruit" />
4 </Select.Trigger>
5 <Select.Content>
6 <Select.Item value="apple">Apple</Select.Item>
7 <Select.Item value="banana">Banana</Select.Item>
8 </Select.Content>
9</Select>

Icon

Pass leadingIcon to Select.Item to show an icon before the item text.

1<Select>
2 <Select.Trigger aria-label="Fruit selection">
3 <Select.Value placeholder="Select a fruit" />
4 </Select.Trigger>
5 <Select.Content>
6 <Select.Item value="apple" leadingIcon={<Info size={16} />}>
7 Apple
8 </Select.Item>
9 <Select.Item value="banana" leadingIcon={<X size={16} />}>
10 Banana
11 </Select.Item>
12 <Select.Item value="grape" leadingIcon={<Home size={16} />}>
13 Grape
14 </Select.Item>

The trigger shows the selected item's icon too. To render the value yourself, pass a function as the child of Select.Value. It receives the selected item as { value, children, leadingIcon }, or an array of items in multiple mode.

1<Select defaultValue="apple">
2 <Select.Trigger>
3 <Select.Value placeholder="Select a fruit">
4 {(item) => (
5 <Flex align="center" gap={2}>
6 {item.leadingIcon}
7 <Text weight="medium">{item.children}</Text>
8 </Flex>
9 )}
10 </Select.Value>
11 </Select.Trigger>
12 <Select.Content>
13 <Select.Item value="apple" leadingIcon={<Info size={16} />}>
14 Apple

Label

Select.Label renders a visible label linked to the trigger. Clicking it focuses the trigger.

1<Flex direction="column" gap={2}>
2 <Select>
3 <Select.Label>Fruit</Select.Label>
4 <Select.Trigger>
5 <Select.Value placeholder="Select a fruit" />
6 </Select.Trigger>
7 <Select.Content>
8 <Select.Item value="apple">Apple</Select.Item>
9 <Select.Item value="banana">Banana</Select.Item>
10 </Select.Content>
11 </Select>
12</Flex>

Size

Two sizes. medium is the default; small fits toolbars and table filters.

1<Flex align="center" gap={9}>
2 <Select>
3 <Select.Trigger size="small">
4 <Select.Value placeholder="Small select" />
5 </Select.Trigger>
6 <Select.Content>
7 <Select.Item value="1">Option 1</Select.Item>
8 <Select.Item value="2">Option 2</Select.Item>
9 </Select.Content>
10 </Select>
11 <Select>
12 <Select.Trigger>
13 <Select.Value placeholder="Medium select" />
14 </Select.Trigger>

Variant

outline (the default) draws a bordered control. text removes the border for use inside a toolbar or beside other text.

1<Select>
2 <Select.Trigger>
3 <Select.Value placeholder="Select..." />
4 </Select.Trigger>
5 <Select.Content>
6 <Select.Item value="all">All</Select.Item>
7 <Select.Item value="active">Active</Select.Item>
8 <Select.Item value="inactive">Inactive</Select.Item>
9 </Select.Content>
10</Select>

With Separator

Select.Separator draws a rule between groups of items.

1<Select>
2 <Select.Trigger>
3 <Select.Value placeholder="Select..." />
4 </Select.Trigger>
5 <Select.Content>
6 <Select.Group>
7 <Select.Item value="1">Option 1</Select.Item>
8 <Select.Item value="2">Option 2</Select.Item>
9 </Select.Group>
10 <Select.Separator />
11 <Select.Group>
12 <Select.Item value="3">Option 3</Select.Item>
13 <Select.Item value="4">Option 4</Select.Item>
14 </Select.Group>

Multiple selection

To enable multiple selection, pass the multiple prop to the Select root element.

When multiple selection is enabled, the value, onValueChange, and defaultValue will be an array of strings.

1<Select multiple>
2 <Select.Trigger>
3 <Select.Value placeholder="Select..." />
4 </Select.Trigger>
5 <Select.Content>
6 <Select.Item value="1">Option 1</Select.Item>
7 <Select.Item value="2">Option 2</Select.Item>
8 <Select.Item value="3">Option 3</Select.Item>
9 <Select.Item value="4">Option 4</Select.Item>
10 <Select.Item value="5">Option 5</Select.Item>
11 <Select.Item value="6">Option 6</Select.Item>
12 <Select.Item value="7">Option 7</Select.Item>
13 <Select.Item value="8">Option 8</Select.Item>
14 <Select.Item value="9">Option 9</Select.Item>

Autocomplete

To enable autocomplete, pass the autocomplete prop to the Select root element.

With items, Base UI filters by label. Without items, the select filters items with a simple text match. For full control, set autocompleteMode="manual" and filter the items yourself.

Select.Empty shows its content only when no item matches the search. It needs items on the root. Select.Status is a polite live region for messages such as a result count or a loading state. Both work only in autocomplete mode.

1<Select
2 autocomplete
3 items={{
4 apple: "Apple",
5 banana: "Banana",
6 blueberry: "Blueberry",
7 grapes: "Grapes",
8 pineapple: "Pineapple",
9 }}
10>
11 <Select.Trigger>
12 <Select.Value placeholder="Select a fruit" />
13 </Select.Trigger>
14 <Select.Content>

Controlled

Pass value with onValueChange to own the selection. Do this when the value comes from a form, a URL, or another control on the page.

1(function ControlledSelect() {
2 const [fruit, setFruit] = React.useState("apple");
3
4 return (
5 <Flex direction="column" gap={5}>
6 <Select value={fruit} onValueChange={setFruit}>
7 <Select.Trigger width={200}>
8 <Select.Value />
9 </Select.Trigger>
10 <Select.Content>
11 <Select.Item value="apple">Apple</Select.Item>
12 <Select.Item value="banana">Banana</Select.Item>
13 <Select.Item value="grapes">Grapes</Select.Item>
14 </Select.Content>

API Reference

The trigger, and the parts of the list it opens.

Root

The Select component is composed of several parts, each with their own props.

The root element is the parent component that holds the select. Using the autocomplete prop, you can enable autocomplete functionality.

Prop

Type

Trigger

The button that triggers the Select.

Prop

Type

Content

The container that holds the Select items.

Prop

Type

Set alignItemWithTrigger to open the list over the trigger, with the selected item lined up on the trigger's value. Base UI turns it off for touch input and when there is not enough space, and then places the list the normal way. side and align only apply when the list is placed the normal way.

Item

Individual clickable options within the Select.

Prop

Type

Group

A way to group related Select items together.

Prop

Type

Value

Shows the label of the selected value, or the placeholder.

Prop

Type

Label

A visible label linked to the trigger.

Prop

Type

GroupLabel

The label of a Select.Group. Use it only inside Select.Group.

Prop

Type

Empty

Shows its content when no item matches the search. Autocomplete mode only.

Prop

Type

Status

A polite live region for status messages. Autocomplete mode only.

Prop

Type

Separator

Visual divider between Select items or groups.

Prop

Type

Slots

Every rendered part carries a stable data-slot attribute for styling and testing:

SlotElement
select-triggerThe trigger button that opens the menu
select-trigger-contentFlex wrapper around the trigger's children
select-trigger-iconThe chevron dropdown icon in the trigger
select-labelThe label linked to the trigger
select-valueThe <span> showing the selected label or placeholder
select-value-contentWrapper around the chips in multiple mode
select-value-overflowThe "+N" overflow count for multiple values (when they don't all fit)
select-positionerThe floating positioner for the popup
select-contentThe popup container
select-searchThe search input (when autocomplete is enabled)
select-listThe scrollable list of items
select-groupA group of items
select-group-labelThe label of a group
select-emptyThe message shown when no item matches (autocomplete only)
select-statusThe live region for status messages (autocomplete only)
select-separatorA divider between items or groups
select-itemAn individual option row
select-item-iconLeading icon on an item (when set)
select-item-textThe text label of an item
select-item-indicatorThe check mark on the selected item (single selection only)

Accessibility

The Select component follows WAI-ARIA guidelines:

  • Trigger has role combobox
  • Content has role listbox
  • Items have role option
  • ARIA labels and descriptions