KQ-939 · THREAD/DIGEST
Thread Digest
What moved while you were away, ordered by what moved last. Each row carries a column sparkline of when its messages landed, animated by each column's y and height on glide rather than by a path, and a thread that receives something climbs the list while every row it passes trades places on the same spring through position-only layout projection. The busiest column is tinted, a thread with nothing new dims and keeps its shape, and the list is one tab stop under a roving tabindex where Down and Up step, Home and End jump, and Enter or Space opens the focused thread.
Coldbrook yard · 4 threads moved · 23 unread
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/thread-digest
Props
- threads
- DigestThread[]
- default —
- The threads: id, name, optional preview, unread, a monotonic activity rank, and one count per bucket.
- bucketLabels
- string[]
- default —
- Names for the buckets ("6 am", "7 am"), used in the row's spoken sentence.
- onOpen
- (id: string) => void
- default —
- Fires from a row's press, and from Enter or Space on it.
- onAnnounce
- (sentence: string) => void
- default —
- Fires once per frozen change sentence, the same one the status region speaks.
- label
- string
- default —
- Names the list for assistive technology.
- heading
- string
- default "While you were away"
- The strip above the list.
- emptyLabel
- string
- default "Nothing moved"
- Drawn when there are no threads.
- maxHeight
- number
- default 280
- How tall the list grows before it scrolls inside its own box.
| Prop | Type | Default | Description |
|---|---|---|---|
| threads | DigestThread[] | — | The threads: id, name, optional preview, unread, a monotonic activity rank, and one count per bucket. |
| bucketLabels | string[] | — | Names for the buckets ("6 am", "7 am"), used in the row's spoken sentence. |
| onOpen | (id: string) => void | — | Fires from a row's press, and from Enter or Space on it. |
| onAnnounce | (sentence: string) => void | — | Fires once per frozen change sentence, the same one the status region speaks. |
| label | string | — | Names the list for assistive technology. |
| heading | string | "While you were away" | The strip above the list. |
| emptyLabel | string | "Nothing moved" | Drawn when there are no threads. |
| maxHeight | number | 280 | How tall the list grows before it scrolls inside its own box. |