Animated List
motiq/animated-listFreeComponent
A semantic list whose items fade/slide in with a stagger and animate out cleanly on removal, with layout-based reordering. Requires stable keys. Reduced-motion safe.
Live preview
live · rendered by the registry
Rendered by motiq on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.motiq.dev/r/animated-list.jsonSource
1"use client";23import * as React from "react";4import { AnimatePresence, motion, useReducedMotion } from "motion/react";56import { cn } from "@/lib/utils";78export interface AnimatedListProps9 extends React.HTMLAttributes<HTMLUListElement> {10 /** Milliseconds of stagger applied to entering items, by DOM order. */11 stagger?: number;12}1314/**15 * AnimatedList — a semantic `<ul>` whose `<li>` children fade/slide in with a16 * stagger and animate out cleanly when removed.17 *18 * Usage: pass keyed children (each `AnimatedListItem` needs a stable `key`) so19 * AnimatePresence can track add/remove. `layout` handles reordering.20 *21 * Accessibility: it stays a real list (`<ul>`/`<li>`), so list semantics and22 * keyboard focus are preserved; exit animation does not steal focus. Under23 * `prefers-reduced-motion` items appear/leave instantly. Clean-room original.24 */25export function AnimatedList({26 stagger = 60,27 className,28 children,29 ...props30}: AnimatedListProps) {31 // Provide the stagger to items via context so index-based delay works even32 // when consumers wrap items.33 return (34 <StaggerContext.Provider value={stagger}>35 <ul className={cn("flex flex-col gap-2", className)} {...props}>36 <AnimatePresence initial={false}>{children}</AnimatePresence>37 </ul>38 </StaggerContext.Provider>39 );40}4142const StaggerContext = React.createContext<number>(60);4344export interface AnimatedListItemProps45 extends React.LiHTMLAttributes<HTMLLIElement> {46 /** Position in the list, used to stagger the entrance. */47 index?: number;48}4950export const AnimatedListItem = React.forwardRef<51 HTMLLIElement,52 AnimatedListItemProps53>(({ index = 0, className, children, ...props }, ref) => {54 const reduce = useReducedMotion();55 const stagger = React.useContext(StaggerContext);56 const delay = reduce ? 0 : (index * stagger) / 1000;5758 return (59 <motion.li60 ref={ref}61 layout={reduce ? false : "position"}62 initial={reduce ? false : { opacity: 0, y: 10 }}63 animate={{ opacity: 1, y: 0 }}64 exit={reduce ? { opacity: 0 } : { opacity: 0, y: -8, scale: 0.98 }}65 transition={{ duration: reduce ? 0 : 0.26, ease: [0.2, 0, 0, 1], delay }}66 className={cn(67 "rounded-xl border border-[var(--color-border,#e4e7ec)]",68 "bg-[var(--color-surface,#fff)] px-4 py-3 text-sm text-[var(--color-fg,#111318)]",69 "[will-change:transform,opacity]",70 className,71 )}72 {...(props as React.ComponentProps<typeof motion.li>)}73// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from motiq
All 100 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Activity Streamactivity-stream | motiq | Components | Free | 1 dep | |
| Adaptive Safe-Zone Gridadaptive-safe-zone-grid | motiq | Components | Free | no deps | |
| Agent Run Timelineagent-run-timeline | motiq | Components | Free | 1 dep | |
| AI Response Streamai-response-stream | motiq | Components | Free | 1 dep | |
| Animated Accordionanimated-accordion | motiq | Components | Free | 2 deps | |
| Animated Buttonanimated-button | motiq | Components | Free | 1 dep | |
| Animated Dialoganimated-dialog | motiq | Components | Free | 2 deps | |
| Animated Gridanimated-grid | motiq | Components | Free | 2 deps |
