Skip to main content

Select

A select is the native <select> (Headless UI Select) with the field styling of Input and a chevron drawn as a background image. It takes plain <option> children and the browser's own picker, so it works everywhere and needs no portal. For custom option rendering use Listbox.

import Select from '@zuilib/components/select'

Variants

outline is the default field: --input border on --background. ghost has no border until it is hovered or focused.

Loading example

Sizes

sm, md and lg read --control-height-*, --control-padding-x-* and the matching --text-* step. The chevron is --spacing * 6 wide and sits half a control padding from the right edge; the text gets padding plus the chevron on the right so it never runs under it.

Loading example

States

state="error" paints the border and focus ring with --destructive and also marks the control invalid; success uses --success. disabled lowers the opacity and blocks the pointer.

Loading example

In a FormItem

FormItem generates the id and wires Label, Description and Message to the select. Its invalid becomes the select's default invalid, so one prop on the item paints the border and sets aria-invalid.

Loading example

Props

SelectProps extends the native <select> attributes (value, defaultValue, onChange, name, disabled, multiple, …) minus size, with:

PropTypeDefaultDescription
variant'outline' | 'ghost''outline'
state'default' | 'error' | 'success''default'Validation state; error also marks the control invalid
invalidbooleanFormItem invalidSets aria-invalid / data-invalid and the error styles
size'sm' | 'md' | 'lg''md'
fullWidthbooleanfalsew-full on the select
classNamestringMerged last onto the native select

Slots

SlotElementNotes
[data-slot="select"]selectRoot. Also data-state (default | error | success) and Headless UI's data-disabled, data-invalid, data-focus, data-hover

Tokens

TokenUsed for
--control-height-sm/md/lg, --control-padding-x-sm/md/lgBox per size and chevron inset
--spacingChevron width (* 6)
--input, --background, --foregroundOutline border, surface, text
--ring, --destructive, --successFocus ring per state
--radius-mdCorner radius
--duration-fastColour transition

Accessibility

  • A real <select>: keyboard (arrows, type-ahead, Space/Enter to open) and the platform picker come for free.
  • Label it with a FormItem Label, a <label htmlFor> or aria-label.
  • invalid (or state="error") sets aria-invalid; inside a FormItem the Message is reached through aria-describedby.
  • disabled uses the native attribute and inherits from an enclosing Fieldset / FormItem.
  • The chevron is a background image, so it is never read or focusable.
  • Listbox: custom-rendered options in a popover.
  • Combobox: a select you can type into.
  • Input: the same variants, sizes and states on a text field.
  • FormItem: label, description and message wiring.