Widget Stack groups glanceable widgets into one space. Swipe or scroll vertically to move between widgets, use the dots on the right to jump to a page, or focus the stack and use the arrow, Page Up, Page Down, Home, and End keys.
Preview
Installation
$ npx shadcn@latest add https://spark-ui-olive.vercel.app/r/widget-stack.json
Usage
import { WidgetStack } from "@/components/widget-stack";
import { CalendarDays, CloudSun, MapPin } from "lucide-react";export default function WidgetStackDemo() {
return (
<WidgetStack size="medium" ariaLabel="Daily widgets">
<article className="relative h-full bg-sky-500 text-white">
<div
role="img"
aria-label="Beach at sunrise"
className="h-full w-full bg-cover bg-center"
style={{ backgroundImage: "url('/images/trail-3.jpg')" }}
/>
<div className="absolute inset-x-0 bottom-0 bg-linear-to-t from-black/65 to-transparent px-4 pb-3 pt-8">
<p className="text-xs font-medium text-white/75">Photos</p>
<p className="text-sm font-semibold">Beach memories</p>
</div>
</article>
<article className="flex h-full items-center justify-between bg-linear-to-br from-sky-400 to-blue-700 p-4 text-white">
<div>
<p className="flex items-center gap-1 text-xs font-medium text-white/70">
<MapPin className="size-3" aria-hidden /> Manila
</p>
<p className="mt-1 text-5xl font-light tracking-tight">28°</p>
<p className="text-sm">Partly cloudy</p>
</div>
<CloudSun className="size-20 text-yellow-200" strokeWidth={1.25} />
</article>
</WidgetStack>
);
}Small and Medium Sizes
Both sizes support any number of child widgets and the same vertical stack interaction.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Widget pages rendered in stack order. |
size | "small" | "medium" | "small" | Square or wide widget proportion. |
defaultIndex | number | 0 | Widget page shown first. |
onIndexChange | (index: number) => void | — | Called after scrolling settles on another widget page. |
ariaLabel | string | "Widget stack" | Accessible label for the scrollable stack. |
className | string | — | Additional classes for the stack container. |
Accessibility
- The stack is keyboard focusable and supports arrow keys, Page Up, Page Down, Home, and End.
- Every page and dot announces its position within the stack.
- Dot controls are native buttons with visible focus states.
- Smooth scrolling is disabled when the user prefers reduced motion.