OPERATOR

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

PROPTYPEDEFAULTREQUIRED
motion

Tactile pointer arrival, exit, and open-state chevron rotation; keyboard, assistive activation, and system reduced motion remain immediate.

enum
auto | none
"auto"no
value

Controlled selected option value. Keep the selected option among the children; a value with no matching option shows the placeholder and submits nothing.

string—no
defaultValue

Initial selected option value.

string—no
onValueChange

(value: string) => void. Called when the operator chooses an option.

function—no
open

Controlled open state of the list.

boolean—no
defaultOpen

Initial open state.

booleanfalseno
onOpenChange

(open: boolean) => void. Called when the list opens or closes.

function—no
placeholderstring—no
emptyMessage

What the list says when there are no options to choose from.

string"No options available."no
aria-label

Accessible name when there is no surrounding Field or visible heading.

string—no
aria-labelledby

IDs of visible elements that name the Select; wins over a Field's label.

string—no
aria-describedby

Description IDs; replaces a surrounding Field's help or error.

string—no
disabledbooleanfalseno
requiredbooleanfalseno
namestring—no
sizeenum
sm | md | lg
"md"no
invalidbooleanfalseno
PROPTYPEDEFAULTREQUIRED
valuestring—yes
disabledbooleanfalseno

Accessibility

  • Button trigger linked to a listbox; supports type-ahead.
  • Enter/Space opens; Arrow keys navigate; Escape closes.
  • Inherits id, aria-describedby, aria-invalid, and required from Field. Outside a Field, aria-labelledby names it by a visible heading and aria-describedby describes 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 when aria-describedby replaces the Field's help: the trigger is a button, which cannot carry aria-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>"
}

On this page