Notification Stack
InteractiveAn iOS-lockscreen notification pile: cards stack behind the top one with a slight y-offset and scale falloff, new items spring in from the top and dismissed ones swipe/fade out, and tapping the top card fans the stack into a full list and back. Under prefers-reduced-motion it degrades to a plain, static, fully-legible list with no stack transforms, drag, or springs.
Inspired by Cult Pro — notification system (pattern) — independently built, not affiliated. Attribution policy
Tap the top card to expand
Installation
npx shadcn@latest add https://parable-three.vercel.app/r/notification-stack.jsonRuns the shadcn CLI — the component source is copied intocomponents/parable/notification-stack.tsx. You own it from there.
Usage
The exact code rendering the preview above.
<div className="flex w-full max-w-sm flex-col gap-3 px-4">
<NotificationStack
items={[
{
id: "1",
title: "Aria Chen",
body: "Sent you the Q3 deck — take a look when you get a sec.",
icon: <MessageCircle />,
},
{
id: "2",
title: "Payment received",
body: "$4,200.00 from Northwind Studios",
icon: <CreditCard />,
},
{
id: "3",
title: "Deploy succeeded",
body: "parable-web · production · 42s",
icon: <Rocket />,
},
{
id: "4",
title: "3 new followers",
body: "and 12 others liked your post",
icon: <Heart />,
},
]}
/>
<p className="text-center text-xs text-white/40">Tap the top card to expand</p>
</div>Props
NotificationStackProps extends Omit< React.HTMLAttributes<HTMLDivElement>, | "children" | "onDrag" | "onDragStart" | "onDragEnd" | "onAnimationStart" | "onAnimationEnd" | "onAnimationIteration" >
| Prop | Type | Default | Description |
|---|---|---|---|
| items* | NotificationItem[] | — | The pile, newest first. Fully controlled — render whatever you keep in state. |
| onDismiss | (id: string) => void | — | Fires with the dismissed `id` (tap the ✕, or swipe the card sideways). |
| collapsedCount | number | 3 | How many cards peek in the collapsed stack before the rest are hidden. |
| accent | string | "#8b5cf6" | Accent for the icon tint, count pill, and focus ring. Mirrors `--pb-violet`. |
npm dependencies
- motion