Components · Inputs
Select
Choose one value from a known, closed list. When the list is long enough that scanning it is a chore, reach for a Combobox instead.
Figma source: Select ↗Examples
<div class="cds-field">
<label class="cds-field__label" for="proposal-type">Proposal type</label>
<select class="cds-select" id="proposal-type">
<option>New</option>
<option>Renewal</option>
<option>Resubmission</option>
</select>
</div>Option rows
The Figma Option component set is considerably richer than a native
<option>: it supports secondary and tertiary data lines, nesting,
checkboxes for multi-select, and a stacked layout for narrow viewports.
| Property | Values | Notes |
|---|---|---|
Element | Option · Nested Group | A leaf row, or a group header with children beneath it. |
Stacked | Single · Double · Triple | How many lines of data the row carries. |
Secondary Info? | boolean | Whether a supporting line is shown beneath the label. |
Checkbox | On · Off | Multi-select mode. |
State | Default · Selected | Selection state. |
Disabled | On · Off | Unavailable options remain visible but unselectable. |
The moment an option row carries more than a single string, a native
<select> can no longer render it and the component becomes a custom
listbox. That is a real cost: you now own keyboard handling (Up/Down, Home/End,
type-ahead), the role="combobox" / role="listbox" /
role="option" wiring, aria-activedescendant, and dismissal
behaviour — all of which the browser gave you for free.
Use the native element whenever the options are plain strings. Reach for the rich version only when the secondary data genuinely changes the user’s choice.
Select properties
| Property | Values | Notes |
|---|---|---|
State | Dropdown Closed · Dropdown Open · Admin Hover · Admin Choose | The two “Admin” values look product-specific rather than systemic — worth confirming whether they belong in the shared component. |
Usage
When to use it
- Use for a closed list of roughly 4–15 options.
- Order options meaningfully — by frequency, or alphabetically for long lists — not by the order they were added to the database.
- Keep disabled options visible when their absence would be confusing, and say why they are unavailable.
When not to use it
- Do not use for two options — use Radio buttons or a Toggle, which show both choices at once.
- Do not use for very long lists — use a Combobox so the user can type.
- Do not use for multi-select; a multiple
<select>is notoriously hard to operate. Use checkboxes or a multi-select combobox. - Do not put an option like “— Select —” in place of a label.
Accessibility
- Prefer the native
<select>. It is fully accessible, works with every assistive technology, and gets the right control on mobile. - Label with
<label for>, as with any field. - If you must build a custom listbox, implement the full ARIA combobox pattern — partial implementations are worse than none, because they announce a role they do not honour.
Tokens consumed
| Token | Applied to | Resolves to |
|---|---|---|
--input-background | Field fill | --color-white |
--input-border | Resting border | --color-gray-400 → #888c8c |
--input-text | Entered value | --color-black → #111111 |
--input-focus-border | Focus ring | --focus-ring → #44a3db ⚠ |
--input-error-background | Fill in error | --color-red-100 |
--input-error-border | Border in error | --color-red-500 |
--input-disabled-background | Fill when disabled | --color-gray-100 |
--input-disabled-text | Value when disabled | --disabled-text → #888c8c |
--input-label | Label | --color-black |
--input-required | Required asterisk | --color-red-500 |
--input-caption | Help text and placeholder | --color-gray-500 |
--input-error-caption | Error message | --color-red-500 |
--menu-background | Dropdown surface | --color-white |
--menu-border | Dropdown border | --color-gray-300 |
--menu-hover | Option hover | --color-gray-200 |
--menu-active | Selected option | --color-blue-100 |