Animated List
A real-time push feed where new items animate in from the top with spring physics — Stripe Radar style.
Installation
File Structure
animated-list.tsx
Usage
import { AnimatedList } from "@/components/unlumen-ui/animated-list";
type Item = { id: number; message: string };
const [items, setItems] = useState<Item[]>([]);
// Prepend new items to show at top:
setItems((prev) => [newItem, ...prev].slice(0, 8));
<AnimatedList
items={items}
renderItem={(item) => (
<div className="rounded-xl border p-3">{item.message}</div>
)}
/>;API Reference
AnimatedList
| Prop | Type | Default | Description |
|---|---|---|---|
items | T[] | - | Array of items. Each item must have a unique `id` (string or number). Prepend new items at index 0 for top-push behavior. |
renderItem | (item: T, index: number) => React.ReactNode | - | Render function called for each visible item. |
maxVisible? | number | 8 | Maximum number of items rendered at once. Older items are removed. |
gap? | string | "gap-3" | Tailwind gap class applied between items. |
className? | string | - | Extra classes on the list container. |
Notes
- Items must have a stable unique
idproperty (string or number) — this is required forAnimatePresenceto correctly track enter/exit animations. - Uses
AnimatePresence mode="popLayout"so exiting items don't block layout shifts. - New items enter with
y: -20 → 0andscale: 0.95 → 1on a spring; exits use a quick 150ms ease-in. - Cap your list with
maxVisibleto avoid accumulating too many DOM nodes in a live feed.
Keep in mind
Most components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.