Skip to the page
Tactile UI

Kit part · Lists · Selects

Listbox

An always-open list let into the plate as a recess. The rows are printed on its floor and a chosen row is a cap let down into it with its lamp lit. One row may be chosen, or several; typing a few letters finds the next row that starts with them. It starts as a native select with a size, so it posts with the form and works without a script.

Element
<tui-listbox>
Needs
kit.css + kit.mjs
Rules
listbox.rules.md · 6
Finishes
Aluminium · Graphite · Oak · Walnut · Porcelain · Black · Daylight · Night · Paper · Phosphor · E-paper · AMOLED
Volumes
Tactile · Quiet
On this page
  1. Variants
  2. Every state, at once
  3. API
  4. Markup
  5. Accessibility
  6. How it’s built
  7. Rules
  8. Related parts

Seats open in 11 days. Want one email that morning?

Variants

Without the script · the select
Portugaleu-south
Irelandeu-west
Germanyeu-central
One chosen · amber lamp
Portugaleu-south
Irelandeu-west
Germanyeu-central
Swedeneu-north
Several chosen · green lamps
Portugaleu-south
Irelandeu-west
Germanyeu-central
Under the arrow keys
Portugal
Ireland
Germany
United States
Brazil
In groups, and scrolling
Portugal
Irelandfull
Germany
A row that cannot be chosen

Every state, at once

Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.

Aluminium

PartRestHoverActiveChosenDisabled
Row
Ireland
Ireland
Ireland
Ireland
Ireland

Graphite

PartRestHoverActiveChosenDisabled
Row
Ireland
Ireland
Ireland
Ireland
Ireland

API

NameKindValuesWhat it does
<tui-listbox>elementaround one <select size>Hides the select, keeps it as the form’s value and draws the options as rows in the recess. Without the script the select is what shows.
<select multiple size="6">attributeon the selectSeveral rows may be chosen, with green lamps; size is how many rows show before the list scrolls.
data-hint · <optgroup label>attributeon options and groupsA second word printed at the right of a row; a printed heading over a group.
value · values · selectpropertystring · string[] · <select>What is chosen, and the select itself (listen for change on it).
tui-listbox-changeeventdetail { values }Bubbles from the element after the choice changes. The select’s own change fires as ever.
↑ ↓ · Home · End · PageUp · PageDownkeyon the listMove the active row. In a single list the choice follows it.
Space · Shift+↑ ↓ · Ctrl+Akeyin a multiple listChoose or let go of the active row; choose the run from where you started; choose every row.
A letterkeytype-aheadTyping finds the next row that starts with what you typed; the same letter again steps on to the next that starts with it.
typeaheadFind(labels, from, typed) · listboxRange(a, b) · listboxMove(index, key, n)functionpureWhich row a typed word finds, the rows between two, and where a key moves the active row.

Markup

<div class="tui-field">
  <label class="tui-label" for="region">Region</label>
  <tui-listbox>
    <select class="tui-select" id="region" name="region" size="5">
      <optgroup label="Europe">
        <option value="pt" data-hint="eu-south" selected>Portugal</option>
        <option value="ie" data-hint="eu-west">Ireland</option>
      </optgroup>
      …
    </select>
  </tui-listbox>
</div>

<!-- Several: a multiple select; plain presses choose and let go -->
<tui-listbox><select class="tui-select" id="targets" name="targets" size="6" multiple>…</select></tui-listbox>
import { typeaheadFind, listboxRange } from '/kit/kit.mjs';

const list = document.querySelector('tui-listbox');
list.addEventListener('tui-listbox-change', (e) => {
  console.log(e.detail.values);               // ['pt']
});

list.values;                                   // the values chosen
typeaheadFind(['Brazil', 'Germany'], -1, 'g'); // 1
listboxRange(1, 3);                            // [1, 2, 3]

Needs kit.css and kit.mjs. How to install the kit.

Accessibility

  • The WAI-ARIA listbox with aria-activedescendant: the list is one tab stop and keeps the focus while the active row moves, and each row has aria-selected; a list that takes several is aria-multiselectable.
  • The label of the select names the list, and the hint and error described on the select are described on the list. A group has its own name, read as the focus enters it.
  • A chosen row is a cap let down into the floor with its lamp lit, and it is selected for a screen reader; colour is never the only sign of it. The row under the keys has the 2px focus ring inside its edge.
  • Several chosen is said politely: “3 chosen”. In a single list the choice follows the arrows, as in a native select, so a keyboard user hears each row as they pass it.
  • On a phone the rows are 44px tall and the press chooses or lets go of a row with no modifier key, so touch needs no Shift or Ctrl.

How it’s built

The recess is the kit’s well and the rows are the combobox’s lines: a lamp, the words, a hint. A chosen row is drawn as a key let down into the recess, the same pressed shadow a latched key has, so it follows every finish and both volumes. The select stays in the page, hidden, and is written to with a real change event, so a form, a framework or a test reads it as ever. Type-ahead keeps a buffer for 700ms and treats one letter repeated as a request for the next row.

Rules

listbox.rules.mdIn the brain

Show every option at once instead of hiding it behind a key: arrows, type-ahead, ranges with Shift, and the same select underneath for the form.

6 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.

Select

A choice from a longer list, in the same recess as a field, with a printed chevron. The browser’s own menu opens it.

Combobox

A field that filters a long list as you type. It starts as a plain select, so it posts with the form and works without a script; then the options card slides out of a slot under the well, the letters that match print heavier and the chosen option’s lamp is lit. Several choices sit in the well as tags.

List

Rows in a rack: a mark, a title, a second line and a fact or a key at the end. Chosen rows sink into a recess with their check key latched; in a running order, a row lifts out of the rack on its skirt and slides past the others, from the keyboard or by its grip.

Multi-select

A combobox that takes several. Each choice is set down in the well as a tag, the card of options stays out while you choose the next, and the foot of the card counts what is chosen and lets it all go. It starts as a native select with the multiple attribute, so it posts with the form and works without a script.