makeover-timing
The time axis of the make-family design system.
makeover resolves colour,
makeover-geometry resolves
distance, and
makeover-layout names what a
thing is without resolving anything. This crate answers the remaining question
of the same shape: how long.
A duration is named by what it is waiting for
| Moment | What it waits for | Resolves to |
|---|---|---|
revert |
a control returning to its resting label after confirming | 1500ms |
clear |
a status line emptying itself | 2000ms |
dismiss |
a transient notice's lifetime | 3000ms |
debounce |
typing settling before the work starts | 150ms |
Whether a toast should live 3000ms or 3500ms is unanswerable on its own.
Whether a message is a toast or a banner is not. That is the whole argument for
the layer, and it is the same one gap-peer makes about six pixels.
One duration per moment, on every renderer
A moment resolves to exactly one duration everywhere, whatever the renderer and whatever the theme.
Distance has a renderer axis because a fingertip is coarser than a cursor and a terminal cell is coarser than a pixel: the surface differs. Time does not differ that way. A second is a second in a browser, in egui and in a terminal, and the reader waiting it out is the same reader. A divergence between renderers is a bug report.
What is deliberately not a moment
A race is not a moment. Waiting 300ms before navigating because the write "should" have landed, or 150ms before closing a dropdown so a mousedown can beat the blur, is a synchronisation bug wearing a duration's clothes. Naming those would launder them into design decisions. They get fixed per screen.
Severity is not a moment, and it is not a fifth number. A message the user
must not miss does not go away on its own. makeover-layout already has the
word for that (such a message is not Notice::transient), and a banner has no
lifetime.
A poll interval is not a moment. A retry backoff, a health check, an update check: those are answerable from what they talk to, not from what a reader can follow.
Motion and cadence are separate axes
Moment says how long a state lasts. Motion says how long a change takes,
and Cadence says how often a repeating mark repeats. CSS draws the first line
itself, a setTimeout against a transition-duration: 300ms of fade and
3000ms of toast answer different questions.
Motion and Cadence both resolve to zero for a reader who has asked for less
motion. A web surface gets that as a prefers-reduced-motion block in the
generated stylesheet; every other renderer asks activity_blink with the
preference its platform reported.
Using it
Web surfaces bake the stylesheet in at build time. Nothing here changes at runtime, so there is no load-time JS step:
use timing_css;
write?;
egui and ratatui surfaces resolve through Duration instead, which is the
reason this is a crate rather than a stylesheet:
use ;
let settle = Debounce.duration;
let gone = notice_lifetime.map;
notice_lifetime takes the description's answer to "does this go away on its
own" rather than makeover-layout's Notice, so this crate stays off that
dependency graph.
Licence
MIT.