All Taste components
Micro-interactions
Sliding tabs
Tabs whose highlight glides to the one you pick, with the panel below fading in to match.
segmented · underline · panels
Checkout redesign3 screens in review, due Friday.
12 updates todayAsha approved the payment step.
5 peopleAsha, Dev, Meera, Kabir and you.
"use client";
import { useState } from "react";
import { cn } from "@/lib/utils";
interface SlidingTabsProps {
tabs: { id: string; label: string; content?: React.ReactNode }[];
variant?: "segmented" | "underline";
label: string;
}
export function SlidingTabs({ tabs, variant = "segmented", label }: SlidingTabsProps) {
const [active, setActive] = useState(0);
const seg = variant === "segmented";
const width = seg ? "calc((100% - 6px) / " + tabs.length + ")" : 100 / tabs.length + "%";
return (
<div className="grid w-full max-w-[300px] gap-3.5">
<div
role="tablist"
aria-label={label}
className={cn("relative isolate grid auto-cols-fr grid-flow-col", seg ? "rounded-lg bg-surface-2 p-[3px]" : "border-b border-border")}
>
{tabs.map((t, i) => (
<button
key={t.id}
type="button"
role="tab"
id={t.id + "-tab"}
aria-controls={t.id + "-panel"}
aria-selected={i === active}
onClick={() => setActive(i)}
className={cn(
"relative z-10 font-medium transition-colors motion-reduce:transition-none",
seg ? "h-8 rounded text-[13px]" : "h-[38px] text-[13.5px]",
i === active ? "text-fg" : "text-fg-muted hover:text-fg",
)}
>
{t.label}
</button>
))}
<span
aria-hidden
className={cn(
"absolute transition-transform duration-500 ease-spring motion-reduce:transition-none",
seg ? "inset-y-[3px] left-[3px] rounded bg-bg shadow-sm" : "-bottom-px left-0 h-0.5 rounded-sm bg-primary",
)}
style={{ width, transform: "translateX(" + active * 100 + "%)" }}
/>
</div>
{tabs[active].content && (
<div key={active} role="tabpanel" id={tabs[active].id + "-panel"} aria-labelledby={tabs[active].id + "-tab"} className="animate-fade text-[13.5px] text-fg-muted motion-reduce:animate-none">
{tabs[active].content}
</div>
)}
</div>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.