{
  "name": "tabs",
  "type": "registry:ui",
  "title": "Tabs",
  "description": "Equal-priority panels within one local page context, with horizontal and vertical orientation.",
  "registryDependencies": [
    "@siteplane/base"
  ],
  "dependencies": [
    "@base-ui/react@1.5.0"
  ],
  "files": [
    {
      "path": "src/components/ui/tabs.tsx",
      "type": "registry:ui",
      "content": "\"use client\";\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport * as React from \"react\";\nimport {\n  type SiteplaneControlSize,\n  useResolvedControlSize,\n} from \"@/components/ui/siteplane-provider\";\nimport { cn } from \"@/lib/utils\";\n\nexport type TabsVariant = \"default\" | \"underline\";\n\nconst TabsSizeContext = React.createContext<SiteplaneControlSize | null>(null);\n\nconst tabsTabSizeClassNames = {\n  default: \"h-9 px-[calc(--spacing(2.5)-1px)] text-base sm:h-8 sm:text-sm\",\n  lg: \"h-10 px-[calc(--spacing(3)-1px)] text-base sm:h-9 sm:text-sm\",\n  sm: \"h-8 px-[calc(--spacing(2)-1px)] text-sm sm:h-7\",\n  xl: \"h-14 px-[calc(--spacing(4)-1px)] text-lg leading-6\",\n} satisfies Record<SiteplaneControlSize, string>;\n\nexport interface TabsProps extends Omit<TabsPrimitive.Root.Props, \"size\"> {\n  size?: SiteplaneControlSize;\n}\n\nexport function Tabs({\n  className,\n  size,\n  ...props\n}: TabsProps): React.ReactElement {\n  const resolvedSize = useResolvedControlSize(size);\n\n  return (\n    <TabsSizeContext.Provider value={resolvedSize}>\n      <TabsPrimitive.Root\n        className={cn(\n          \"flex flex-col gap-2 data-[orientation=vertical]:flex-row\",\n          className,\n        )}\n        data-size={resolvedSize}\n        data-slot=\"tabs\"\n        {...props}\n      />\n    </TabsSizeContext.Provider>\n  );\n}\n\nexport interface TabsListProps extends Omit<TabsPrimitive.List.Props, \"size\"> {\n  variant?: TabsVariant;\n  size?: SiteplaneControlSize;\n}\n\nexport function TabsList({\n  variant = \"default\",\n  size,\n  className,\n  children,\n  ...props\n}: TabsListProps): React.ReactElement {\n  const groupSize = React.useContext(TabsSizeContext);\n  const resolvedSize = useResolvedControlSize(size ?? groupSize);\n\n  return (\n    <TabsSizeContext.Provider value={resolvedSize}>\n      <TabsPrimitive.List\n        className={cn(\n          \"relative z-0 flex w-fit items-center justify-center gap-x-0.5 text-muted-foreground\",\n          \"data-[orientation=vertical]:flex-col\",\n          variant === \"default\"\n            ? \"rounded-lg bg-muted p-0.5 text-muted-foreground/72\"\n            : \"data-[orientation=vertical]:px-1 data-[orientation=horizontal]:py-1 *:data-[slot=tabs-tab]:hover:bg-accent\",\n          className,\n        )}\n        data-size={resolvedSize}\n        data-slot=\"tabs-list\"\n        {...props}\n      >\n        {children}\n        <TabsPrimitive.Indicator\n          className={cn(\n            \"absolute bottom-0 left-0 h-(--active-tab-height) w-(--active-tab-width) translate-x-(--active-tab-left) -translate-y-(--active-tab-bottom) transition-[width,translate] duration-(--motion-duration-base) ease-(--motion-ease-soft-in-out) motion-reduce:transition-none\",\n            variant === \"underline\"\n              ? \"z-10 bg-primary data-[orientation=horizontal]:h-0.5 data-[orientation=vertical]:w-0.5 data-[orientation=vertical]:-translate-x-px data-[orientation=horizontal]:translate-y-px\"\n              : \"-z-1 rounded-md bg-background shadow-sm/5 dark:bg-input\",\n          )}\n          data-slot=\"tab-indicator\"\n        />\n      </TabsPrimitive.List>\n    </TabsSizeContext.Provider>\n  );\n}\n\nexport interface TabsTabProps extends Omit<TabsPrimitive.Tab.Props, \"size\"> {\n  size?: SiteplaneControlSize;\n}\n\nexport function TabsTab({\n  className,\n  size,\n  ...props\n}: TabsTabProps): React.ReactElement {\n  const groupSize = React.useContext(TabsSizeContext);\n  const resolvedSize = useResolvedControlSize(size ?? groupSize);\n\n  return (\n    <TabsPrimitive.Tab\n      className={cn(\n        \"relative flex shrink-0 grow cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent font-medium outline-none transition-[color,background-color,box-shadow] hover:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring data-disabled:cursor-not-allowed data-[orientation=vertical]:w-full data-[orientation=vertical]:justify-start data-active:text-foreground data-disabled:opacity-64 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:-mx-0.5 [&_svg]:shrink-0\",\n        tabsTabSizeClassNames[resolvedSize],\n        className,\n      )}\n      data-size={resolvedSize}\n      data-slot=\"tabs-tab\"\n      {...props}\n    />\n  );\n}\n\nexport function TabsPanel({\n  className,\n  ...props\n}: TabsPrimitive.Panel.Props): React.ReactElement {\n  return (\n    <TabsPrimitive.Panel\n      className={cn(\"flex-1 outline-none\", className)}\n      data-slot=\"tabs-content\"\n      {...props}\n    />\n  );\n}\n\nexport { TabsPrimitive, TabsTab as TabsTrigger, TabsPanel as TabsContent };\n"
    }
  ],
  "categories": [
    "navigation"
  ],
  "docs": "# Tabs\n\n> Siteplane UI release `0.1.1`.\n\n## Public Purpose\n\nUse Tabs for equal-priority panels within one local page context, such as settings sections or compact detail views.\n\n## Import\n\n`import { Tabs, TabsList, TabsPanel, TabsTab } from \"@/components/ui/tabs\";`\n\n`import { TabsContent, TabsTrigger } from \"@/components/ui/tabs\";`\n\n## Public API\n\n- `Tabs` accepts controlled or uncontrolled `value`, `onValueChange`, `orientation` and `size=\"sm\" | \"default\" | \"lg\" | \"xl\"` through the Base UI root contract.\n- `TabsList` accepts `variant=\"default\" | \"underline\"` and can provide the size to its child tabs.\n- Each `TabsTab` requires a matching `value` and can be disabled or sized locally; render the corresponding content in `TabsPanel`.\n- `TabsContent` remains a compatibility alias for `TabsPanel`; new code should use the canonical `TabsPanel` name.\n\n## Public Motion\n\n- The active indicator uses the native Siteplane position and size transition. Panels do not receive a heavy entrance animation.\n- The operating-system reduced-motion preference removes indicator interpolation. The forced `reducedMotionPreset` shortens the shared base duration from 180ms to 80ms while preserving selection and focus.\n\n## Public Accessibility\n\n- Preserve the tab, tablist and tabpanel relationship generated by Base UI.\n- Keep orientation consistent with both layout and arrow-key navigation.\n- Do not make a disabled tab the only path to required content.\n\n## Public Agent Guidance\n\n- Use Stepper for workflow steps and navigation links for global routing.\n- Use canonical `TabsPanel` in new code and keep value pairs unique.\n- Do not replace native indicator, focus or orientation behavior.\n\n## Public Links\n\n- [Documentation and preview](https://ui.siteplane.io/docs/components/navigation/tabs)\n\n- [Registry source](https://ui.siteplane.io/r/tabs.json)\n",
  "meta": {
    "siteplane:agentContractVersion": 1,
    "siteplane:docs": "https://ui.siteplane.io/docs/components/navigation/tabs",
    "siteplane:releaseVersion": "0.1.1",
    "siteplane:sourceOwned": true
  },
  "devDependencies": []
}
