Select
Selected options use OPERATOR's Check icon, matching ComboBox and other selection controls.
The trigger is as tall as an Input for one line; a long value or placeholder wraps and the trigger grows taller, and long identifiers break anywhere. The list is at least as wide as the trigger, wraps at about 30rem, keeps 16px from the screen edges, and its options wrap.
Default
Sizes
Disabled
A disabled Select keeps its value readable: dim text on a muted fill, with the control outline, and no fade.
Inside a Field
Inside a Field the trigger fills the Field's width, like the other text controls; outside a Field it keeps the width of its text (a width class still wins). A required Field makes the Select required: its description says "Required" to a screen reader, and the browser stops a native submission while nothing is chosen.
REQUIRED
No options
A Select with nothing to choose from still opens, with a non-interactive "No options
available." row; emptyMessage changes the words.
The selected value
Keep the selected option among the children. A value with no matching option shows the
placeholder and submits nothing.
Motion
The popup arrives from its trigger in 200ms and exits in 150ms, with a small directional movement and scale. The chevron rotates up while open and returns down on close using the same timing. Selection and callbacks update immediately. Keyboard navigation, Escape, assistive activation, and system reduced motion stay instant. Use motion="none" to disable the treatment.
Props
| PROP | TYPE | DEFAULT | REQUIRED |
|---|---|---|---|
motionTactile pointer arrival, exit, and open-state chevron rotation; keyboard, assistive activation, and system reduced motion remain immediate. | enumauto | none | "auto" | no |
valueControlled selected option value. Keep the selected option among the children; a value with no matching option shows the placeholder and submits nothing. | string | — | no |
defaultValueInitial selected option value. | string | — | no |
onValueChange(value: string) => void. Called when the operator chooses an option. | function | — | no |
openControlled open state of the list. | boolean | — | no |
defaultOpenInitial open state. | boolean | false | no |
onOpenChange(open: boolean) => void. Called when the list opens or closes. | function | — | no |
placeholder | string | — | no |
emptyMessageWhat the list says when there are no options to choose from. | string | "No options available." | no |
aria-labelAccessible name when there is no surrounding Field or visible heading. | string | — | no |
aria-labelledbyIDs of visible elements that name the Select; wins over a Field's label. | string | — | no |
aria-describedbyDescription IDs; replaces a surrounding Field's help or error. | string | — | no |
disabled | boolean | false | no |
required | boolean | false | no |
name | string | — | no |
size | enumsm | md | lg | "md" | no |
invalid | boolean | false | no |
| PROP | TYPE | DEFAULT | REQUIRED |
|---|---|---|---|
value | string | — | yes |
disabled | boolean | false | no |
Accessibility
- Button trigger linked to a listbox; supports type-ahead.
- Enter/Space opens; Arrow keys navigate; Escape closes.
- Inherits
id,aria-describedby,aria-invalid, andrequiredfrom Field. Outside a Field,aria-labelledbynames it by a visible heading andaria-describedbydescribes it; both win over a Field's. - A required Select (its own
required, or a required Field's) is described as "Required" by a visually hidden word at the start of its description, kept whenaria-describedbyreplaces the Field's help: the trigger is a button, which cannot carryaria-required. - A checkmark identifies selection alongside color.
- The trigger outline is the control outline (
--oprt-border-control, 3:1 or more). - In forced-colors (high contrast) mode, keyboard focus draws a 2px outline in the system text color around the trigger, and the option about to be chosen is drawn in the system highlight color.
Manifest entry
<Field label="THEATER">
<Select placeholder="CHOOSE...">
<SelectOption value="indo-pacific">INDO-PACIFIC</SelectOption>
<SelectOption value="european">EUROPEAN</SelectOption>
</Select>
</Field>View agent manifest
{
"description": "Single-select dropdown. Trigger matches Input geometry for one line and grows when its text wraps; inside a Field it fills the Field's width. Portal'd list with an accent border and the shared OPERATOR Check icon on the selected option; an empty Select opens a list that says so.",
"props": {
"motion": {
"type": "enum",
"values": [
"auto",
"none"
],
"default": "auto",
"description": "Tactile pointer arrival, exit, and open-state chevron rotation; keyboard, assistive activation, and system reduced motion remain immediate."
},
"value": {
"type": "string",
"description": "Controlled selected option value. Keep the selected option among the children; a value with no matching option shows the placeholder and submits nothing."
},
"defaultValue": {
"type": "string",
"description": "Initial selected option value."
},
"onValueChange": {
"type": "function",
"description": "(value: string) => void. Called when the operator chooses an option."
},
"open": {
"type": "boolean",
"description": "Controlled open state of the list."
},
"defaultOpen": {
"type": "boolean",
"default": false,
"description": "Initial open state."
},
"onOpenChange": {
"type": "function",
"description": "(open: boolean) => void. Called when the list opens or closes."
},
"placeholder": {
"type": "string"
},
"emptyMessage": {
"type": "string",
"default": "No options available.",
"description": "What the list says when there are no options to choose from."
},
"aria-label": {
"type": "string",
"description": "Accessible name when there is no surrounding Field or visible heading."
},
"aria-labelledby": {
"type": "string",
"description": "IDs of visible elements that name the Select; wins over a Field's label."
},
"aria-describedby": {
"type": "string",
"description": "Description IDs; replaces a surrounding Field's help or error."
},
"disabled": {
"type": "boolean",
"default": false
},
"required": {
"type": "boolean",
"default": false
},
"name": {
"type": "string"
},
"size": {
"type": "enum",
"values": [
"sm",
"md",
"lg"
],
"default": "md"
},
"invalid": {
"type": "boolean",
"default": false
}
},
"slots": {
"children": {
"type": "SelectOption",
"required": true
}
},
"composable_with": [
"Field"
],
"never_inside": [
"Button",
"Badge"
],
"example": "<Field label=\"THEATER\">\n <Select placeholder=\"CHOOSE...\">\n <SelectOption value=\"indo-pacific\">INDO-PACIFIC</SelectOption>\n <SelectOption value=\"european\">EUROPEAN</SelectOption>\n </Select>\n</Field>"
}<SelectOption value="alpha">ALPHA</SelectOption>View agent manifest
{
"description": "Single option inside a Select. Must be a child of <Select>.",
"props": {
"value": {
"type": "string",
"required": true
},
"disabled": {
"type": "boolean",
"default": false
}
},
"composable_with": [
"Select"
],
"never_inside": [
"Button",
"Badge"
],
"example": "<SelectOption value=\"alpha\">ALPHA</SelectOption>"
}