Toast
A confirmation after an action: a small plate with a lamp and one factual sentence, read out politely, gone in 3.6 seconds.
Kit part · Notifications · Receipts & tickets · Toasts
A toast issued like a numbered ticket from a dispenser. A short slip of thermal paper with a number, a line of words and, if it needs one, an action key slides out of a slot at the edge of the screen. Several fan a little. Tear one off with a swipe or its close key, or leave it and it retracts by itself, on a timer that stops while you are reading it.
Deploy 4.2 finished in 3 regions.
Signing key lode-prod-3 revoked.
Warning. Disk at 91% on db-2. The on-call engineer has been paged.
Error. Canary rolled back: p95 latency passed 800 ms.
Warning. Certificate renews in 9 days.
Cache warmed. Hit rate is back to 96%.
Build 412 passed.
Nothing to report.
The nightly export of the audit log to cold storage has been running for nine hours and is not finished.
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 | Green | Amber | Red | With a key |
|---|---|---|---|---|
| Ticket | No.001 Saved. | No.002 Warning. Disk at 91%. | No.003 Error. Deploy failed. | No.005 Key revoked. |
Graphite
| Part | Green | Amber | Red | With a key |
|---|---|---|---|---|
| Ticket | No.001 Saved. | No.002 Warning. Disk at 91%. | No.003 Error. Deploy failed. | No.005 Key revoked. |
| Name | Kind | Values | What it does |
|---|---|---|---|
| ticketToast(options) | function | kit.mjs | Issues a ticket and returns a handle, { el, number, dismiss() }. The first call sets the dispenser up. |
| options.text | option | string | The words: one sentence. Written as text, never as markup. |
| options.tone | option | "green" · "amber" · "red" · "blue" · "white" · "off" | The lamp on the stub. Red makes the ticket role="alert" and puts “Error.” before the words for a screen reader; amber puts “Warning.”. Green by default. |
| options.action | option | { label, onClick } | One action key. Pressing it calls onClick(handle) and then tears the ticket off, unless onClick returns false. |
| options.timeout | option | ms · 0 | How long before it retracts. 6000 by default. 0 keeps it until it is torn off, which is the default for red. |
| options.into | option | element | Dispense into a box of your own instead of the bottom right of the screen. The box needs position: relative and overflow: hidden. |
| handle.dismiss() | method | none | Pulls the ticket back into the slot now. |
| .tui-ticket-toasts | class | one per host | The dispenser: a region named “Notices” with the slot at its foot. --in stands it in a box; --flow lays it in the page. data-open shows the slot. |
| .tui-ticket-toast | class | role · data-tone | A ticket. role is status, or alert for red. data-leaving is on it while it goes. |
| .__paper · __stub · __no · __main · __text · __keys | class | inside a ticket | The paper with its torn edge; the stub with its number and lamp; the words; and the row of keys. |
| .__action · .__tear | class | the keys | The optional action key, and the close key, a real button named “Tear off ticket 042”. |
| --i · --s | custom property | set by script | How far back a ticket is in the stack, and which way it leans. Set them yourself to fan a stack that script did not issue. |
| swipe | pointer | on the paper | Drag it sideways and it follows and leans. Past a third of its width, or fast, it tears off; short of that it settles back. Works with a finger. |
| Escape | keyboard | inside a ticket | Tears the ticket off. |
| ticketNumber · ticketTone · ticketTimeout · ticketVerdict · ticketClock · ticketHTML | function | kit.mjs | The rules, pure: the number, what a tone means, how long a ticket stays, whether a swipe tears, a clock that can be held, and the markup for a page that renders one on a server. |
<div class="tui-ticket-toasts tui-ticket-toasts--flow" data-open role="region" aria-label="Notices">
<div class="tui-ticket-toasts__slot" aria-hidden="true"></div>
<div class="tui-ticket-toast" role="status" data-tone="green">
<div class="tui-ticket-toast__paper">
<div class="tui-ticket-toast__stub">
<span class="tui-ticket-toast__label">No.</span>
<span class="tui-ticket-toast__no">042</span>
<span class="tui-lamp" data-on aria-hidden="true"></span>
</div>
<div class="tui-ticket-toast__main">
<p class="tui-ticket-toast__text">Signing key revoked.</p>
<div class="tui-ticket-toast__keys">
<button type="button" class="tui-key tui-key--sm tui-ticket-toast__action">Undo</button>
</div>
<button type="button" class="tui-key tui-key--sm tui-key--icon tui-key--flat tui-ticket-toast__tear"
aria-label="Tear off ticket 042">…</button>
</div>
</div>
</div>
</div>import { ticketToast } from '/kit/kit.mjs';
// The slot appears at the bottom right of the screen the first time you issue one.
const ticket = ticketToast({ text: 'Signing key lode-prod-3 revoked.', action: { label: 'Undo', onClick: restoreKey } });
ticket.number; // '042'
ticket.dismiss(); // pull it back into the slot now
ticketToast({ text: 'Disk at 91% on db-2.', tone: 'amber' });
ticketToast({ text: 'Canary rolled back: p95 passed 800 ms.', tone: 'red' }); // role="alert", stays until torn off
// Into a box of your own (position: relative; overflow: hidden) instead of the screen:
ticketToast({ text: 'Saved.', into: document.querySelector('.device') });Needs kit.css and kit.mjs. How to install the kit.
role="status", read after the current sentence, or role="alert" for red, read at once. A screen reader gets “Error.” or “Warning.” before the words. The lamp is a second signal.The slot is drawn in two halves with the tickets between them: a dark mouth behind and a raised lip in front, set apart by z-index, so paper comes out of the mouth and goes back into it. The paper is the kit’s paper tokens, the same in both finishes. Its torn edge is a mask of downward triangles, which would clip a shadow, so the shadow is a drop-shadow on the wrapper round it. The stub is set off by a dashed perforation. The lean of the stack is the individual rotate and translate properties, which leaves transform free for the Web Animations API: the slide out of the slot, the tear, and the older tickets riding up when a new one comes (a FLIP). The timer is ticketClock, which is pure and tested, held by the hover and by focus. A swipe is judged by ticketVerdict: a third of the width, or fast.
A notice with one action that the reader clears by hand, and a lamp for its tone.
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.
A confirmation after an action: a small plate with a lamp and one factual sentence, read out politely, gone in 3.6 seconds.
Disk 82% full.
A message let into the surface, with an annunciator: a small lit legend (Note, Done, Check, Fault) beside the words that say what happened.
Battery full
Surplus to the grid.
A key with a counter window in its cap, and a card of messages hung from it. Each unread message has its lamp lit; reading it puts the lamp out and the counter steps down.