KQ-877 · JOIN/TOAST
Join Toast
A card lands above the room's own content on recoil when a member joins, while the cards already there glide down through layout so the stack opens instead of reflowing. Each card drains a linear hairline timer and clears itself on the exit ease; past max the older arrivals fold into one summary line whose count rolls on snap and whose timers keep running. Pointer or focus holds every timer, Escape clears the stack, and the whole thing sits in a ResizeObserver-measured height inside the component's own box.
KQ-877 · JOIN/TOAST
- Marta Gate B is clear from nine.
- Ines Two pallets left on the Friday run.
Nobody yet · the room is quiet
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/join-toast
Props
- arrivals
- Arrival[]
- default —
- Who has joined, oldest first; { id, name, note? }. The host removes them in onDismiss.
- room
- string
- default —
- The room's name, spoken in every card's sentence.
- duration
- number
- default 4200
- Milliseconds a card stays before it clears itself; 0 or less keeps it up.
- max
- number
- default 3
- Cards shown before the older ones fold into the summary line.
- onDismiss
- (id: string, reason: "timer" | "action") => void
- default —
- Fires when a card's timer runs out or its close control is pressed.
- onClear
- () => void
- default —
- Fires when Escape clears the whole stack.
- onHoldChange
- (held: boolean) => void
- default —
- Fires as the pointer or focus enters and leaves the stack.
- children
- React.ReactNode
- default —
- The room content the stack sits above and pushes down.
| Prop | Type | Default | Description |
|---|---|---|---|
| arrivals | Arrival[] | — | Who has joined, oldest first; { id, name, note? }. The host removes them in onDismiss. |
| room | string | — | The room's name, spoken in every card's sentence. |
| duration | number | 4200 | Milliseconds a card stays before it clears itself; 0 or less keeps it up. |
| max | number | 3 | Cards shown before the older ones fold into the summary line. |
| onDismiss | (id: string, reason: "timer" | "action") => void | — | Fires when a card's timer runs out or its close control is pressed. |
| onClear | () => void | — | Fires when Escape clears the whole stack. |
| onHoldChange | (held: boolean) => void | — | Fires as the pointer or focus enters and leaves the stack. |
| children | React.ReactNode | — | The room content the stack sits above and pushes down. |