Component
Select
Choice from a known, closed set of options.
Plain-text source, for agents and clipboard use: /components/source/select.txt
When to use it
Use when the value must come from a fixed list the user cannot extend, and the list is long enough that radios would crowd the layout — roughly five options or more.
Examples
Default
<div class="flux-field">
<span class="flux-field__label" id="channel-label">Sales channel</span>
<div class="flux-select" data-flux-select>
<button class="flux-select__control" id="channel-trigger" type="button" aria-haspopup="listbox" aria-expanded="false" aria-controls="channel-list" aria-labelledby="channel-label channel-value">
<span class="flux-select__value" id="channel-value">Direct B2C</span>
<svg class="flux-select__chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</button>
<input type="hidden" name="channel" value="direct" />
<div class="flux-select__panel" id="channel-list" role="listbox" aria-labelledby="channel-label" hidden>
<ul class="flux-select__options">
<li><button class="flux-select__option" type="button" role="option" aria-selected="true" data-value="direct"><span>Direct B2C</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="trade" tabindex="-1"><span>Trade partner</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="agent" tabindex="-1"><span>Agent network</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="corporate" tabindex="-1"><span>Corporate</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
</ul>
</div>
</div>
</div>With a placeholder option
Where no value is preselected, the first option states the choice rather than reading as a value.
<div class="flux-field">
<div class="flux-field__header">
<span class="flux-field__label" id="region-label">Region</span>
<span class="flux-info" data-flux-info>
<button class="flux-info__trigger" type="button" aria-label="About region" aria-describedby="region-info">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<circle cx="8" cy="8" r="6.25" stroke="currentColor" stroke-width="1.5" />
<path d="M8 7.25V11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
<circle cx="8" cy="5" r="0.875" fill="currentColor" />
</svg>
</button>
<span class="flux-info__bubble" id="region-info" role="tooltip" hidden>Determines which price rules apply.</span>
</span>
</div>
<div class="flux-select" data-flux-select>
<button class="flux-select__control" id="region-trigger" type="button" aria-haspopup="listbox" aria-expanded="false" aria-controls="region-list" aria-labelledby="region-label region-value" aria-describedby="region-info">
<span class="flux-select__value" id="region-value">Choose a region</span>
<svg class="flux-select__chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</button>
<input type="hidden" name="region" value="" />
<div class="flux-select__panel" id="region-list" role="listbox" aria-labelledby="region-label" hidden>
<ul class="flux-select__options">
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="iceland"><span>Iceland</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="nordics" tabindex="-1"><span>Nordics</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="uk" tabindex="-1"><span>United Kingdom</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
</ul>
</div>
</div>
</div>Grouped options
When the options fall into categories people scan by. Each group is labelled, and the labels are not selectable. Keep groups to a handful; if every group holds one option, drop the grouping.
<div class="flux-field">
<span class="flux-field__label" id="service-label">Service</span>
<div class="flux-select" data-flux-select>
<button class="flux-select__control" id="service-trigger" type="button" aria-haspopup="listbox" aria-expanded="false" aria-controls="service-list" aria-labelledby="service-label service-value">
<span class="flux-select__value" id="service-value">Choose a service</span>
<svg class="flux-select__chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</button>
<input type="hidden" name="service" value="" />
<div class="flux-select__panel" id="service-list" role="listbox" aria-labelledby="service-label" hidden>
<ul class="flux-select__options">
<li class="flux-select__group" role="none">
<span class="flux-select__group-label" id="service-group-1">Accommodation</span>
<ul role="group" aria-labelledby="service-group-1">
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Hotel room"><span>Hotel room</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Cabin" tabindex="-1"><span>Cabin</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Guesthouse" tabindex="-1"><span>Guesthouse</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
</ul>
</li>
<li class="flux-select__group" role="none">
<span class="flux-select__group-label" id="service-group-2">Transport</span>
<ul role="group" aria-labelledby="service-group-2">
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Coach transfer"><span>Coach transfer</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Domestic flight" tabindex="-1"><span>Domestic flight</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Ferry crossing" tabindex="-1"><span>Ferry crossing</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
</ul>
</li>
<li class="flux-select__group" role="none">
<span class="flux-select__group-label" id="service-group-3">Activities</span>
<ul role="group" aria-labelledby="service-group-3">
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Glacier walk"><span>Glacier walk</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Whale watching" tabindex="-1"><span>Whale watching</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Lagoon entry" tabindex="-1"><span>Lagoon entry</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
</ul>
</li>
</ul>
</div>
</div>
</div>Searchable
For lists longer than about ten options. The list opens with focus in a search field; typing narrows the options, Arrow Down moves into them and Enter picks the best match. Groups work here too, and a group with no matches is hidden.
No suppliers match.
<div class="flux-field">
<span class="flux-field__label" id="supplier-label">Supplier</span>
<div class="flux-select" data-flux-select>
<button class="flux-select__control" id="supplier-trigger" type="button" aria-haspopup="listbox" aria-expanded="false" aria-controls="supplier-list" aria-labelledby="supplier-label supplier-value">
<span class="flux-select__value" id="supplier-value">Choose a supplier</span>
<svg class="flux-select__chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</button>
<input type="hidden" name="supplier" value="" />
<div class="flux-select__panel flux-select__panel--search" hidden>
<div class="flux-select__search-row">
<input class="flux-input flux-select__search" type="text" aria-label="Search suppliers" aria-controls="supplier-list" placeholder="Search suppliers" autocomplete="off" />
</div>
<ul class="flux-select__options" id="supplier-list" role="listbox" aria-labelledby="supplier-label">
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Arctic Adventures"><span>Arctic Adventures</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Blue Lagoon" tabindex="-1"><span>Blue Lagoon</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Eagle Air" tabindex="-1"><span>Eagle Air</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Elding Whale Watching" tabindex="-1"><span>Elding Whale Watching</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Fosshotel Hekla" tabindex="-1"><span>Fosshotel Hekla</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Gray Line Iceland" tabindex="-1"><span>Gray Line Iceland</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Hotel Kea" tabindex="-1"><span>Hotel Kea</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Hótel Búðir" tabindex="-1"><span>Hótel Búðir</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Icelandair" tabindex="-1"><span>Icelandair</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Reykjavik Excursions" tabindex="-1"><span>Reykjavik Excursions</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Sky Lagoon" tabindex="-1"><span>Sky Lagoon</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
<li><button class="flux-select__option" type="button" role="option" aria-selected="false" data-value="Smyril Line" tabindex="-1"><span>Smyril Line</span><svg class="flux-select__check" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3 8L6.5 11.5L13 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg></button></li>
</ul>
<p class="flux-select__empty" hidden>No suppliers match.</p>
</div>
</div>
</div>Multi-select
When several values from a closed set may be chosen at once and the list is too long for a visible checkbox group. Checkbox options inside a dropdown panel; the trigger matches Select geometry. flux-components.js keeps the trigger label in step: the placeholder, up to two chosen labels, then a count.
United Kingdom
<div class="flux-field">
<div class="flux-field__header">
<span class="flux-field__label" id="markets-label">Markets</span>
<span class="flux-info" data-flux-info>
<button class="flux-info__trigger" type="button" aria-label="About markets" aria-describedby="markets-info">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<circle cx="8" cy="8" r="6.25" stroke="currentColor" stroke-width="1.5" />
<path d="M8 7.25V11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
<circle cx="8" cy="5" r="0.875" fill="currentColor" />
</svg>
</button>
<span class="flux-info__bubble" id="markets-info" role="tooltip" hidden>Price rules apply to every selected market.</span>
</span>
</div>
<details class="flux-multiselect" data-flux-multiselect data-placeholder="Choose markets" aria-labelledby="markets-label">
<summary class="flux-multiselect__control" aria-describedby="markets-info">
<span class="flux-multiselect__value">United Kingdom</span>
<svg class="flux-multiselect__chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</summary>
<div class="flux-multiselect__panel">
<ul class="flux-multiselect__options">
<li>
<label class="flux-multiselect__option">
<input class="flux-checkbox" type="checkbox" name="markets" value="iceland" />
<span>Iceland</span>
</label>
</li>
<li>
<label class="flux-multiselect__option">
<input class="flux-checkbox" type="checkbox" name="markets" value="nordics" />
<span>Nordics</span>
</label>
</li>
<li>
<label class="flux-multiselect__option">
<input class="flux-checkbox" type="checkbox" name="markets" value="uk" checked />
<span>United Kingdom</span>
</label>
</li>
<li>
<label class="flux-multiselect__option">
<input class="flux-checkbox" type="checkbox" name="markets" value="dach" />
<span>DACH</span>
</label>
</li>
</ul>
</div>
</details>
</div>Anatomy
| Part | Description |
|---|---|
| Label | Above the control, matching Input exactly. |
| Trigger | A button with the same height, radius and border as Input, so a mixed form stays level. |
| Indicator | A line chevron in icon-subtle at the trailing edge. Stroke only, not a filled triangle. |
| Listbox | A Flux surface containing keyboard-focusable options and the selected checkmark, optionally in labelled groups. |
| Search field | Optional, for long lists. Sits above the options and stays in view while they scroll. |
| Value | A hidden input carrying the selected value into ordinary form submission. |
API
| Name | Kind | Description |
|---|---|---|
flux-select | class | Positions the styled trigger and its floating listbox. |
data-flux-select | attribute | Initialises listbox selection, focus management and form-value syncing. |
flux-select-change | element | Cancelable event dispatched on the select when an option is chosen, with detail.value, detail.label and detail.option. A framework that renders the value cancels it and renders the selection from detail; the select then leaves the value, aria-selected and the hidden input to it. |
flux-select__control | class | Button trigger. Matches Input geometry exactly. |
flux-select__value | class | Visible selected option inside the trigger. |
flux-select__chevron | class | Line chevron indicator. Stroke inherits icon-subtle via currentColor. |
flux-select__panel | class | Floating Flux surface containing the listbox. |
flux-select__option | class | Focus-managed option. Set aria-selected on exactly one option. |
flux-select__group | class | An li with role="none" holding a flux-select__group-label and a nested ul with role="group" and aria-labelledby pointing at that label. |
flux-select__panel--search | class | Searchable panel. The panel itself has no role; role="listbox" moves to the flux-select__options list, which the trigger’s aria-controls points at. |
flux-select__search | class | Text input inside flux-select__search-row at the top of a searchable panel, with flux-input, an aria-label and aria-controls naming the listbox. |
flux-select__empty | class | Hidden message after the list, shown when the search matches nothing. |
flux-multiselect | class | Dropdown multi-select built on details. Checkbox options, each with flux-checkbox, inside the panel. |
data-flux-multiselect | attribute | On the details element. Keeps the trigger label in step with the checked options and closes the panel on Escape or a click outside. data-placeholder is the label when nothing is checked. |
flux-multiselect__control | class | The trigger summary. Same field geometry as flux-select. |
flux-multiselect__value | class | Trigger label. Written by the script; set its initial text to match the options checked in the markup. |
flux-field | class | Same wrapper as Input. |
aria-invalid | attribute | Error state on select or multiselect trigger. |
States
| State | Treatment |
|---|---|
| Default | Identical to Input at rest. |
| Hover | border-interactive. |
| Focus | Global teal focus outline. |
| Disabled | surface-disabled fill at 60% opacity. |
Keyboard
| Keys | Action |
|---|---|
Space, Enter | Opens the listbox from the trigger or selects the focused option. |
Up, Down | Opens the listbox, then moves focus through its options. |
Home, End | Moves to the first or last option. |
Type-ahead | Moves to the first option matching the typed characters. In a searchable select, typing goes to the search field instead. |
Escape | Closes the listbox and returns focus to the trigger. |
Down (in search) | Moves from the search field to the first matching option. Up from the first option returns to the field. |
Enter (in search) | Selects the first option that starts with the search text, or else the first match. |
Space, Enter | Opens or closes the multi-select panel. |
Tab | Moves through checkbox options inside an open multi-select panel. |
Escape (multi-select) | Closes the panel and returns focus to the trigger. |
Accessibility
- The trigger exposes aria-haspopup="listbox", its expanded state and the panel it controls. Its accessible name includes the visible field label and current value.
- Every option exposes aria-selected, and selection moves back to the trigger so the new value is announced in context.
- The hidden input carries the value into form submission. Validate required values in the form logic and bind any error with aria-describedby and aria-invalid.
- The line chevron and selected checkmarks are decorative and aria-hidden; selected state is also exposed programmatically.
- Multi-select uses a details panel with labelled checkboxes. Each option is a native checkbox so selection state is announced correctly.
- flux-components.js updates flux-multiselect__value as boxes change, so screen-reader users hear the current choice or count, not only the placeholder.
- Group labels are named by aria-labelledby on their group, so each option is announced with its category. They are not options and cannot be selected.
- The search field has its own aria-label; it narrows the list and never becomes the value. Options it hides are skipped by every key.
- Option text must stand alone; "Yes" and "No" mean nothing when read out of context.
Tokens
The tier-3 and tier-2 tokens this component binds to. Change the token, not the component.
- --flux-field-height
- --flux-field-radius
- --flux-field-border
- --flux-icon-subtle
- --flux-select-chevron-size
- --flux-select-panel-max-height
- --flux-multiselect-panel-max-height
Do and don’t
Do
- Order options by expected frequency, or alphabetically when frequency is unknown.
- Keep the trigger the same height as neighbouring inputs.
- Use multi-select when the list is long but only some values apply; use a visible checkbox group when the full set should stay in view.
- Add the search field once a list passes about ten options, so nobody scrolls to find a known name.
Don’t
- Do not use a select for two options — that is a switch or a pair of radios.
- Do not omit flux-components.js. The styled select requires its focus and form-value behaviour.