Tabs
Pestañas sobre Base UI, con indicador deslizante.
Navigation@base-ui/react
Installation
npx shadcn@latest add @saastro/tabsPreview

Source Code
"use client"
import { Tabs as TabsPrimitive } from "@base-ui/react/tabs"
import { cn } from "@/lib/utils"
function Tabs({ className, ...props }: TabsPrimitive.Root.Props) {
return (
<TabsPrimitive.Root
data-slot="tabs"
className={cn("flex flex-col gap-3", className)}
{...props}
/>
)
}
/**
* La lista lleva el indicador deslizante de Base UI: una sola pieza que se
* mueve, en vez de pintar el fondo activo en cada pestaña. Se posiciona con
* las variables que expone el propio primitivo.
*/
function TabsList({ className, children, ...props }: TabsPrimitive.List.Props) {
return (
<TabsPrimitive.List
data-slot="tabs-list"
className={cn(
"relative isolate inline-flex h-8 w-fit items-center justify-center rounded-lg bg-muted p-0.5 text-muted-foreground",
className
)}
{...props}
>
{children}
<TabsPrimitive.Indicator
data-slot="tabs-indicator"
className="absolute top-1/2 left-0 -z-10 h-[calc(100%-0.25rem)] w-(--active-tab-width) -translate-y-1/2 translate-x-(--active-tab-left) rounded-[min(var(--radius-md),8px)] bg-background shadow-sm transition-all duration-200 ease-out"
/>
</TabsPrimitive.List>
)
}
function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {
return (
<TabsPrimitive.Tab
data-slot="tabs-trigger"
className={cn(
"inline-flex h-7 flex-1 items-center justify-center gap-1.5 rounded-[min(var(--radius-md),8px)] px-2.5 text-sm font-medium whitespace-nowrap transition-colors outline-none select-none focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-active:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}
/>
)
}
function TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {
return (
<TabsPrimitive.Panel
data-slot="tabs-content"
className={cn("flex-1 outline-none", className)}
{...props}
/>
)
}
export { Tabs, TabsContent, TabsList, TabsTrigger }Registry Setup
Add the Saastro registry to your components.json:
{
"registries": {
"@saastro": "https://ui.saastro.io/r/{name}.json"
}
}