NEW
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
Learn more
Skip to content
Docs

Transition List

This is a list where items are removed with smooth transition.

Loading...

Installation

CLI

pnpm dlx shadcn@latest add https://animata.design/r/list/transition-list.json

Manual

Install dependencies

npm install motion

Run the following command

It will create a new file called transition-list.tsx inside the components/animata/list directory.

mkdir -p components/animata/list && touch components/animata/list/transition-list.tsx

Paste the code

Open the newly created file and paste the following code:

import { AnimatePresence, motion } from "motion/react";
import { type ReactNode, useEffect, useState } from "react";
 
import { cn } from "@/lib/utils";
 
const Icon = ({ children, className }: { children: string; className?: string }) => (
  <div className={cn("font-mono text-xl font-bold", className)}>{children}</div>
);
 
interface Item {
  id: string;
  icon: ReactNode;
  name: string;
  type: string;
  amount: number;
}
 
const itemListDefault: Item[] = [
  {
    id: "Item-001",
    icon: <Icon className="text-red-500">N</Icon>,
    name: "Netflix",
    type: "Entertainment",
    amount: 13.2,
  },
  {
    id: "Item-002",
    icon: <Icon className="text-blue-500">G</Icon>,
    name: "Google",
    type: "Advertising",
    amount: 18.9,
  },
  {
    id: "Item-003",
    icon: <Icon className="text-red-500">Y</Icon>,
    name: "YouTube",
    type: "Entertainment",
    amount: 23.5,
  },
  {
    id: "Item-004",
    icon: <Icon className="text-green-500">S</Icon>,
    name: "Shopify",
    type: "Advertising",
    amount: 162.0,
  },
  {
    id: "Item-005",
    icon: <Icon className="text-white">A</Icon>,
    name: "Apple",
    type: "Devices",
    amount: 14.87,
  },
];
 
const TransitionList = ({ itemList }: { itemList?: Item[] }) => {
  const [list, setList] = useState<Item[]>(itemList || itemListDefault);
 
  useEffect(() => {
    if (!list.length) {
      return;
    }
 
    const timeouts = setTimeout(() => {
      setList((prev) => prev.slice(1));
    }, 2500);
 
    return () => {
      clearTimeout(timeouts);
    };
  }, [list]);
 
  return (
    <div className="h-36 w-full min-w-96 overflow-hidden rounded-lg bg-secondary">
      <AnimatePresence>
        {list.map((item) => (
          <motion.div
            key={item.id}
            animate={{ height: "3rem", scale: 1 }}
            exit={{ height: 0, scale: 0, margin: 0 }}
            transition={{ duration: 0.5 }}
            className="m-2 flex h-12 items-center rounded-lg border border-gray-400 bg-primary/5 text-secondary-foreground"
          >
            <div className="ml-4 w-8">{item.icon}</div>
            <div className="flex flex-1 justify-between px-4">
              <div>{item.name}</div>
              <div>{item.type}</div>
              <div>{item.amount}</div>
            </div>
          </motion.div>
        ))}
      </AnimatePresence>
    </div>
  );
};
 
export default TransitionList;

Credits

Built by Sanjaya Acharya

yevhenyurchuk.com