Live Glance Strip
A live-activity information strip — the iOS Live Activity vocabulary brought to the web as a frosted-glass pill, with status text flipping vertically on update, a progress track advancing live, and details expanding on click.
npx shadcn@latest add https://webberui.com/r/live-glance-strip.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<LiveGlanceStrip />
Installation
npx shadcn@latest add https://webberui.com/r/live-glance-strip.jsonOr, once registries are configured in components.json, install it as @webberui/live-glance-strip.
Usage
import { LiveGlanceStrip } from "@/components/ui/live-glance-strip";
<LiveGlanceStrip
icon={<Rocket className="size-4" />}
title="Production deploy"
status="Building" // changing the value triggers the flip
progress={0.6}
position="fixed-bottom" // fixed to the bottom of the window in a real app; the docs preview uses 'inline'
>
{/* The details shown once expanded */}
<ul className="space-y-2 text-xs">
<li>Install dependencies ✓</li>
<li>Build and bundle …</li>
<li>Deploy to edge nodes</li>
</ul>
</LiveGlanceStrip>;Controlled expansion:
const [open, setOpen] = React.useState(false);
<LiveGlanceStrip
title="Production deploy"
status="Deploying"
expanded={open}
onExpandedChange={setOpen}
>
…
</LiveGlanceStrip>;Props
LiveGlanceStrip
| Prop | Type | Default | Description |
|---|---|---|---|
icon | React.ReactNode | — | Content for the left slot (usually an icon), placed inside a circular base |
title | string | — | Activity title |
status | string | — | Live status text; when the value changes, the old one flips out upward and the new one flips in from below |
progress | number | — | Progress (0–1); when provided, a thin progress track appears at the bottom and advances with a spring on change |
expanded | boolean | — | Controlled expanded state; when omitted, the component manages it internally |
onExpandedChange | (expanded: boolean) => void | — | Callback fired when the expanded state changes |
position | 'fixed-bottom' | 'inline' | 'inline' | fixed-bottom fixes it centered at the bottom of the window (z-50), which suits a real app; inline lays it out in the document flow, which suits documentation previews |
children | React.ReactNode | — | The details shown once expanded; without them the pill cannot be expanded |
className | string | — | Appended to the pill body's class |
How it works
- The Live Activity metaphor: it borrows the information hierarchy of iOS Live Activities — a glance gives you only three things (icon, title, current status) and you tap in for the whole picture; a good fit for "still in progress" activities such as deployment progress, delivery tracking, and game scores
- Status flip: when the
statusvalue changes,AnimatePresence mode="popLayout"flips the old value out upward and the new one in from below, withoverflow-hiddenon the wrapper acting as a mask, producing a small split-flap scoreboard effect - Progress track: the 2px thin track at the bottom is driven by
scaleX(origin-left+ spring), so even a jumping value advances smoothly along an elastic curve, and it carriesrole="progressbar"semantics - Expansion morph: the pill body carries a
layoutspring, so mountingchildrengrows the whole thing naturally and unmounting collapses it; the details fade in with a delay — open the box first, then serve. The inner layer is protected withlayout="position"so during the growth the content only shifts and is never stretched - Positioning:
fixed-bottomcenters it with apointer-events-nonewrapper, so only the pill body takes pointer events and it never blocks clicks elsewhere on the page - Frosted-glass texture: a translucent base color plus
backdrop-blur-xl, preserving that see-through feel in both light and dark themes - Reduce motion: when the user has "reduce motion" enabled at the system level, the flip degrades to a fade in and out and the layout morph and progress spring are disabled in favor of direct switching; the first render still matches the SSR output
- Accessibility: assistive technology hears a plain-text "title: status" announcement through an
sr-onlyrole="status"live region, and animated nodes are alwaysaria-hidden; the expansion trigger is a nativebuttoncarryingaria-expandedandaria-controls
UI Sound Kit
Lightweight interface sounds — click, hover, success, error and more — synthesized live with Web Audio, with built-in volume control, a global switch, and preference-respecting behavior; no audio files, no extra requests.
Streak Flame Counter
A Duolingo-style streak flame — the flame flares when the number goes up and changes color at milestones