Household pattern
Timeline
The week as a strip: day columns, one marker per event, and a playhead you can drag.
States
A full week, mid-week
drag the playhead, or focus it and use the arrow keys
Now: Wednesday, Aug 26 at 9:30 am
7:00 amWaiting on you
Reorder laundry detergent, the 5-litre size
The big bottle from Valley Wholesale works out 30% cheaper per wash than the one you usually get, but it's a bigger order than usual.
With what-if changes ringed
wait window cut to 4 hours: two outcomes change
Now: Wednesday, Aug 26 at 9:30 am
7:00 amWaiting on you
Reorder laundry detergent, the 5-litre size
The big bottle from Valley Wholesale works out 30% cheaper per wash than the one you usually get, but it's a bigger order than usual.
Read-only
no playhead control
Now: Wednesday, Aug 26 at 9:30 am
7:00 amWaiting on you
Reorder laundry detergent, the 5-litre size
The big bottle from Valley Wholesale works out 30% cheaper per wash than the one you usually get, but it's a bigger order than usual.
Empty
Nothing happened in this stretch.
Now: Wednesday, Aug 26 at 9:30 am
When to use
- Once per replay, above the list and detail panel.
- Read-only (no onNowChange) when the period is a fixed snapshot.
When not to
- For fewer than three events; a list is clearer.
- For periods longer than about two weeks; the markers get too dense at phone width.
Props
| Name | Type | Notes |
|---|---|---|
| events* | EvaluatedEvent[] | From the engine. Any order; the timeline sorts. |
| startsAt / endsAt* | number | Instants from parseWallClock. |
| now* | number | The playhead. Everything after it is upcoming. |
| onNowChange | (now: number) => void | Enables dragging and keyboard scrubbing. |
| selectedId / onSelect | string, (id) => void | Marker selection. |
| changedIds | Set<string> | Markers whose outcome changed under what-if get a ring. |
* required
Accessibility invariants
- The playhead is a slider: arrow keys move an hour, Shift six hours, PageUp/PageDown a day, Home/End to the ends. Its value text is the full date and time.
- Markers are native buttons in a toolbar with roving tabindex and aria-pressed; arrow keys move between events in time order. Changed outcomes are included in their accessible names.
- Every marker's name is its date, action and status. Colour and glyph are reinforcement.
- Drag uses pointer events with capture, so it works with touch and mouse; the strip is touch-action none.
Agent instructions
For anything generating UI from this system
Render one Timeline per replay with events from the engine run, startsAt/endsAt from the fixture, and now from state that the ApprovalCard and TraceEvent list also read. Pass onNowChange so the user can scrub, and onSelect so the detail panel follows. Under a what-if, pass changedIds from diffRuns. Do not position or colour markers yourself; do not add a second playhead.