shadcn.io is not affiliated with official shadcn/ui
Minimal Line Timeline Block for Ark UI
A journal on a whisper-thin line where each dot is sized by the words written (four steps) and is a button that opens its entry underneath, with the entry count, the words and the longest gap worked out in the header.
Installation
Overview
Let the shape of the line carry the data with this minimal timeline for React with Ark UI. It is written for Lampbook, a fictional journal app. A hairline frame with a plus mark on each corner holds seven journal entries on one thin line, newest first, each a date and one sentence. The size of each dot is the number of words written, in four steps (under 40, 40 to 99, 100 to 199 and 200 and over), with a one-line key under the line. Each dot is a real button named for what it opens ("Read 3 October, 212 words"), and its whole row is the target. Pressing one opens that entry's first lines and its word count under it and closes the one that was open, so there is always one open and the panel keeps its height. The header derives the numbers from the data: how many entries, how many words in all and the longest gap between two entries. There are no band rules inside the panel, only the line. It is built from Guides and CSS, with an entrance only. For journals, diaries, notes apps and any history where weight matters more than ornament. The entries are example data.
FAQ
How do I change the entries?
Edit ENTRIES at the top of the file, newest first. Each has an ISO day on, a one-line sentence, an excerpt for the first lines and the number of words in the whole entry. The totals and the longest gap are derived from the list. Keep each excerpt to about 150 characters so every entry opens to the same height.
How do I change the dot sizes?
The four steps live in TIERS: a literal size class, a label and the fewest words that reach the step. tierOf() picks the last step an entry reaches, and the key under the line is drawn from the same list, so the key and the dots cannot disagree. Keep the classes literal so Tailwind sees them.
Why can I not close the open entry?
One entry is always open, so the panel never changes height: pressing another dot opens it and closes the previous one at the same height. If you prefer to be able to close all of them, hold openOn as a string that may be empty and reserve the height with an unseen copy.
What stays in the page?
The open entry is local state, and nothing is saved or sent. Replace the typed excerpt with the entry's text from your own store, or load it when a dot opens.
Is it accessible?
Each dot is a button with aria-expanded and a name that says the date and the words, so a screen reader hears "Read 3 October, 212 words" rather than a bare dot. The size of the dot is also written in the key and in the name, so it never depends on sight. A polite status line, hidden visually and there from load, announces which entry opened.