Animations

Dynamic Island

Pronew

A pill that springs between sizes, with its own content for each: status, alerts and live activity at the top of a screen.

Deploying0:42

Installation

npx shadcn@latest add @blank-pro/dynamic-island

Needs 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:

PropTypeDefault
size"default" | "compact" | "large" | "tall" | string—
defaultSizestring"default"
onSizeChange(size: string) => void—
presetsRecord<string, { width, height, radius }>—
transitionTransition{ type: "spring", stiffness: 400, damping: 32 }

The built-in sizes, in px:

SizeWidthHeightRadius
default1283618
compact2403618
large3607638
tall36019640

DynamicIslandView

Takes motion div props, plus:

PropTypeDefault
sizestring | 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.