{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tabs",
  "type": "registry:ui",
  "title": "Tabs",
  "description": "Tabs on Base UI with a raised thumb or a line underline that springs to the active tab, optional count badges, vertical orientation and roving keyboard focus.",
  "dependencies": [
    "@base-ui/react",
    "class-variance-authority",
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/ui/tabs.tsx",
      "type": "registry:ui",
      "target": "components/ui/tabs.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { motion, useReducedMotion } from \"motion/react\"\nimport { cn } from \"@/lib/utils\"\n\n/**\n * Tabs - a raised thumb or accent underline that glides to the active tab.\n * Base UI for roving focus and panels. The active tab carries one\n * indicator per list (a raised thumb, or a 2px accent underline for `line`)\n * that glides between tabs on a spring, the way segmented-control does.\n */\n\ntype Variant = \"default\" | \"line\"\n\nconst ListContext = React.createContext<{ variant: Variant; layoutId: string }>({ variant: \"default\", layoutId: \"tabs\" })\n\ntype TabsProps = TabsPrimitive.Root.Props\n\nfunction Tabs({ className, orientation = \"horizontal\", ...props }: TabsProps) {\n  return (\n    <TabsPrimitive.Root\n      data-slot=\"tabs\"\n      data-orientation={orientation}\n      orientation={orientation}\n      className={cn(\"group/tabs flex gap-2 data-horizontal:flex-col\", className)}\n      {...props}\n    />\n  )\n}\n\nconst tabsListVariants = cva(\n  \"group/tabs-list relative isolate inline-flex w-fit items-center justify-center text-fg-muted group-data-horizontal/tabs:h-9 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col group-data-vertical/tabs:items-stretch\",\n  {\n    variants: {\n      variant: {\n        default: \"rounded-lg bg-sunken p-0.5 shadow-[inset_0_0_0_1px_var(--border)]\",\n        line: \"gap-4 rounded-none border-b border-border bg-transparent group-data-vertical/tabs:gap-0.5 group-data-vertical/tabs:border-r group-data-vertical/tabs:border-b-0\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\ntype TabsListProps = TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>\n\nfunction TabsList({ className, variant = \"default\", ...props }: TabsListProps) {\n  const layoutId = React.useId()\n  const v = variant ?? \"default\"\n  const ctx = React.useMemo(() => ({ variant: v, layoutId }), [v, layoutId])\n  return (\n    <ListContext.Provider value={ctx}>\n      <TabsPrimitive.List\n        data-slot=\"tabs-list\"\n        data-variant={v}\n        className={cn(tabsListVariants({ variant: v }), className)}\n        {...props}\n      />\n    </ListContext.Provider>\n  )\n}\n\nconst THUMB = \"absolute inset-0 -z-10 rounded-[inherit] bg-raised shadow-key\"\nconst UNDERLINE =\n  \"absolute -z-10 rounded-full bg-accent group-data-horizontal/tabs:inset-x-0 group-data-horizontal/tabs:-bottom-px group-data-horizontal/tabs:h-0.5 group-data-vertical/tabs:inset-y-1 group-data-vertical/tabs:-right-px group-data-vertical/tabs:w-0.5\"\n\ntype TabsTriggerProps = TabsPrimitive.Tab.Props & {\n  /** Short trailing detail, e.g. a count. */\n  badge?: React.ReactNode\n}\n\nfunction TabsTrigger({ className, badge, children, ...props }: TabsTriggerProps) {\n  const { variant, layoutId } = React.useContext(ListContext)\n  const reduce = useReducedMotion()\n  const line = variant === \"line\"\n  return (\n    <TabsPrimitive.Tab\n      data-slot=\"tabs-trigger\"\n      className={cn(\n        \"group/tab relative inline-flex h-full flex-1 cursor-pointer items-center justify-center gap-1.5 text-[0.8125rem] font-medium whitespace-nowrap outline-none select-none\",\n        \"transition-[color] duration-[70ms] ease-hairline\",\n        \"text-fg-muted hover:text-fg data-active:text-fg\",\n        \"disabled:cursor-not-allowed disabled:opacity-45 data-disabled:cursor-not-allowed data-disabled:opacity-45\",\n        \"group-data-vertical/tabs:w-full group-data-vertical/tabs:flex-none group-data-vertical/tabs:justify-start\",\n        \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        line\n          ? \"flex-none rounded-md px-1 focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg group-data-vertical/tabs:h-8 group-data-vertical/tabs:px-2.5\"\n          : \"rounded-md px-3 focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-sunken group-data-vertical/tabs:h-8\",\n        className\n      )}\n      render={(p, state) => (\n        <button {...p}>\n          {state.active ? (\n            <motion.span\n              layoutId={layoutId}\n              aria-hidden\n              data-slot={line ? \"tabs-underline\" : \"tabs-thumb\"}\n              className={line ? UNDERLINE : THUMB}\n              transition={reduce ? { duration: 0 } : { type: \"spring\", bounce: 0.18, duration: 0.42 }}\n            />\n          ) : line ? null : (\n            <span\n              aria-hidden\n              className=\"absolute inset-0 -z-10 rounded-[inherit] bg-fg/0 transition-colors duration-[70ms] group-hover/tab:bg-fg/[0.035] group-active/tab:bg-fg/[0.06] group-disabled/tab:bg-fg/0 group-data-disabled/tab:bg-fg/0\"\n            />\n          )}\n          {p.children}\n          {badge != null ? (\n            <span\n              className={cn(\n                \"rounded-full px-1.5 font-mono text-[10px] leading-4 tabular-nums transition-colors duration-[70ms]\",\n                state.active ? \"bg-accent-soft text-accent-fg\" : \"bg-fg/5 text-fg-subtle\"\n              )}\n            >\n              {badge}\n            </span>\n          ) : null}\n        </button>\n      )}\n      {...props}\n    >\n      {children}\n    </TabsPrimitive.Tab>\n  )\n}\n\ntype TabsContentProps = TabsPrimitive.Panel.Props\n\nfunction TabsContent({ className, ...props }: TabsContentProps) {\n  return (\n    <TabsPrimitive.Panel\n      data-slot=\"tabs-content\"\n      className={cn(\n        \"flex-1 rounded-lg text-sm outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }\nexport type { TabsProps, TabsListProps, TabsTriggerProps, TabsContentProps }\n"
    }
  ]
}
