Select

One value from a list, shown in the field once it is chosen: a button in Input’s box that opens the system’s own list.

Try it

On shift
Amanda Hall
Jonathan Young
Ashley Brooks
Away
Sandra Brown
90791 - Diagnostic evaluation
90792 - Therapeutic exercises
90834 - Psychotherapy, 45 minutes
Phoenix Clinic Hospital
Scottsdale Clinic Building
Video office

An Avatar before the name, a code in bold, a plain list with an icon: the three drawn fields. Type a letter, open or closed, to go to an option.

Choosing a select

A select is for one value from a list too long to lay out: past six or so options, a row of radios is a wall, and a select is one line. Under that, prefer radios, which show every answer at once and need no opening. Two answers are a switch or a checkbox, never a select.

Put the options in the order the reader expects — alphabetical for names and places, by size or by time where the list has one, and the common answer first when there is one — and choose it for them when the form usually wants it. A placeholder is a prompt for the field’s answer, Choose a service: it is not an option, and it cannot be the value a required field submits.

Select or dropdown menu

Both are a button that opens a list on the same surface, and in a drawing they are the same thing. They answer different questions. A select holds a value: the choice stays visible in the field afterwards, belongs to a form, and is submitted with it. A dropdown menu runs a command: nothing is kept, the list closes, and something happens — reschedule, export, cancel.

The test is what the control shows once the list has closed. If it shows the choice, it is a Select. If choosing was the end of it, it is a dropdown menu. A screen reader is told the difference: a select says its name, its value and “3 of 12”; a menu says how many commands it has.

Chosen, and active

The chosen option carries a check in the accent and nothing else. The wash belongs to the active option, the one under the pointer or the arrows, so the two are never the same mark, and when they are the same option both show. The check is a shape, so the choice does not rest on colour.

Anatomy and sizes

Select geometry, in pixels
PartValue
FieldInput’s box: 32, 40 or 48 tall, radius 12
Chevron20, in the accent
Listthe menu’s surface, radius 12, 8 of padding, never narrower than the field
Option40 tall, radius 6; taller with a description
Description12 / 16
Check16, in the accent
Mosteight options, then it scrolls
Consultation30 minutes
Follow-up15 minutes
Assessment60 minutes
Consultation30 minutes
Follow-up15 minutes
Assessment60 minutes
Consultation30 minutes
Follow-up15 minutes
Assessment60 minutes

The field is Input’s box, at its three heights, with the same fill and the same border that arrives on focus. The open list is not drawn anywhere; it is the menu’s rows on the one floating surface the menu, the date picker and the popover stand on.

States

Consultation30 minutes
Follow-up15 minutes
Assessment60 minutes
Consultation30 minutes
Follow-up15 minutes
Assessment60 minutes

No hover, as on Input: the box does not react to the pointer, and the border arrives with focus. Disabled drops the paint and the focus; invalid takes the danger border, and inside a Field the message that says what to choose.

In a Field

Determines the length of the appointment.
Consultation30 minutes
Follow-up15 minutes
Assessment60 minutes
Choose a service before continuing.

The Field’s label names the button, and its description and error are read with it. With a name the value goes with the form through a hidden input. A hidden input cannot stop a form, so required is said to a screen reader and enforced by the caller, as the error above is.

The platform’s select

Until 2026-09-21 this component was the native <select>, by a rule the system still holds: prefer the native element. It was set aside here for one reason. The drawn fields hold what a native list cannot show — an Avatar, a code in bold, a second line — and the list belongs to the operating system, so it is a different list in every browser. appearance: base-select will end that trade; it is in Chrome, Edge and Safari 27, and not yet in Firefox.

The native one is NativeSelect, unchanged. It is the better choice on a phone in a long form, where the platform’s picker is better than any list of ours, and for a very long list such as countries.

The platform’s list.

Accessibility

It is the select-only combobox of the ARIA practices: a button with role="combobox" that owns a listbox. The keyboard’s focus never leaves the button; the active option is named to it, so there is one tab stop and nothing to give the focus back to. The list is the platform’s popover, so a press outside closes it.

Select, by keyboard
KeyDoes
Down, Up, Enter, SpaceOpen the list at the option that is chosen.
Down, UpMove over the options, past what cannot be chosen, and stop at the ends.
Home, EndThe first and the last.
A letterThe next option that starts with it, open or closed.
Enter, SpaceChoose and close.
TabChooses the active option and moves on.
EscCloses with nothing chosen, and goes no further: a Dialog around it stays.

The select never renders its own label. Wrap it in a Field or give it an aria-label, as the sizes above do. An option’s label is always words, even where content is shown in its place: it is what typing finds.

Props

TSX
import { Select, Avatar, Field } from 'alpenglow';

<Field label="Staff">
  <Select
    name="staff"
    placeholder="Choose someone"
    value={staff}
    onChange={setStaff}
    options={[
      { label: 'On shift', options: people.map((p) => ({
        value: p.id,
        label: p.name,
        start: <Avatar name={p.name} size="xxs" />,
      })) },
    ]}
  />
</Field>
Select props
PropTypeDefault
optionsSelectEntry[] — options, or groups of themrequired
valuestring—
defaultValuestring''
onChange(value: string) => void—
placeholderstring—
size'sm' | 'md' | 'lg'density/control — 40, 32 compact
invalidbooleanfrom Field, else false
disabledbooleanfalse
requiredbooleanfrom Field
namestring—
iconStartReactNode—
id, aria-label, aria-labelledby, aria-describedbystringfrom Field
classNamestring—
An option
FieldTypeDefault
valuestringrequired
labelstring — what typing finds and a screen reader saysrequired
startReactNode — an Avatar, an icon—
descriptionstring—
contentReactNode, shown in place of the label—
disabledbooleanfalse

A group is { label, options }. NativeSelect takes size, placeholder, invalid, iconStart, its options as children, and every attribute of a select.