Design
Tabs
Animated Tab

Animated Tab

Implement a animated tab component using Next.js, Tailwind CSS, and Framer Motion.

Preview

Installation

Install dependencies

pnpm add clsx tailwind-merge framer-motion

Add util file

utils/cn.ts
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
 
export function cn(...inputs: ClassValue[]): string {
  return twMerge(clsx(inputs));
}

Copy the source code

components/ui/animatedTab.tsx
"use client";
 
import { motion } from "framer-motion";
import React, { useState } from "react";
import { cn } from "@/util/cn";
 
interface AnimatedTabProps {
  tabs: { id: string; label: string }[];
}
 
function AnimatedTab({ tabs }: AnimatedTabProps): React.JSX.Element {
  const [activeTab, setActiveTab] = useState(tabs[0].id);
 
  return (
    <div className="flex space-x-1">
      {tabs.map((tab) => (
        <button
        type="button"
          key={tab.id}
          onClick={() => {
            setActiveTab(tab.id);
          }}
          className={cn(
            activeTab === tab.id ? "" : "hover:text-white/60",
            "relative rounded-full px-3 py-1.5 text-sm font-medium text-white transition focus-visible:outline-2",
          )}
          style={{
            WebkitTapHighlightColor: "transparent",
          }}
        >
          {activeTab === tab.id && (
            <motion.span
              layoutId="bubble"
              className="absolute inset-0 z-10 bg-white mix-blend-difference"
              style={{ borderRadius: 9999 }}
              transition={{ type: "spring", bounce: 0.2, duration: 0.6 }}
            />
          )}
          {tab.label}
        </button>
      ))}
    </div>
  );
}
 
export default AnimatedTab;

Use the component

import { AnimatedTab } from "@/components/ui/animatedTab";
 
export function AnimatedTabDemo(): React.JSX.Element {
  const tabsData = [
    { id: "home", label: "Home" },
    { id: "about", label: "About" },
    { id: "blogs", label: "Blogs" },
    { id: "carrer", label: "Carrer" },
    { id: "docs", label: "Documentation" },
  ];
 
  return (
    <div>
      <AnimatedTab tabs={tabsData} />
    </div>
  );
}
 

File Structure of the project

        • animatedTab.tsx
      • cn.ts