Dynamic Island
PronewA pill that springs between sizes, with its own content for each: status, alerts and live activity at the top of a screen.
Installation
npx shadcn@latest add @blank-pro/dynamic-islandNeeds a Blank Pro licence key and the @blank-pro registry. Set up Pro access
Usage
import {
DynamicIsland,
DynamicIslandView,
} from "@/components/ui/dynamic-island"<DynamicIsland size={size} onSizeChange={setSize}>
<DynamicIslandView size="compact">…</DynamicIslandView>
<DynamicIslandView size="large">…</DynamicIslandView>
<DynamicIslandView size="tall">…</DynamicIslandView>
</DynamicIsland>The island's surface springs to the active size's width, height and corner
radius. Each DynamicIslandView names the size, or sizes, it belongs to; only
the matching view is mounted. A view lays its content out at its own size from
the first frame and is clipped by the growing surface, so nothing reflows
while the spring runs — the outgoing view blurs away and the incoming one blurs
in.
The surface uses the device and overlay-foreground tokens: near-black glass
with light ink in both themes, like the hardware it imitates. It never grows
wider than its container.
With prefers-reduced-motion, sizes change instantly and views cross-fade.
Examples
Interactive
Leave size uncontrolled and change it from inside a view with
useDynamicIsland(). presets adds sizes of your own — here expanded.
API Reference
DynamicIsland
Takes every div prop for its root, plus:
| Prop | Type | Default |
|---|---|---|
size | "default" | "compact" | "large" | "tall" | string | — |
defaultSize | string | "default" |
onSizeChange | (size: string) => void | — |
presets | Record<string, { width, height, radius }> | — |
transition | Transition | { type: "spring", stiffness: 400, damping: 32 } |
The built-in sizes, in px:
| Size | Width | Height | Radius |
|---|---|---|---|
default | 128 | 36 | 18 |
compact | 240 | 36 | 18 |
large | 360 | 76 | 38 |
tall | 360 | 196 | 40 |
DynamicIslandView
Takes motion div props, plus:
| Prop | Type | Default |
|---|---|---|
size | string | string[] | — |
A view that is leaving is marked inert and aria-hidden until it is gone.
useDynamicIsland
Returns { size, setSize } for the nearest island.
The root carries data-size, so siblings can follow the island with
group-data-[size=tall]: selectors.