/Navigation
Navigation • React
Sliding Underline Tabs
A compact tab switcher with an orange underline that glides between labels.
Content one
Installation
Terminal
npx shadcn@latest add https://microkit.co/r/sliding-underline-tabs.jsonCode
1"use client";23import { useState } from "react";45const tabs = [6{ label: "Audience", content: "Content one" },7{ label: "Reactions", content: "Content two" },8{ label: "Saved", content: "Content three" },9];1011export function SlidingUnderlineTabs() {12const [active, setActive] = useState(0);13const activeTab = tabs[active];1415return (16<>17<style>{"@keyframes underline-tabs-enter { from { opacity: 0; transform: translateX(-5px); } to { opacity: 1; transform: translateX(0); } }"}</style>18<section className="w-full max-w-[248px] rounded-[10px] border border-[#30343a] bg-[#101216] p-[5px]">19<div className="relative grid grid-cols-3 border-b border-[#30343a]" role="tablist" aria-label="Activity">20{tabs.map(({ label }, index) => (21<button22key={label}23id={`underline-tab-${index}`}24type="button"25role="tab"26aria-selected={active === index}27className={`relative z-10 cursor-pointer border-0 bg-transparent px-1 py-[9px] text-[10px] transition-colors duration-300 ease-[cubic-bezier(.16,1,.3,1)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[#f97316] motion-reduce:transition-none ${active === index ? "text-white" : "text-[#858c96]"}`}28onClick={() => setActive(index)}29>30{label}31</button>32))}33<span34className="pointer-events-none absolute bottom-[-2px] left-1 h-[3px] w-[calc(33.333333%_-_8px)] rounded-full bg-[#f97316] transition-transform duration-[750ms] ease-[cubic-bezier(.22,1,.36,1)] motion-reduce:transition-none"35style={{ transform: `translateX(calc(${active * 100}% + ${active * 8}px))` }}36aria-hidden="true"37/>38</div>39<div key={active} className="grid min-h-[54px] place-content-center px-2 pb-1.5 pt-2.5 text-center text-[11px] text-[#f4f5f7] [animation:underline-tabs-enter_.65s_cubic-bezier(.22,1,.36,1)] motion-reduce:animate-none">40<span>{activeTab.content}</span>41</div>42</section>43</>44);45}