āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/directory/karthikmudunuri/eldoraui/components/animated-list ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
components/eldoraui/animated-list.tsx
import { AnimatedList } from "@/components/eldoraui/animated-list"
<div className="bg-background relative h-[400px] w-full overflow-hidden rounded-lg border">
<AnimatedList>
<div className="bg-card flex w-full max-w-[350px] items-center gap-4 rounded-2xl border p-4 shadow-sm">
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-cyan-500 text-sm font-medium text-white">
A
</div>
<div className="flex flex-1 flex-col">
<span className="text-sm font-medium">App</span>
<span className="text-muted-foreground text-sm">
Notification message
</span>
</div>
</div>
</AnimatedList>
</div>
<AnimatedList
stackGap={20}
columnGap={85}
scaleFactor={0.05}
scrollDownDuration={5}
formationDuration={1}
>
{items.map((item) => (
<div key={item.id}>{item.content}</div>
))}
</AnimatedList>
const notifications = [
{ name: "Location", message: "Thomas has arrived home", time: "2h ago" },
{ name: "Fitness", message: "Daily step goal reached!", time: "1h ago" },
{ name: "Calendar", message: "Team meeting in 30 minutes", time: "45m ago" },
// ... more notifications
]
<div className="relative h-[400px] w-full overflow-hidden rounded-lg border bg-background">
<AnimatedList
stackGap={20}
columnGap={85}
scaleFactor={0.05}
scrollDownDuration={5}
formationDuration={1}
>
{notifications.map((notification, index) => (
<div
key={index}
className="flex w-full max-w-[350px] items-center gap-4 rounded-2xl border bg-card p-4 shadow-sm"
>
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-cyan-500 text-white text-sm font-medium">
{notification.name.charAt(0)}
</div>
<div className="flex flex-1 flex-col">
<div className="flex items-center justify-between">
<span className="text-sm font-medium">{notification.name}</span>
<span className="text-xs text-muted-foreground">{notification.time}</span>
</div>
<span className="text-sm text-muted-foreground">{notification.message}</span>
</div>
</div>
))}
</AnimatedList>
</div>
| Prop | Type | Default | Description |
| -------------------- | ----------- | ------- | ------------------------------------------------- |
| children | ReactNode | - | The list items to animate |
| className | string | - | Additional CSS classes for the container |
| stackGap | number | 20 | Vertical spacing between stacked items |
| columnGap | number | 85 | Horizontal spacing between column items |
| scaleFactor | number | 0.05 | Scale difference between stacked items |
| scrollDownDuration | number | 5 | Duration for scrolling animation (seconds) |
| formationDuration | number | 1 | Duration for column formation animation (seconds) |
The component goes through four distinct animation phases:
AnimatePresence for efficient renderingā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā