KQ-1495 · FLICK/NOTE
Flick Note
A toast stack you handle like cards: notes stack with depth, a new one rises in on springs.recoil while the rest step back on springs.glide, and hovering or focusing the stack fans it into a readable column on springs.snap. Any open note follows the finger 1:1 in any direction and turns like a card held off its middle; on release the throw is projected, and past the dismiss distance the note carries on at its own speed and spin out through the region's edge while the stack closes up behind it, otherwise it springs home on springs.snap with the throw's velocity. The stack is a list with one tab stop: arrows move between notes, Enter opens one, Delete dismisses it and Escape dismisses the top note.
- 2m
Build 482 passed
main is live in production
- 6m
Review requested
Ines asked you to look at PR 318
- 14m
Disk at 86%
eu-west log volume is filling
- 1h
Payout sent
1,240.00 to Waylight Pay
4 notes · hover to fan, flick to dismiss
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/flick-note
Props
- notes
- { id: string; title: string; body?: string; time?: string; tone?: "info" | "success" | "warn" | "danger" }[]
- default —
- The notes, newest first. Notes the host removes fade out; new ones arrive on the recoil spring.
- onDismiss
- (id: string, via: "flick" | "key" | "button") => void
- default —
- A note was dismissed, reported at the moment it was let go — remove it from `notes`; its exit keeps playing.
- onOpen
- (id: string) => void
- default —
- A click or Enter on a note.
- visible
- number
- default 3
- How many notes the stack shows.
- gap
- number
- default 8
- Space between fanned notes, in px; the stack's peek at rest follows it.
- distance
- number
- default 120
- How far a throw must carry to dismiss, in px (also how quickly a held note fades).
- tilt
- number
- default 0.6
- How much a held note turns with the pull, 0 to 1.
- expand
- "hover" | "always"
- default "hover"
- Fan the stack on hover and focus, or keep it fanned.
- label
- string
- default "Notifications"
- The region's accessible name.
- size
- "sm" | "md" | "lg"
- default "md"
- Note height: 48, 56 or 64px.
- sound
- boolean
- default false
- A swish as a note is thrown or keyed away (pitched by speed, panned by direction) and a pop as one seats back.
- disabled
- boolean
- default false
- No flicks, keys or close buttons.
- className
- string
- default —
- Classes for the region, which is as tall as the fanned stack so nothing jumps on hover.
| Prop | Type | Default | Description |
|---|---|---|---|
| notes | { id: string; title: string; body?: string; time?: string; tone?: "info" | "success" | "warn" | "danger" }[] | — | The notes, newest first. Notes the host removes fade out; new ones arrive on the recoil spring. |
| onDismiss | (id: string, via: "flick" | "key" | "button") => void | — | A note was dismissed, reported at the moment it was let go — remove it from `notes`; its exit keeps playing. |
| onOpen | (id: string) => void | — | A click or Enter on a note. |
| visible | number | 3 | How many notes the stack shows. |
| gap | number | 8 | Space between fanned notes, in px; the stack's peek at rest follows it. |
| distance | number | 120 | How far a throw must carry to dismiss, in px (also how quickly a held note fades). |
| tilt | number | 0.6 | How much a held note turns with the pull, 0 to 1. |
| expand | "hover" | "always" | "hover" | Fan the stack on hover and focus, or keep it fanned. |
| label | string | "Notifications" | The region's accessible name. |
| size | "sm" | "md" | "lg" | "md" | Note height: 48, 56 or 64px. |
| sound | boolean | false | A swish as a note is thrown or keyed away (pitched by speed, panned by direction) and a pop as one seats back. |
| disabled | boolean | false | No flicks, keys or close buttons. |
| className | string | — | Classes for the region, which is as tall as the fanned stack so nothing jumps on hover. |