Dynamic Island
Adaptive notification and status hub that morphs between collapsed, expanded, and panel states.
Incoming Call
A ready-made call UI — dot, activity bar, and full panel with Decline/Answer, all driven by props. No local state, no custom markup.
Tap the island to cycle Dot → Bar → Panel
Now Playing / Music
Pass a track and playback state — the preset renders the collapsed icon, the activity-bar mini player, and the full panel with progress and controls.
Tap the island to cycle Dot → Bar → Panel
Timer / Stopwatch
A self-running countdown or count-up timer with real Pause/Resume and Restart controls, and a distinct completed state. Fires onComplete when a countdown reaches zero.
Tap the island, then Pause/Restart in the panel — this is a real, running kitchen timer
Order / Delivery Tracker
Step through delivery stages. The panel lists every stage with progress dots and a "Next stage" action.
Tap the island, then "Next stage" in the panel
Notification Stack
Badge count on the collapsed dot, first notification on the activity bar, full grouped list in the panel.
Tap the island to cycle Dot → Bar → Panel
Charging
Battery percentage with a live progress ring, a time-to-full estimate, and a real low-battery state — the accent switches to danger under 20% while unplugged, the same convention as the OS battery indicator.
Tap the island to cycle · click here to unplug (watch it go amber under 20%)
Voice Recording
A running mm:ss counter with a live waveform, plus Pause and Save so a take can be paused and kept — not just stopped and lost.
Tap the island, then Pause/Save/Stop in the panel — the waveform freezes on pause
Focus / Do Not Disturb
A focus-mode toggle. The panel shows current status and an on/off action.
Tap the island, then toggle it on/off in the panel
Alarm
An alarm-ringing state with repeat days shown under the time, a snooze counter that persists across taps, and Snooze/Dismiss actions in the panel.
Tap the island, then Snooze a few times — the count actually persists
Ride Share
Driver, car, and a live-counting ETA for a ride in progress, plus a trip progress bar, fare, and a Message action alongside Call — the kind of live activity a real rideshare app would push.
The ETA counts down and the trip bar fills in — like a real ride in progress
Live Score
A compact score line on the activity bar, a full scoreboard with team badges and a pulsing LIVE indicator in the panel — the leading team's badge fills in solid, just like a real live-score push.
The score occasionally ticks up on its own, like a real live-game push
Uploading
A file upload with a live progress ring, and a status swap (uploading → success/error) that reflows the panel automatically. Fixed: the live preview here was staying stuck in 'uploading' forever even at 100% — because status is a prop you own, not something the component flips on its own — so it looked frozen with nothing happening. The preview now flips itself to 'success' once progress completes, and that's the pattern to copy in your own code below.
quarterly-report.pdf
Uploading · %
Tap the island to cycle · click here to bump progress
Downloading
A file download with speed label and Pause/Resume. It now also has a real completed state built in — once progress reaches 100% it swaps to a checkmark and 'Saved to Downloads' on its own, instead of just sitting at a full progress bar forever.
Downloads on its own — watch it flip to a checkmark at 100%
AI Processing
For long-running AI work — summarizing, transcribing, generating. Supports a determinate progress bar or an indeterminate shimmer when you don't have a percentage yet. Fixed: a longer stageText line was wrapping in the real panel but the hidden measurer sized the box for one line, so the wrapped part got clipped by the island's own overflow — this is why the panel could look empty. The measurer now wraps identically to the real render.
Generating summary
Reading transcript and cross-referencing prior notes · step 2 of 3
Tap the island to cycle Dot → Bar → Panel
Custom — Build Your Own
Every demo above is a preset — this is the primitive underneath. DynamicIsland itself takes plain `collapsedContent` / `expandedContent` / `panelContent` and a `state` you own (it doesn't cycle itself), so you can build activities the presets don't cover. Here's a water-intake tracker built from scratch, entirely with theme tokens.
Built from the raw DynamicIsland primitive — its own useState, its own markup
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
state | 'collapsed' | 'expanded' | 'panel' | — | Controlled state. Every preset manages this internally by default — pass `state` yourself only if you need to drive it externally. |
defaultState | 'collapsed' | 'expanded' | 'panel' | 'collapsed' | Initial state for uncontrolled presets. |
onStateChange | (state) => void | — | Fires whenever the island cycles, controlled or not. |
cycleOnClick | boolean | true | Whether tapping the island advances collapsed → expanded → panel. Set false to fully drive state yourself. |
color | string | — | Accent color used for the icon badge, glow, and progress indicators across all three states. |
size | 'sm' | 'md' | 'lg' | 'md' | Scales icon size, badge size, and type across the preset. |
renderCollapsed / renderExpanded / renderPanel | (ctx: { state, color }) => ReactNode | — | Full override for any one state's content — drop in your own markup without losing the island's shape animation. |
position | 'top' | 'inline' | 'top' | 'top' fixes to the top of viewport; 'inline' renders in flow. |
sizes | Partial<Record<state, Partial<{ width, height, radius }>>> | — | Override the exact width/height/radius for one or more states. Heights default to 'auto' for expanded/panel so the island always hugs its real content instead of a fixed box. |
glow / glowPulse | boolean | true / false | Ambient color glow behind the glass, and whether it gently breathes at rest. |