KQ-1155 · ISLAND/PILL
Island Pill
A black island at the top edge of a screen that carries the live activity — a timer, an upload, a call — and is where notices arrive. Its width, height and corner radius each ride their own spring from one stiffness (the width leads, the height follows, the radius lags) and the body thins while the width travels fast, so it morphs like liquid rather than resizing; a notice grows it into a banner, a tap into a full card with the activity's actions and the notices, and a long press buds the actions off its bottom as droplets joined by metaball necks that pinch on springs.snap. Enter opens the card and focus follows it in, Escape or Shrink brings it back, and Shift+F10 or the menu key opens the quick actions as a menu the arrow keys move through.
Tempo run
Fieldline · today
6 × 800 m at 4:05 per km, 90 s jog between
- 14:08
- 24:06
- 34:03
- 44:02
Press to open. Press and hold, or press Shift+F10, for quick actions.
timer running · 12:47 · 2 notices
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/island-pill
Props
- notices
- IslandPillNotice[]
- default —
- Notices waiting in the island, oldest first: { id, title, body?, tone? }. A new one arrives as a banner.
- onDismiss
- (id: string) => void
- default —
- A notice was dismissed from the open card: its ×, or Delete.
- state
- "timer" | "upload" | "call"
- default "timer"
- The live activity the island carries. Changing it morphs the island.
- timer
- { label: string; seconds: number; paused?: boolean }
- default —
- The timer's label and the seconds on it; the host advances it.
- upload
- { name: string; progress: number; paused?: boolean }
- default —
- The file going up and its progress, 0 to 1.
- call
- { caller: string; detail?: string; connected?: boolean }
- default —
- The caller; once connected the call offers End instead of Decline and Answer.
- onAction
- (action: IslandPillAction) => void
- default —
- An action chosen from the open card or the quick actions: pause, resume, lap, stop, cancel, decline, answer or end.
- expand
- boolean
- default false
- Open as the full card. A new value opens or closes the island the way a tap does; taps, outside presses and Escape change it too.
- onExpandChange
- (open: boolean) => void
- default —
- The visitor opened or closed the card.
- stiffness
- number
- default 380
- How stiff the liquid is, 200 to 600: slow and wobbly, or quick and firm.
- glow
- number
- default 0.5
- The halo in the live activity's colour, 0 to 1; it flares when a notice arrives.
- label
- string
- default "Live activity"
- The island's accessible name.
- children
- ReactNode
- default —
- The screen the island floats over.
- sound
- boolean
- default false
- Play the morphs and the actions.
- disabled
- boolean
- default false
- Closes the island and takes no presses.
- className
- string
- default —
- Classes for the screen box the island hangs in.
| Prop | Type | Default | Description |
|---|---|---|---|
| notices | IslandPillNotice[] | — | Notices waiting in the island, oldest first: { id, title, body?, tone? }. A new one arrives as a banner. |
| onDismiss | (id: string) => void | — | A notice was dismissed from the open card: its ×, or Delete. |
| state | "timer" | "upload" | "call" | "timer" | The live activity the island carries. Changing it morphs the island. |
| timer | { label: string; seconds: number; paused?: boolean } | — | The timer's label and the seconds on it; the host advances it. |
| upload | { name: string; progress: number; paused?: boolean } | — | The file going up and its progress, 0 to 1. |
| call | { caller: string; detail?: string; connected?: boolean } | — | The caller; once connected the call offers End instead of Decline and Answer. |
| onAction | (action: IslandPillAction) => void | — | An action chosen from the open card or the quick actions: pause, resume, lap, stop, cancel, decline, answer or end. |
| expand | boolean | false | Open as the full card. A new value opens or closes the island the way a tap does; taps, outside presses and Escape change it too. |
| onExpandChange | (open: boolean) => void | — | The visitor opened or closed the card. |
| stiffness | number | 380 | How stiff the liquid is, 200 to 600: slow and wobbly, or quick and firm. |
| glow | number | 0.5 | The halo in the live activity's colour, 0 to 1; it flares when a notice arrives. |
| label | string | "Live activity" | The island's accessible name. |
| children | ReactNode | — | The screen the island floats over. |
| sound | boolean | false | Play the morphs and the actions. |
| disabled | boolean | false | Closes the island and takes no presses. |
| className | string | — | Classes for the screen box the island hangs in. |