KQ-1778 · LIVE/CHATTER

Live Chatter

A live event chat that holds still while you read: while nothing holds it, the log's scroll chases the newest row on a spring derived from springs.glide whose stiffness scales with scrollSpeed², keeping its velocity across arrivals so a burst reads as one climb. Hovering, keyboard focus, Space or scrolling up freezes it in place while a pill rises on springs.snap counting the messages below the fold with rolling digits; choosing the pill or pressing End fast-forwards on a stiff glide under a brief vertical blur and draws the newest row's edge on springs.flick. Up and Down walk the rows, Space pauses and resumes, Tab reaches each row's Report, and slow mode, mutes and a dropped connection show in the composer and the log.

KQ-1778 · LIVE/CHATTER

Coldbrook all-hands

Q4 roadmap · 1,284 watching

Live

Up and Down move between messages and hold the chat still. Space pauses and resumes. End jumps to the latest message and goes live.

  1. HostInes Marlow: Welcome in, everyone. We start in two minutes., 17:00

  2. Tomas Brandt: Morning from the Basin office, 17:00

  3. Priya Raman: Audio is clear here, 17:00

  4. ModeratorKenji Ito: Questions for the panel go in the Q&A tab. Chat is for chatter., 17:00

  5. Lena Okafor: hi from the night shift, 17:00

  6. Dario Silva: Is this being recorded?, 17:00

  7. ModeratorKenji Ito: Yes, the recording goes up tomorrow., 17:00

  8. Hana Sato: the new office plants are thriving, 17:00

  9. HostInes Marlow: And we're live. First up: the Q4 roadmap., 17:00

  10. SpeakerRafi Okafor: Thanks Ines. Three things this quarter., 17:00

  11. Malia Fern: here we go, 17:01

  12. Joel Park: three things, writing them down, 17:01

  13. SpeakerRafi Okafor: One: offline mode ships to everyone in November., 17:01

  14. Tomas Brandt: finally, 17:01

  15. StaffSana Idris: Offline beta notes are pinned in #roadmap, 17:01

  16. Dario Silva: @Mara you called it, 17:01

  17. Lena Okafor: does that include the tablet app, 17:01

  18. ModeratorKenji Ito: Lena, drop it in Q&A so the panel sees it, 17:01

  19. SpeakerRafi Okafor: Two: shared boards get comments., 17:01

  20. Hana Sato: comments on boards, yes please, 17:01

  21. Joel Park: two of three, 17:01

live · 21 messages · 1,284 watching

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/live-chatter

Props

messages
LiveChatterMessage[]
default defaultLiveChatterMessages
The stream so far, oldest first: { id, author, text, at, badges?: ("host" | "mod" | "speaker" | "staff")[], kind?: "message" | "gap", missed?, until? }. The host appends; the chat follows.
title
string
default "Coldbrook all-hands"
The broadcast's name in the header; also names the log.
subtitle
string
default "Q4 roadmap"
A short line under the title, before the viewer count.
viewers
number
default 1284
How many people are watching, grouped by hand so server and browser agree.
connection
"live" | "reconnecting" | "offline"
default "live"
Anything but live tears the log's tail with a "Connection lost" edge and holds sending with a reason in the composer.
paused / defaultPaused
boolean
default — / false
The explicit pause (Space), controlled or initial. Hover, keyboard focus and scrolling up still hold on top of it.
onPause
(paused, reason) => void
default —
The stream started or stopped holding still; reason is "hover", "focus", "key", "scroll", "pill" or "send".
onSend
(text) => void
default —
A message was sent from the composer (Enter). Append it to messages to show it; the log goes live to see it land.
onReport
(message) => void
default —
A message was reported through its row's confirm; it is already hidden for this viewer.
slowMode
number
default 0
Seconds between messages from one viewer. Shows a header chip, and after a send a ring on Send that empties over the cooldown.
muted / mutedUntil / mutedReason
boolean / number / string
default false
Replaces the composer with a calm notice: until when (ms since the epoch) and why.
viewerName
string
default "Mara Quinn"
Messages that @mention the viewer's first name get an accent wash.
now
number
default defaultLiveChatterNow
The current moment in ms since the epoch, for the connection-lost stamp. Never read from the clock during render.
scrollSpeed
number
default 1
How briskly the log follows new rows: the follow spring's stiffness scales with its square (0.5 drifts, 2 ticks).
density
"compact" | "regular" | "roomy"
default "regular"
One tight line per row at 12px, a coloured dot before each name, or an initial avatar with the name and time over the message.
accent
string
default "var(--accent-bright)"
Pill, Send, Host badge, mention wash and the newest-row edge — any CSS colour; fills take its hue at a fixed lightness.
maxRows
number
default 80
Rows kept in the DOM while live; a hold keeps up to three times as many so nothing you are reading is trimmed.
maxLength
number
default 200
Characters a message may hold; a counter shows past 80%.
formatTime
(ms) => string
default UTC HH:MM
How times are printed on rows, the mute notice and the connection stamp.
status / onRetry
"ready" | "loading" | "error" / () => void
default "ready"
Loading shows skeleton rows; error shows a message and Try again, which calls onRetry.
height
number
default 540
The surface's height in px; the log scrolls inside it.
disabled
boolean
default false
Read only: no composer and no reporting; the log still reads and pauses.
className
string
default —
Classes for the outer section.