Skip to the page
TACTILE UI

Kit part · Notifications · Receipts & tickets · Toasts

Ticket toast

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.

Element
ticketToast()
Needs
kit.css + kit.mjs
Rules
ticket-toast.rules.md · 6
Finishes
Aluminium · Graphite · Porcelain · Black
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
01

Variants

No.041

Deploy 4.2 finished in 3 regions.

One ticket
No.042

Signing key lode-prod-3 revoked.

With an action key
No.043

Warning. Disk at 91% on db-2. The on-call engineer has been paged.

Amber · a warning
Red · an error, role="alert"
No.047

Warning. Certificate renews in 9 days.

No.046

Cache warmed. Hit rate is back to 96%.

No.045

Build 412 passed.

A stack fans
No.049

Nothing to report.

Lamp off
No.048

The nightly export of the audit log to cold storage has been running for nine hours and is not finished.

Long words wrap
02

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

PartGreenAmberRedWith a key
Ticket
No.001

Saved.

No.002

Warning. Disk at 91%.

No.005

Key revoked.

Graphite

PartGreenAmberRedWith a key
Ticket
No.001

Saved.

No.002

Warning. Disk at 91%.

No.005

Key revoked.

03

API

NameKindValuesWhat it does
ticketToast(options)functionkit.mjsIssues a ticket and returns a handle, { el, number, dismiss() }. The first call sets the dispenser up.
options.textoptionstringThe words: one sentence. Written as text, never as markup.
options.toneoption"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.actionoption{ label, onClick }One action key. Pressing it calls onClick(handle) and then tears the ticket off, unless onClick returns false.
options.timeoutoptionms · 0How long before it retracts. 6000 by default. 0 keeps it until it is torn off, which is the default for red.
options.intooptionelementDispense into a box of your own instead of the bottom right of the screen. The box needs position: relative and overflow: hidden.
handle.dismiss()methodnonePulls the ticket back into the slot now.
.tui-ticket-toastsclassone per hostThe 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-toastclassrole · data-toneA ticket. role is status, or alert for red. data-leaving is on it while it goes.
.__paper · __stub · __no · __main · __text · __keysclassinside a ticketThe paper with its torn edge; the stub with its number and lamp; the words; and the row of keys.
.__action · .__tearclassthe keysThe optional action key, and the close key, a real button named “Tear off ticket 042”.
--i · --scustom propertyset by scriptHow 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.
swipepointeron the paperDrag 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.
Escapekeyboardinside a ticketTears the ticket off.
ticketNumber · ticketTone · ticketTimeout · ticketVerdict · ticketClock · ticketHTMLfunctionkit.mjsThe 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.
04

Markup

<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.

05

Accessibility

  • Each ticket is a live region of its own: 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 time belongs to the reader. The timer stops while the pointer is over a ticket or focus is inside it, and starts again with whatever was left. A red ticket has no timer.
  • Tearing off is never the only way out. The close key is a real button named “Tear off ticket 042”, and Escape does the same from anywhere in the ticket. The swipe is the quick way.
  • Focus is not dropped when a ticket goes. If it was inside, it moves to the close key of the next ticket, or back to where it was before the ticket came.
  • The action key is a real button named by its own words. Keep them to the act: “Undo”, “Open runbook”.
  • Keys sit on paper, which is light in both finishes, so their focus ring and printing use the paper’s ink, not the finish’s.
  • With reduced motion tickets appear and leave at once: no sliding, leaning or tearing. The timers still run and everything is still said.
06

How it’s built

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.

07

Rules

ticket-toast.rules.mdIn the brain

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.

08
Preset saved.

Toast

A confirmation after an action: a small plate with a lamp and one factual sentence, read out politely, gone in 3.6 seconds.

Check

Disk 82% full.

Alert

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.

Notifications

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.

Docs
Finish
Volume