Docs
Expanding Cards

Expanding Cards

A beautiful expanding cards component with smooth animations and hover effects.

Blonkisoaz
Omuke trughte a otufta
Oretemauw
Omuke trughte a otufta
Iteresuselle
Omuke trughte a otufta
Idiefe
Omuke trughte a otufta
Inatethi
Omuke trughte a otufta

Installation

Copy and paste the following code into your project.

components/ui/expanding-cards.tsx

"use client";
 
import * as React from "react";
import { cn } from "@/lib/utils";
 
export interface CardItem {
  id: string;
  title: string;
  subtitle: string;
  icon: React.ReactNode;
  backgroundUrl: string;
}
 
interface ExpandingCardsProps {
  items: CardItem[];
  className?: string;
}
 
export function ExpandingCards({ items, className }: ExpandingCardsProps) {
  const [activeId, setActiveId] = React.useState<string>(items[0]?.id);
 
  return (
    <div
      className={cn(
        "flex min-h-[400px] w-full min-w-[600px] max-w-[900px] items-stretch gap-2 px-4",
        className,
      )}
    >
      {items.map((item) => (
        <div
          key={item.id}
          className={cn(
            "ease-[cubic-bezier(0.05,0.61,0.41,0.95)] relative cursor-pointer overflow-hidden bg-cover bg-center transition-all duration-700",
            activeId === item.id
              ? "flex-[10_1_0%] rounded-[40px]"
              : "flex-[1_1_0%] rounded-[30px]",
          )}
          style={{
            backgroundImage: `url(${item.backgroundUrl})`,
          }}
          onClick={() => setActiveId(item.id)}
        >
          <div
            className={cn(
              "ease-[cubic-bezier(0.05,0.61,0.41,0.95)] absolute inset-x-0 bottom-0 transition-all duration-700",
              activeId === item.id
                ? "h-[120px] bg-linear-to-t from-black/80 to-transparent"
                : "h-0 bg-linear-to-t from-black/80 to-transparent opacity-0",
            )}
          />
 
          <div className="absolute bottom-0 left-0 w-full p-5">
            <div
              className={cn(
                "ease-[cubic-bezier(0.05,0.61,0.41,0.95)] flex items-center transition-all duration-700",
                activeId === item.id
                  ? "translate-x-0 opacity-100"
                  : "translate-x-5 opacity-0",
              )}
            >
              <div
                className={cn(
                  "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-white transition-all duration-700",
                  activeId === item.id
                    ? "translate-y-0 opacity-100"
                    : "-translate-y-5 opacity-0",
                )}
              >
                {item.icon}
              </div>
              <div className="ml-3 text-white">
                <div
                  className={cn(
                    "ease-[cubic-bezier(0.05,0.61,0.41,0.95)] text-lg font-bold transition-all duration-700",
                    activeId === item.id
                      ? "translate-x-0 opacity-100"
                      : "translate-x-5 opacity-0",
                  )}
                >
                  {item.title}
                </div>
                <div
                  className={cn(
                    "ease-[cubic-bezier(0.05,0.61,0.41,0.95)] text-sm text-white/80 transition-all delay-100 duration-700",
                    activeId === item.id
                      ? "translate-x-0 opacity-100"
                      : "translate-x-5 opacity-0",
                  )}
                >
                  {item.subtitle}
                </div>
              </div>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

Update the import paths to match your project setup.

import { ExpandingCards } from "@/components/ui/expanding-cards";

Usage

import { ExpandingCards } from "@/components/ui/expanding-cards";
 
const items = [
  {
    id: "1",
    title: "Title",
    subtitle: "Subtitle",
    icon: <Icon />,
    backgroundUrl: "path/to/image.jpg",
  },
  // ... more items
];
 
export function Demo() {
  return <ExpandingCards items={items} />;
}

Props

PropTypeDescriptionDefault
itemsCardItem[]Array of items to display in the cards[]
classNamestringOptional className for the container-

CardItem

PropertyTypeDescription
idstringUnique identifier for the card
titlestringTitle text to display
subtitlestringSubtitle text to display
iconReact.ReactNodeIcon component to display
backgroundUrlstringURL for the background image