Confirm
Erase reel 3?
Dialog
A decision that must be made now: a native dialog with a question, one sentence of consequence, a way back and the act.
Kit part · Dialogs · Search bars
Every action and page behind one key: a modal plate whose entry line is a lit display, with the results printed below and the chosen one pressed in.
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
| Part | Just opened | Typed, moved down | Nothing found |
|---|---|---|---|
| Palette | DashboardGD CircuitsGC | BatteryGB Set reserve | Nothing matchesNo line has “solar”. |
Graphite
| Part | Just opened | Typed, moved down | Nothing found |
|---|---|---|---|
| Palette | DashboardGD CircuitsGC | BatteryGB Set reserve | Nothing matchesNo line has “solar”. |
| Name | Kind | Values | What it does |
|---|---|---|---|
| .tui-command | class | on <dialog> | The palette: a modal plate up to 600px wide, 12% down the window. |
| data-command-key | attribute | a letter | Opens it with ⌘ or Ctrl and that letter. Leave it off to open only from a key. |
| data-command-open | attribute | the dialog’s id | On any key: opens the palette with an empty field. |
| .tui-command__display | class | on <div> | The entry line: a VFD window, a › prompt, the query, the count of matches. |
| .tui-command__input | class | role="combobox" | The field. aria-expanded, aria-controls and aria-autocomplete="list"; the part sets aria-activedescendant. |
| .tui-command__count | class | on <output> | Rewritten as “9 matches”. |
| .tui-command__list · .tui-command__group | class | role="listbox" · role="group" | The results, in named groups; a group with no match is hidden. |
| .tui-command__heading | class | aria-hidden | The printed group name (the group’s aria-label says it). |
| .tui-command__item · role="option" | class · attribute | — | A line: icon, words, <small> detail, shortcut. aria-selected marks the chosen one. |
| data-value · data-keywords | attribute | on an option | What the line returns; other words it should be found by. |
| .tui-command__keys > kbd | class · element | — | A shortcut drawn as small keys on a skirt. |
| .tui-command__empty · [data-command-query] | class · attribute | hidden | Shown when nothing matches, with the query written into it as text. |
| .tui-command__foot | class | — | The printed key hints along the bottom. |
| .tui-command--inline | class | on a <div> | The same palette in the page, for a filterable list. |
| openCommand(d) · filterCommand(d) · commandMatches(text, query) | function | kit.mjs | Open it; refilter after changing the lines; the pure match rule. |
| tui-command | event | detail: value, option | Fired on the dialog when a line runs; then it closes with returnValue = value. |
| ↑ ↓ · Enter · Escape | keyboard | in the field | Move the chosen line (wrapping), run it, close. Focus returns to where it was. |
<button class="tui-key" data-command-open="cmd">Commands</button>
<dialog class="tui-command" id="cmd" aria-label="Commands" data-command-key="k">
<div class="tui-command__display">
<input class="tui-command__input" type="search" role="combobox" aria-label="Command"
aria-expanded="true" aria-controls="cmd-list" aria-autocomplete="list"
autocomplete="off" spellcheck="false" placeholder="Type a command or a page">
<output class="tui-command__count"></output>
</div>
<div class="tui-command__list" id="cmd-list" role="listbox" aria-label="Commands">
<div class="tui-command__group" role="group" aria-label="Go to">
<div class="tui-command__heading" aria-hidden="true">Go to</div>
<div class="tui-command__item" role="option" data-value="battery" data-keywords="storage">
<svg …></svg><span>Battery</span>
<span class="tui-command__keys"><kbd>G</kbd><kbd>B</kbd></span>
</div>
</div>
</div>
<div class="tui-command__empty" hidden>
<span class="tui-status"><span class="tui-lamp"></span>Nothing matches</span>
<span>No line has “<span data-command-query></span>”. Try a page, a device or a verb.</span>
</div>
</dialog>import '/kit/kit.mjs'; // wires every .tui-command and [data-command-open]
const palette = document.getElementById('cmd');
palette.addEventListener('tui-command', (e) => run(e.detail.value));
import { openCommand } from '/kit/kit.mjs';
openCommand(palette);Needs kit.css and kit.mjs. How to install the kit.
<dialog> opened with showModal(): focus is held inside and returns to where it was on close.aria-activedescendant moves, so typing never stops working.aria-label; the printed headings are aria-hidden so each is read once.A native dialog with the kit’s rise. The entry line is a VFD (the display background, scanlines, an inset shadow and a two-step glow on the typed text) with the caret in the same light. command.mjs filters by delegation: every word typed must appear in a line or its keywords, empty groups hide, the first match is chosen. The chosen line is the kit’s recess; shortcuts are drawn as 20px caps on a 1.5px skirt, the same build as a key.
Lines are named for what they do, grouped by kind, and show their shortcut as the keys to press; finding nothing says what to try instead.
5 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.
Confirm
Erase reel 3?
A decision that must be made now: a native dialog with a question, one sentence of consequence, a way back and the act.
A vacuum-fluorescent display: cyan-white light on near-black glass, with a glow and a ghost. Frequencies, levels, status screens.
A card of actions and options that slides out from under its key. The key stays down while the card is out; an option that is on lights its lamp.