pub struct Track {
pub span: Span,
pub slot: u16,
pub tick: u16,
}Expand description
A time axis: things placed by when they happen, rather than flowed.
§Why this is a primitive
This crate refused to name it until 2026-08-15, on the argument that a description expressive enough to draw a timeline is a component library wearing a description’s name. The refusal is withdrawn, and it is worth being precise about what was wrong with it, because the reasoning it used applies to real cases and should not be discarded with it.
What a timeline needs that a List does not is one
thing: placement. Where a thing sits is a fact about the thing, the way a
row’s primary text is, and it is not derivable from order. Everything else a
day view draws – the labels, the gridlines, the item bodies, the tones –
is furniture this vocabulary already names. Measured against goingson’s
day-planning-render.js, the only members it needed and could not get were
at and minutes.
So the timeline was never a component library’s worth of vocabulary. It was two integers, and the refusal was priced as though it were the whole widget. The test that matters is not “does this shape look complicated” but “how many members does it actually add, and are they facts or presentation”. Slot heights, gridline colour, how overlaps stack and which hour scrolls into view on open are all presentation and all stay the renderer’s, which is why they are absent here.
§What it does not carry
No pixel measure, no scroll offset, no drag affordance. A renderer draws the
span at whatever density its host uses; makeover-geometry owns that the
way it owns everything else measured in pixels.
Fields§
§span: SpanThe window the axis covers.
slot: u16The granularity a thing can be placed on, in minutes.
goingson’s day view is 15, giving 96 slots across a day. A renderer uses
it to decide where gridlines fall and what a drop lands on; it does not
constrain Placement, because data arriving from a calendar does not
respect anyone’s grid.
tick: u16How often the axis labels itself, in minutes.
60 gives an hourly ruler over a 15-minute grid, which is the common
shape and the reason this is separate from slot. Zero means an
unlabelled axis.
Implementations§
Source§impl Track
impl Track
Sourcepub const fn slots(self) -> u16
pub const fn slots(self) -> u16
How many slots the axis holds.
Rounded up, so a span that does not divide evenly by slot still has a
slot covering its tail rather than dropping it. Never zero: slot of 0
reads as one slot spanning the whole axis rather than a division by
zero, since a renderer asking this question has already committed to
drawing something.
Sourcepub fn fraction(self, minute: u16) -> f32
pub fn fraction(self, minute: u16) -> f32
Where a placement sits on the axis, as a fraction from 0.0 to 1.0.
The one calculation every renderer would otherwise write itself, and the place the three would drift apart. Clamped, so a placement outside the span draws at the edge rather than off it – an event running past midnight is a real thing and truncating it is better than either panicking or drawing it somewhere impossible.