Native Select

The browser's own select, styled: the system's list on every device.

Used for tax and invoices.

Installation

npx @yolkui/cli add native-select

When to use it

Only the closed control is styled; the open list is the system's: a wheel on iOS, a sheet on Android, a menu on the desktop. That list is large, familiar and fast on every device, it handles hundreds of options, and the select works before JavaScript loads and submits with the form like any other field. Use it when the options are plain text; options with icons, descriptions or a search need a custom select.

  • Options are NativeSelectOption and NativeSelectOptGroup: <option> and <optgroup> with a data-slot, so plain ones work too.
  • className styles the select's surface, which owns the layout. It is as wide as its longest option; className="w-full" fills the container.
  • Keep it out of a Toolbar: a toolbar moves focus with the arrow keys, and on a closed select the same keys change the value.

Variants

soft, the default, is Input's surface, so a select in a form matches the fields around it. variant="outline" and variant="secondary" are the outline and secondary Buttons' surfaces, for a select on its own: a sort, a filter, a table's page size. Beside an Input in a form they would not match.

Sizes

Button's and Input's four heights, 28 · 32 · 36 · 40, so a select lines up with a button or a field of the same size. shape="pill" rounds both ends.

xs · 28
sm · 32
default · 36
lg · 40

Placeholder and groups

A first option with value="" and disabled is a placeholder: it shows in the muted colour until a choice is made, and cannot be picked back. An empty option that is not disabled ("All countries") is a real choice and keeps the full colour. With required, the form will not submit while it is chosen. NativeSelectOptGroup labels a group of options in the open list.

In a group

In a ButtonGroup a select joins its neighbours like a field: one shape, square corners where they meet and one line at each seam. Beside an Input it keeps its width and the Input takes the rest; give the group a width (w-full). An outline select shares its border with outline buttons.

Invalid

In an invalid Field the edge and the focus outline turn red, and FieldError says why, with an icon and words.

Disabled

A disabled select fades, cannot be opened and is left out of the form, as a native one is. It is skipped by Tab, so a tooltip could never say why: put the reason in a FieldDescription under it, where everyone sees it, phones included.

The region is set when the project is created.

Accessibility

It is the browser's own select, so every screen reader, keyboard and switch device already knows it: Space or Alt+Down opens it, arrows move, typing jumps to an option. Screen readers hear the label, "pop-up button" or "combo box", and the chosen option.

  • Give it a label: a FieldLabel in a Field, or aria-label when it stands alone ("Sort by").
  • Text is 16px on phones, so iOS does not zoom the page in when it opens.
  • Options cannot be styled in the open list, so never rely on colour or icons there; the text carries the meaning.