Skip to content
design system
Thème d’affichage, actuellement Auto

atom · stable · since 2026-09

Select

Purpose

A choice among options, as the native select and nothing else. The browser gives the focus, the arrows, typing the first letters, the system’s picker on a phone; a remade select loses all of it. The component ties the label, the hint and the error, and keeps an empty option so nothing chosen stays distinct from a choice.

When to use, when not

Use it for a choice among many options, or among a few that need no comparing. For two to five options the user should see at once, RadioGroup. For free text, Field.

Anatomy

  1. The label, with the required mark when needed.
  2. The hint.
  3. The select, with the empty option first, the options or the groups.
  4. The error.

Props

Props of Select
NameTypeDefaultWhat it does
idstringThe control's id; the label's `for` is the same value.
labelstringThe visible label, a noun.
name?stringThe name sent with the form.
value?string | undefinedThe chosen value; bindable, absent reads as nothing chosen.
options?Option[][]The options, when they are not grouped.
groups?Group[][]The options by group.
placeholder?string'Choisissez'The text of the empty option, "Choisissez" by default; an empty string removes it.
hint?string | undefinedA help sentence, announced with the field.
error?string | undefinedThe error message; its presence alone marks the field invalid.
required?booleanfalseRequired: the word goes into the accessible name and the attribute onto the control.
disabled?booleanfalseUnavailable.

States

Plain, with a choice made, grouped, required, in error, and unavailable.

chosen

Light

Le niveau change le nombre de critères évalués.

Dark

Le niveau change le nombre de critères évalués.

320 px, light

Le niveau change le nombre de critères évalués.

320 px, dark

Le niveau change le nombre de critères évalués.

216 px, light

Le niveau change le nombre de critères évalués.

Forced colours, captured
Select, story chosen, as Chromium renders it with forced colours active

disabled

Light

Une seule version est prise en charge.

Dark

Une seule version est prise en charge.

320 px, light

Une seule version est prise en charge.

320 px, dark

Une seule version est prise en charge.

216 px, light

Une seule version est prise en charge.

Forced colours, captured
Select, story disabled, as Chromium renders it with forced colours active

error

aria-invalid on the select, the message tied by aria-describedby and read as an alert.

Light
Dark
320 px, light
320 px, dark
216 px, light
Forced colours, captured
Select, story error, as Chromium renders it with forced colours active

grouped

optgroup: the group label is read before its options, and the position is counted inside the whole list.

Light
Dark
320 px, light
320 px, dark
216 px, light
Forced colours, captured
Select, story grouped, as Chromium renders it with forced colours active

plain

Light
Dark
320 px, light
320 px, dark
216 px, light
Forced colours, captured
Select, story plain, as Chromium renders it with forced colours active

required

Light
Dark
320 px, light
320 px, dark
216 px, light
Forced colours, captured
Select, story required, as Chromium renders it with forced colours active

Accessibility contract

  • Role and name: a listbox in a combobox, as the browser exposes a select, named by its label; “(obligatoire)” in the name when required.
  • Keyboard, focus: the browser’s. No navigation on change: the arrows walk the options one by one, and a navigation fired there would leave on the first one met.
  • Live regions: the error is role="alert".

Content rules

French. The label is a noun (“Niveau visé”); the empty option says what to do (“Choisissez”, “Choisissez un critère”); option texts are short and start with what distinguishes them.

Do and don’t

  • Do keep the empty option unless a value is always chosen, as with a single supported version.
  • Do not navigate or submit on change.
  • Do not remake the control with a list of divs.

Examples

<Select id="level" label="Niveau visé" options={levels} bind:value={level} required />
<Select id="criterion" label="Critère" groups={byTheme} placeholder="Choisissez un critère" />

Surfaces

  • App: the audit’s method and version, the new account’s role.
  • Extension: the page switcher’s list, when the panel is on Svelte.

Related

Field, RadioGroup.

Decisions

  • 2026-09-24: placeholder defaults to “Choisissez” and an empty string removes it, so the ordinary case asks and the exception is written.

Criteria held by construction

  • 11.1, Chaque champ de formulaire a-t-il une étiquette ?
    The label's for and the control's id come from one prop, so a select cannot be rendered without its label.
  • 11.10, Dans chaque formulaire, le contrôle de saisie est-il utilisé de manière pertinente ?
    The error is tied by aria-describedby and aria-invalid together, and an empty option keeps nothing chosen distinct from a choice.
  • 7.3, Chaque script est-il contrôlable par le clavier et par tout dispositif de pointage ?
    The native element gives the arrows, the first letters and the system's picker; nothing is remade, so nothing is lost.

Tokens it reads

  • Colour: --rl-action, --rl-ink, --rl-ink-soft, --rl-line, --rl-line-control, --rl-nc, --rl-surface
  • Typography: --rl-weight-bold, --rl-text-base, --rl-text-sm
  • Spacing: --rl-space-1-5, --rl-space-2, --rl-space-3
  • Layout: --rl-radius, --rl-border

Seen in patterns