Skip to main content

Select

Stable

Compound dropdown with full keyboard navigation, type-ahead, groups, and separators. Controlled and uncontrolled modes both supported.

Form elementInteractiveVhyxSeal

Interactive example

Country selector with groups

Import

tsx
import { Select } from '@vhyxui/react'

// Compound sub-components
// Select.Trigger  — the visible button that opens the dropdown
// Select.Content  — the dropdown panel
// Select.Item     — a selectable option
// Select.Group    — groups related items
// Select.Label    — label for a group
// Select.Separator — visual divider between groups

Variants

Simple flat list
With disabled items
Disabled select

Sizes

sm, md, lg

Props

PropTypeDefaultDescription
valuestringControlled selected value.
defaultValuestringDefault value for uncontrolled usage.
onValueChange(value: string) => voidCalled when the user selects a new option.
disabledbooleanfalseDisables the entire select.
size'sm' | 'md' | 'lg''md'Size of the trigger — maps to --vhyx-size-* tokens.
placeholderstringPlaceholder text shown when no value is selected.
contractPartial<ComponentContract>VhyxSeal contract override.

Select.Item accepts value: string (required) and disabled?: boolean.Select.Group is a semantic grouping wrapper.Select.Label renders a group heading.

Accessibility

  • Trigger has role="combobox", aria-haspopup="listbox", aria-expanded.
  • Dropdown has role="listbox". Items have role="option".
  • Type-ahead: typing characters immediately jumps to the first matching option.
  • Disabled items have aria-disabled="true" and cannot be selected.
  • Focus ring via :focus-visible.

Keyboard navigation

KeyAction
EnterorSpaceOpen the dropdown.
Arrow DownorArrow UpNavigate between options.
HomeJump to the first option.
EndJump to the last option.
EnterSelect the focused option and close.
EscapeClose the dropdown without selecting.
A–ZType-ahead: jump to the first matching option.

Agent contract

Default VhyxSeal contract shipped with every Select.

Default contract
{
  "type": "input",
  "intent": "select-option",
  "description": "Allows the user to choose one option from a dropdown list",
  "requires": [],
  "requiredPermissions": [],
  "consequence": "Updates the selected option value in the parent form context",
  "affects": [
    "form"
  ],
  "reversible": true,
  "safetyLevel": "low",
  "requiresConfirmation": false,
  "destructive": false,
  "contractVersion": "0.0.1",
  "fingerprint": "vhyxs_384d4b58"
}

Theming

Override these CSS tokens to theme Select.

--vhyx-size-sm/md/lgTrigger height per size
--vhyx-color-borderTrigger border color
--vhyx-color-border-focusTrigger focus border
--vhyx-color-surface-overlayDropdown background
--vhyx-color-accent-subtleSelected item background
--vhyx-shadow-lgDropdown shadow
--vhyx-radius-mdTrigger and dropdown radius
--vhyx-shadow-focusFocus ring

Examples

Font size selector

Compact numeric selector

Inside a Field

tsx
<Field name="country" label="Country" required>
  <Select {...form.register('country')} placeholder="Select country">
    <Select.Trigger />
    <Select.Content>
      <Select.Item value="us">United States</Select.Item>
      <Select.Item value="gb">United Kingdom</Select.Item>
    </Select.Content>
  </Select>
</Field>