KQ-1157 · RIBBON/UNFURL
Ribbon Unfurl
A banner notice on a spring roller along the top edge: the fabric drops on a spring whose bounce is the swing, the cloth sways to rest about the roller line, and a stitched leader above the message winds back in at 7px a second, so the time left is how much leader is still out. Dragged, the ribbon follows 1:1; a throw up rolls it away on an accelerating tween, a pull past full length catches a ratchet and pins it open on snap, and anything else glides back with the release velocity. ArrowUp, Delete or Escape rolls the focused ribbon away and ArrowDown pins it.
Fieldline · Crew board
Tue 14 Oct
- Crew 2Coldbrook culvertOn site
- Crew 4Basin RoadOn site
- Crew 7DepotLoading
- Crew 9Lot 9 surveyTravelling
Arrow Up or Delete rolls it away. Arrow Down keeps it open.
2 more waiting.
Crew 4 checked in at Basin Road
Shift started 06:40. Two vans on site.
Crew 4 checked in at Basin Road. Shift started 06:40. Two vans on site. 2 more waiting.
on the roller · Crew 4 checked in at Basin Road · 2 waiting
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/ribbon-unfurl
Props
- notices
- { id: string; title: string; body?: string; tone?: "info" | "success" | "warn" | "danger" }[]
- default —
- The notices, in the order they drop. One is on the roller at a time; the rest are counted beside it.
- onDismiss
- (id: string) => void
- default —
- Fires as a ribbon starts to roll away: by the hand, a key, its button, or its time running out.
- onPin
- (id: string, pinned: boolean) => void
- default —
- Fires when the visitor pins a ribbon open, or lets it go again.
- duration
- number
- default 6
- Seconds a ribbon stays down, 3 to 12. Also its leader: 7px of stitched fabric per second, capped to what fits the surface.
- swing
- number
- default 0.5
- How much the ribbon bounces and sways as it lands, 0 to 1. At 0 it drops without overshoot.
- fabric
- "satin" | "canvas" | "paper"
- default "satin"
- The cloth and its weight: light satin with a sheen and the most sway, heavy woven canvas, or stiff paper.
- label
- string
- default "Notices"
- The notice region's accessible name.
- children
- ReactNode
- default —
- The surface the roller is mounted on. The ribbon hangs over it, clipped to it.
- sound
- boolean
- default false
- Play a swish when the visitor rolls a ribbon away and a click when they pin or release it.
- disabled
- boolean
- default false
- The ribbon ignores the hand and the keys; its time still runs.
- className
- string
- default —
- Classes for the root, which is the surface's box.
| Prop | Type | Default | Description |
|---|---|---|---|
| notices | { id: string; title: string; body?: string; tone?: "info" | "success" | "warn" | "danger" }[] | — | The notices, in the order they drop. One is on the roller at a time; the rest are counted beside it. |
| onDismiss | (id: string) => void | — | Fires as a ribbon starts to roll away: by the hand, a key, its button, or its time running out. |
| onPin | (id: string, pinned: boolean) => void | — | Fires when the visitor pins a ribbon open, or lets it go again. |
| duration | number | 6 | Seconds a ribbon stays down, 3 to 12. Also its leader: 7px of stitched fabric per second, capped to what fits the surface. |
| swing | number | 0.5 | How much the ribbon bounces and sways as it lands, 0 to 1. At 0 it drops without overshoot. |
| fabric | "satin" | "canvas" | "paper" | "satin" | The cloth and its weight: light satin with a sheen and the most sway, heavy woven canvas, or stiff paper. |
| label | string | "Notices" | The notice region's accessible name. |
| children | ReactNode | — | The surface the roller is mounted on. The ribbon hangs over it, clipped to it. |
| sound | boolean | false | Play a swish when the visitor rolls a ribbon away and a click when they pin or release it. |
| disabled | boolean | false | The ribbon ignores the hand and the keys; its time still runs. |
| className | string | — | Classes for the root, which is the surface's box. |