Skip to content
GetUrUI

Live Activity Pill

Pro
.md

A floating status pill for live activities — idle, now playing, timer, incoming call and upload — whose dark shell springs between sizes while content crossfades through a blur.

dynamic islandioslive activitymusictimercalluploadmorphnotification

Installation

Pro installs use your private registry token. Add the @geturui-pro registry once — setup guide. The command works after you get Pro.

$npx shadcn@latest add @geturui-pro/dynamic-island

Usage

usage.tsx
1"use client";
2import * as React from "react";
3import { DynamicIsland, type IslandView } from "@/components/ui/dynamic-island";
4
5export function NowPlaying() {
6  const [view, setView] = React.useState<IslandView>("music");
7  const [playing, setPlaying] = React.useState(true);
8  return (
9    <DynamicIsland
10      view={view}
11      music={{ title: "Spring Physics", artist: "Damping Ratio", playing }}
12      timer={{ seconds: 120, label: "Tea timer" }}
13      call={{ name: "Maya Chen", initials: "MC" }}
14      upload={{ name: "release-notes.pdf", progress: 64 }}
15      onTogglePlay={() => setPlaying((p) => !p)}
16      onAcceptCall={() => setView("idle")}
17      onDeclineCall={() => setView("idle")}
18      onTimerEnd={() => setView("idle")}
19    />
20  );
21}

Props

PropTypeDefaultDescription
view*"idle" | "music" | "timer" | "call" | "upload"—Which live activity to show. Changing it morphs the shell.
music{ title: string; artist: string; playing?: boolean; coverInitials?: string }—Now-playing data. Waveform bars bounce while playing is true.
timer{ seconds: number; label?: string }—Countdown that starts each time the timer view appears.
call{ name: string; subtitle?: string; initials?: string }—Incoming caller shown with accept and decline buttons.
upload{ name: string; progress: number }—File name and 0–100 progress drawn as a ring.
expandedboolean—Music view only: show the full player. Uncontrolled (tap to toggle) when omitted.
onExpandedChange(expanded: boolean) => void—Called when the player expands or collapses.
onTogglePlay() => void—Play / pause pressed in the expanded player.
onSkip(direction: -1 | 1) => void—Previous or next track pressed.
onAcceptCall() => void—Accept pressed in the call view.
onDeclineCall() => void—Decline pressed in the call view.
onTimerEnd() => void—Fired when the countdown reaches zero.
classNamestring—Classes for the outer wrapper.

Accessibility

  • The island is a labelled region with a polite live region that announces activity changes (not every timer tick).
  • Every control is a real button with a descriptive label, e.g. "Accept call from Maya Chen"; the compact player is a button with aria-expanded.
  • With reduced motion the shell resizes with a short tween, content fades without blur and the waveform and ringing wiggle stop.
  • The shell is always black, like the hardware cutout it imitates; text and accents keep contrast in both themes.

Related