{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tabs",
  "type": "registry:ui",
  "title": "Tabs",
  "description": "Switches which panel is shown: the switcher track and gliding thumb as the tab list, and panels that drift in from the side the thumb went.",
  "dependencies": [
    "@base-ui/react@^1.8.0"
  ],
  "registryDependencies": [
    "https://metalui.dev/r/tokens.json"
  ],
  "files": [
    {
      "path": "packages/metalui/src/components/tabs/tabs.tsx",
      "type": "registry:ui",
      "target": "components/metalui/tabs/tabs.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { Tabs as BaseTabs } from '@base-ui/react/tabs';\nimport { SlidingIndicator } from '../../motion/indicator';\nimport { trackParts } from '../switcher/switcher';\n\n/* ─────────────────────────────────────────────────────────\n * TABS on Base UI Tabs: switch which panel is shown\n *\n * Use it when each option owns a panel (React / Agent guide, the pages of Settings).\n * Picking a value with no panel of its own is the Switcher; a long list is a Select.\n *\n *   list      the switcher track: a well, tabs in ink2, the active one a raised thumb in ink\n *   hover     the label turns ink\n *   switch    the thumb glides to the new tab on the part spring (a track with ends, so it\n *             may overshoot against the stop); the new panel comes in from the side the thumb\n *             went: 6 px drift and a fade on the settle spring. The old panel leaves at once.\n *   first     the first panel shows without motion\n *   focus     a 1.5 ring on the tab; ← → move and choose, Home / End jump; Tab goes into the panel\n *   disabled  40 %\n * Reduce Motion: the thumb moves at once and the panel only fades.\n * ───────────────────────────────────────────────────────── */\n\nexport interface TabItem<V extends string = string> {\n  value: V;\n  label: React.ReactNode;\n  /** A leading glyph at the size the height gives (12 in 24, 14 in 28). */\n  icon?: React.ReactNode;\n  disabled?: boolean;\n}\n\nexport interface TabsProps<V extends string = string> {\n  value?: V;\n  defaultValue?: V;\n  onValueChange?: (value: V) => void;\n  children: React.ReactNode;\n  className?: string;\n}\n\nexport interface TabListProps<V extends string = string> {\n  items: TabItem<V>[];\n  /** compact is 24 tall (in a panel head, a strip), regular 28. */\n  size?: 'compact' | 'regular';\n  'aria-label': string;\n  className?: string;\n}\n\nexport interface TabPanelProps<V extends string = string> {\n  value: V;\n  children: React.ReactNode;\n  /** Keep the panel in the page while hidden (for state that must survive a switch). */\n  keepMounted?: boolean;\n  className?: string;\n}\n\nconst PANEL = 'mu-tabs-panel tabs-panel';\nconst join = (a: string, b?: string) => (b ? `${a} ${b}` : a);\n\n/** Holds the active tab; put a TabList and one TabPanel per tab anywhere inside. */\nexport function Tabs<V extends string = string>({ value, defaultValue, onValueChange, children, className }: TabsProps<V>) {\n  return (\n    <BaseTabs.Root value={value} defaultValue={defaultValue} onValueChange={(v) => onValueChange?.(v as V)} className={className}>\n      {children}\n    </BaseTabs.Root>\n  );\n}\n\n/** The tabs, on the switcher track with its gliding thumb. */\nexport function TabList<V extends string = string>({ items, size = 'regular', className, ...props }: TabListProps<V>) {\n  return (\n    <BaseTabs.List activateOnFocus aria-label={props[\"aria-label\"]} data-size={size} className={join(trackParts.TRACK, className)}>\n      <SlidingIndicator className={trackParts.THUMB} />\n      {items.map((t) => (\n        <BaseTabs.Tab key={t.value} value={t.value} disabled={t.disabled} className={trackParts.OPTION[size]}>\n          {t.icon}\n          {t.label}\n        </BaseTabs.Tab>\n      ))}\n    </BaseTabs.List>\n  );\n}\n\n/** One tab's panel; it drifts in from the side the thumb went. */\nexport function TabPanel<V extends string = string>({ value, children, keepMounted, className }: TabPanelProps<V>) {\n  return (\n    <BaseTabs.Panel value={value} keepMounted={keepMounted} className={join(PANEL, className)}>\n      {children}\n    </BaseTabs.Panel>\n  );\n}\n"
    }
  ],
  "docs": "Agent guide: https://metalui.dev/r/tabs.md. SwiftUI: MetalTabs in the MetalUI Swift package."
}
