Timeline
Every example on this page is live, drawn by the library's Storybook, where you can also change its props and see the result.
An event timeline with dots and connecting lines, running down a column or across a band. Give an event an icon to draw it in place of the dot, or number every event for a list of steps. Mark one current to make it the one solid mark on the line. Set fit to fill a box and the timeline shows as many whole events as the box holds.
Import
import { Timeline } from "~lib/data-display/timeline";
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
events | { title: string; description?: string; timestamp?: string; icon?: IconName | ReactElement; current?: boolean }[] | Yes | N/A | Timeline events; current marks the event drawn solid, such as the next one due |
size | "xs" | "sm" | "md" | No | "md" | Type size and spacing; the smaller sizes suit slim columns |
lines | number | No | N/A | Keep each title to at most this many lines, ending in "…" |
maxRows | number | No | N/A | Show at most this many events |
fit | "content" | "fill" | number | No | "content" | Fill a flex parent or take a height in pixels; a vertical timeline shows only the events that fit |
numbered | boolean | No | false | Mark each event with its step number in place of its dot or icon |
direction | "vertical" | "horizontal" | No | "vertical" | Run the events down a column, or side by side across a band |
minColumnWidth | number | No | 120 | With direction="horizontal", the narrowest a column gets, in pixels, before fewer events show |
Examples
Default
With Timestamps
Single Event
With Icons
An event's icon is drawn in place of its dot, with the line running into it from above and on from below. Give it an Icon name such as "person-walking" or "bus", or any small element of your own. Icons grow with size.
For a route from a directions API, travelModeIconName turns each step's travel mode into an icon name. A mode it does not know keeps the dot.
import { travelModeIconName } from "~lib/icon";
import { Timeline } from "~lib/data-display/timeline";
const Steps = ({
steps,
}: {
steps: { instruction: string; mode: string }[];
}) => (
<Timeline
events={steps.map((step) => ({
title: step.instruction,
icon: travelModeIconName(step.mode),
}))}
size="sm"
fit="fill"
/>
);
Numbered Steps
numbered marks each event with its step number in a filled circle, for a recipe's method or any other list of steps. The numbers take the place of the dots, and of any icons.
The circles shrink with size, and a number with more digits is set smaller to fit its circle.
Compact
size="xs" tightens the type and the room between events for a slim column.
Clamped Titles
lines keeps each title to at most that many lines, ending in "…".
At Most a Few Rows
maxRows shows at most that many events.
Fill a Box
With fit="fill" the timeline takes the room its flex parent leaves and shows as many whole events as fit, so a widget does not have to guess how many rows its box holds. A number takes that height in pixels instead.
Current Event
Mark an event current, such as the next prayer of the day or the step a journey is on, and it is the one drawn solid: the other events' dots are outlined, so the eye lands on it without a word written beside it. Pass the flag on the event itself, so it stays with the right event however the list is sorted or cut.
import { Timeline } from "~lib/data-display/timeline";
const Prayers = ({
prayers,
now,
}: {
prayers: { name: string; time: Date; label: string }[];
now: Date;
}) => {
const next = prayers.find((prayer) => prayer.time > now);
return (
<Timeline
events={prayers.map((prayer) => ({
title: prayer.name,
timestamp: prayer.label,
current: prayer === next,
}))}
size="sm"
/>
);
};
A current event's icon is drawn in the background color on a filled disc, and the other icons stay as they are.
In a numbered timeline the current step's circle stays filled and the others are outlined.
Horizontal
direction="horizontal" lays the events out side by side for a band along the top or bottom of the frame: equal columns across the width, the markers and the line along the top, each event's title, description and timestamp beneath its marker. lines clamps the titles as it does down a column.
It shows as many events, from the first, as the width holds at minColumnWidth each, and drops the rest, so in a narrower box the later events give way rather than every column squeezing. The line runs on past the last column shown when more events follow. The browser counts the columns from the box's own width, so a saved render shown in a narrower box drops columns too.
current and numbered work the same way across a band.