Select
A trigger that opens a list of options to pick a single value from.
Usage
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@epilot/spark-ui/select'<Select items={items}>
<SelectTrigger>
<SelectValue placeholder="Pick one" />
</SelectTrigger>
<SelectContent>
<SelectItem value="a">Option A</SelectItem>
</SelectContent>
</Select>SelectValue renders the raw value by default. Pass items (a { value, label }
list) on the root, or a children formatter, so it shows a label instead.
Examples
Groups
Wrap related options in SelectGroup with a SelectLabel, and split sections
with SelectSeparator. Mark unavailable options disabled.
Input styles
The trigger is themed as an input box: it reads data-input-style
(soft / surface / outlined / ghost) and data-input-color
(brand / gray) from the enclosing <Field> or <Theme>, so a Select and an
Input look identical in the same form. Override per instance with variant.
With a label
Compose inside <Field> to get a label with the same positions as any field:
outset (above), inset (inside the shell).
The trigger picks up the field's id, inputStyle, and aria-describedby, and
goes bare in inset so the shell carries the box.
Hidden label
Pass srOnly to FieldLabel to hide it visually while keeping it in the
accessibility tree; it still names and focuses the control. Prefer this over
dropping the label when the surrounding UI already makes the purpose obvious.
Disabled
Set disabled on the root to disable the whole control.
Clearing a selection
Base UI ships no Select.Clear, so SelectClear is a plain button that sits
beside the trigger inside SelectTriggerGroup rather than nesting inside it.
The group hides the clear button while the trigger shows its placeholder, is
disabled, or is read-only. Select must be controlled (value +
onValueChange) so the app can reset the value itself. Clicking or activating
the clear button returns keyboard focus to the trigger.
multiple works the same way; clear to an empty array.
API Reference
Built on Base UI Select. See the
Base UI docs for the full API (value, defaultValue, items, multiple,
onValueChange, …). Spark notes:
SelectTriggeris themed as an input box aligned withInput: resolvesinputStyle/inputColorfrom the enclosingField/Theme(shared box recipes), with avariantprop ("soft" | "surface" | "outlined" | "ghost") to override;size:"sm" | "default"; follows theradiusknob; picks up theFieldid+aria-describedbywhen inside one.SelectContentrenders its own portal; drops below the trigger like a popover by default, matching its width. SetalignItemWithTriggerto overlay the menu on the trigger (aligning the selected item over it) instead; height-capped and scrollable. Passcontainerto mount the portal into a different document/element thandocument.body— an embedded preview iframe, say.SelectValue: passitemson the root or achildrenformatter to render a label rather than the raw value.SelectTriggerGroupwrapsSelectTriggerandSelectClearas siblings and hides the clear button while the trigger is a placeholder, disabled, or read-only.className="w-full"makes it span aFieldthe same way the trigger does on its own.SelectClearis a plain<button>that resets keyboard focus to the trigger after youronClickruns — wireonClickto reset your controlledvalue(null, or[]formultiple). Passaria-label; the default icon is decorative.
Accessibility
- The trigger is a native
<button>withrole="combobox". Arrow keys move the highlight in the popup, Enter/Space chooses the highlighted option, Escape closes it. - Name the trigger with a
FieldLabeloraria-label. SelectClearneeds its ownaria-label— the same rule asAutocompleteClear.