{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tabs",
  "title": "Tabs",
  "description": "A tabs component.",
  "dependencies": [
    "class-variance-authority"
  ],
  "registryDependencies": [
    "@cubby-ui/elevated",
    "@cubby-ui/use-animated-height"
  ],
  "files": [
    {
      "path": "registry/default/tabs/tabs.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Tabs as BaseTabs } from \"@base-ui/react/tabs\";\nimport { cva } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\nimport { solidSurface } from \"@/registry/default/lib/elevated\";\nimport { useAnimatedHeight } from \"@/registry/default/hooks/use-animated-height\";\n\ntype TabsVariant = \"capsule\" | \"underline\";\ntype TabsSize = \"small\" | \"medium\";\ntype TabsSide = \"left\" | \"right\";\n\n/* -------------------------------------------------------------------------------------------------\n * CVA Variants\n * -------------------------------------------------------------------------------------------------*/\n\nconst tabsListVariants = cva(\n  [\n    \"group/tabs-list text-muted-foreground relative z-0 inline-flex w-fit items-center justify-center gap-1\",\n    \"data-[orientation=vertical]:flex-col data-[orientation=vertical]:self-start\",\n  ],\n  {\n    variants: {\n      variant: {\n        capsule: \"bg-muted\",\n        underline:\n          \"data-[orientation=horizontal]:px-0 data-[orientation=horizontal]:pt-0 data-[orientation=vertical]:py-0\",\n      },\n      size: {\n        small: \"p-0.5 data-[orientation=horizontal]:gap-x-0.5\",\n        medium: \"p-1 data-[orientation=horizontal]:gap-x-1\",\n      },\n      side: {\n        left: \"\",\n        right: \"\",\n      },\n    },\n    compoundVariants: [\n      {\n        variant: \"capsule\",\n        size: \"small\",\n        class: \"rounded-md\",\n      },\n      {\n        variant: \"capsule\",\n        size: \"medium\",\n        class: \"rounded-xl\",\n      },\n      {\n        variant: \"underline\",\n        side: \"left\",\n        class:\n          \"data-[orientation=vertical]:**:data-[slot=tabs-trigger]:justify-end\",\n      },\n      {\n        variant: \"underline\",\n        side: \"right\",\n        class:\n          \"data-[orientation=vertical]:**:data-[slot=tabs-trigger]:justify-start\",\n      },\n    ],\n    defaultVariants: {\n      variant: \"capsule\",\n      size: \"medium\",\n      side: \"left\",\n    },\n  },\n);\n\nconst tabIndicatorVariants = cva(\n  [\n    \"ease-out-expo absolute z-[-1] transition-all duration-200\",\n    // Vertical orientation\n    \"data-[orientation=vertical]:top-0 data-[orientation=vertical]:h-(--active-tab-height) data-[orientation=vertical]:translate-y-(--active-tab-top)\",\n    // Horizontal orientation\n    \"data-[orientation=horizontal]:left-0 data-[orientation=horizontal]:w-(--active-tab-width) data-[orientation=horizontal]:translate-x-(--active-tab-left) data-[orientation=horizontal]:-translate-y-1/2\",\n  ],\n  {\n    variants: {\n      variant: {\n        underline: [\n          \"bg-neutral rounded-full\",\n          \"data-[orientation=vertical]:w-0.75\",\n          \"data-[orientation=horizontal]:bottom-0 data-[orientation=horizontal]:top-auto data-[orientation=horizontal]:h-0.75 data-[orientation=horizontal]:translate-y-0\",\n        ],\n        capsule: [\n          solidSurface(5, 1),\n          \"data-[orientation=vertical]:w-auto\",\n          \"data-[orientation=horizontal]:top-1/2 data-[orientation=horizontal]:h-(--active-tab-height)\",\n        ],\n      },\n      size: {\n        small: \"\",\n        medium: \"\",\n      },\n      side: {\n        left: \"\",\n        right: \"\",\n      },\n    },\n    compoundVariants: [\n      {\n        variant: \"capsule\",\n        size: \"small\",\n        class: \"rounded-sm data-[orientation=vertical]:inset-x-0.5\",\n      },\n      {\n        variant: \"capsule\",\n        size: \"medium\",\n        class: \"rounded-md data-[orientation=vertical]:inset-x-1\",\n      },\n      {\n        variant: \"underline\",\n        side: \"left\",\n        class: \"data-[orientation=vertical]:right-0\",\n      },\n      {\n        variant: \"underline\",\n        side: \"right\",\n        class: \"data-[orientation=vertical]:left-0\",\n      },\n    ],\n    defaultVariants: {\n      variant: \"capsule\",\n      size: \"medium\",\n      side: \"left\",\n    },\n  },\n);\n\nfunction Tabs({ className, ...props }: BaseTabs.Root.Props) {\n  return (\n    <BaseTabs.Root\n      data-slot=\"tabs\"\n      className={cn(\n        \"flex min-w-0 gap-2\",\n        \"data-[orientation=vertical]:flex-row\",\n        \"data-[orientation=horizontal]:flex-col\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction TabsList({\n  variant = \"capsule\",\n  size = \"medium\",\n  side = \"left\",\n  className,\n  children,\n  ...props\n}: BaseTabs.List.Props & {\n  variant?: TabsVariant;\n  size?: TabsSize;\n  side?: TabsSide;\n}) {\n  return (\n    <BaseTabs.List\n      data-slot=\"tabs-list\"\n      data-variant={variant}\n      data-size={size}\n      data-side={side}\n      className={cn(tabsListVariants({ variant, size, side }), className)}\n      {...props}\n    >\n      {children}\n      <div\n        data-slot=\"tabs-divider\"\n        className={cn(\n          \"bg-accent absolute z-[-2] rounded-full\",\n          variant === \"underline\" ? \"block\" : \"hidden\",\n          // Vertical orientation\n          \"group-data-[orientation=vertical]/tabs-list:top-0 group-data-[orientation=vertical]/tabs-list:bottom-0 group-data-[orientation=vertical]/tabs-list:w-[2px]\",\n          side === \"left\" &&\n            \"group-data-[orientation=vertical]/tabs-list:right-0 group-data-[orientation=vertical]/tabs-list:-translate-x-[0.5px]\",\n          side === \"right\" &&\n            \"group-data-[orientation=vertical]/tabs-list:left-0 group-data-[orientation=vertical]/tabs-list:translate-x-[0.5px]\",\n          // Horizontal orientation\n          \"group-data-[orientation=horizontal]/tabs-list:right-0 group-data-[orientation=horizontal]/tabs-list:bottom-0 group-data-[orientation=horizontal]/tabs-list:left-0 group-data-[orientation=horizontal]/tabs-list:h-[2px] group-data-[orientation=horizontal]/tabs-list:-translate-y-[0.5px]\",\n        )}\n        aria-hidden=\"true\"\n      />\n      <TabIndicator variant={variant} size={size} side={side} />\n    </BaseTabs.List>\n  );\n}\n\nfunction TabsTrigger({ className, ...props }: BaseTabs.Tab.Props) {\n  return (\n    <BaseTabs.Tab\n      data-slot=\"tabs-trigger\"\n      className={cn(\n        // Base styles\n        \"text-muted-foreground data-active:text-foreground flex cursor-pointer items-center gap-1.5 font-medium text-nowrap whitespace-nowrap\",\n        \"transition-[outline-offset,color] duration-200 ease-out\",\n        \"focus-visible:outline-ring/50 focus-visible:outline-2 focus-visible:outline-offset-2\",\n        \"hover:text-muted-foreground/75\",\n        \"data-disabled:pointer-events-none data-disabled:opacity-60\",\n        \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        // Orientation\n        \"data-[orientation=horizontal]:flex-1 data-[orientation=vertical]:w-full\",\n        \"justify-center\",\n        \"group-data-[variant=underline]/tabs-list:focus-visible:outline-offset-0\",\n        // Default size (small) - overridden by group data attribute for medium\n        \"rounded-sm px-2 py-1 text-xs\",\n        // Medium size via parent group\n        \"group-data-[size=medium]/tabs-list:rounded-md group-data-[size=medium]/tabs-list:px-2.5 group-data-[size=medium]/tabs-list:py-1.5 group-data-[size=medium]/tabs-list:text-sm\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction TabIndicator({\n  variant = \"capsule\",\n  size = \"medium\",\n  side = \"left\",\n  className,\n  ...props\n}: BaseTabs.Indicator.Props & {\n  variant?: TabsVariant;\n  size?: TabsSize;\n  side?: TabsSide;\n}) {\n  return (\n    <BaseTabs.Indicator\n      data-slot=\"tab-indicator\"\n      className={cn(tabIndicatorVariants({ variant, size, side }), className)}\n      {...props}\n    />\n  );\n}\n\nfunction TabsPanels({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  const { outerRef, innerRef } = useAnimatedHeight();\n\n  return (\n    <div\n      ref={outerRef}\n      data-slot=\"tabs-panels\"\n      className={cn(\n        \"min-h-0 grow\",\n        \"has-[>_*_>_[data-ending-style]]:ease-out-expo has-[>_*_>_[data-ending-style]]:transition-[height] has-[>_*_>_[data-ending-style]]:duration-400\",\n        className,\n      )}\n      {...props}\n    >\n      <div ref={innerRef} className=\"grid\">\n        {children}\n      </div>\n    </div>\n  );\n}\n\nfunction TabsContent({\n  className,\n  disableAnimation = false,\n  ...props\n}: BaseTabs.Panel.Props & { disableAnimation?: boolean }) {\n  return (\n    <BaseTabs.Panel\n      data-slot=\"tabs-content\"\n      className={cn(\n        \"min-w-0 flex-1 outline-none\",\n        \"[grid-area:1/1]\",\n        !disableAnimation && [\n          \"ease-out-expo transition-[opacity,translate,filter] duration-[350ms,350ms,350ms]\",\n          // Enter/exit: fade + blur (scale with height diff via --fade-duration)\n          \"data-starting-style:opacity-0 data-starting-style:blur-sm\",\n          \"data-ending-style:opacity-0 data-ending-style:blur-sm data-ending-style:contain-[size]\",\n          // Directional slide (fixed 400ms)\n          \"data-[activation-direction=right]:data-starting-style:translate-x-3\",\n          \"data-[activation-direction=right]:data-ending-style:-translate-x-3\",\n          \"data-[activation-direction=left]:data-starting-style:-translate-x-3\",\n          \"data-[activation-direction=left]:data-ending-style:translate-x-3\",\n          \"data-[activation-direction=down]:data-starting-style:translate-y-3\",\n          \"data-[activation-direction=down]:data-ending-style:-translate-y-3\",\n          \"data-[activation-direction=up]:data-starting-style:-translate-y-3\",\n          \"data-[activation-direction=up]:data-ending-style:translate-y-3\",\n          // Fallback for none/initial mount\n          \"data-[activation-direction=none]:data-starting-style:translate-y-3\",\n          \"data-[activation-direction=none]:data-ending-style:translate-y-3\",\n          \"motion-reduce:blur-none motion-reduce:transition-none\",\n        ],\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsPanels, TabsContent };\n",
      "type": "registry:ui",
      "target": "components/ui/cubby-ui/tabs.tsx"
    }
  ],
  "type": "registry:ui"
}