Oblivion
Oblivion
Docs
Go back
Component by
OV
Oblivion
TSX
fluid-tabs
"use client"

import { useState } from "react"
import { motion, AnimatePresence } from "framer-motion"

export const componentMeta = {
  name: "Fluid Tabs",
  description: "A segmented control where the active state background fluidly slides between options.",
  props: {}
}

const tabs = ["Overview", "Integrations", "Activity", "Settings"]

export default function FluidTabs() {
  const [activeTab, setActiveTab] = useState(tabs[0])

  return (
    <div className="flex space-x-1 p-1 rounded-full bg-white dark:bg-zinc-900 border border-black/5 dark:border-white/5 shadow-sm w-fit mx-auto">
      {tabs.map((tab) => (
        <button
          key={tab}
          onClick={() => setActiveTab(tab)}
          className={`relative rounded-full px-5 py-2 text-sm font-medium transition-colors focus-visible:outline-2 ${
            activeTab === tab 
              ? "text-neutral-900 dark:text-white" 
              : "text-neutral-500 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-white"
          }`}
        >
          {activeTab === tab && (
            <motion.div
              layoutId="active-tab"
              className="absolute inset-0 bg-neutral-100 dark:bg-zinc-800 rounded-full"
              transition={{ type: "spring", bounce: 0.2, duration: 0.6 }}
            />
          )}
          <span className="relative z-10">{tab}</span>
        </button>
      ))}
    </div>
  )
}
Save to favoritesCopy to Figma
React

Fluid Tabs

A segmented control where the active state background fluidly slides between options.

Installation

$ npx @cosmoo/oblivion add fluid-tabs
Dependenciesnpm install framer-motion

Usage Example

tsx
import FluidTabs from "@/components/oblivion/fluid-tabs"

export default function Demo() {
  return (
    <div className="p-10 flex justify-center">
      <FluidTabs />
    </div>
  )
}