{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tabs",
  "title": "Tabs",
  "description": "The key stretches across the list to the tab you pick, and the panel slides in from that side.",
  "dependencies": [
    "@ui-sdk/core@0.1.0-beta.2",
    "@ui-sdk/react@0.1.0-beta.2"
  ],
  "registryDependencies": [
    "@keyframery/motion"
  ],
  "files": [
    {
      "path": "registry/components/keyframery/primitives/tabs.tsx",
      "content": "\"use client\"\n\n/* Animated drop-in for `@ui-sdk/react/tabs`: same parts, same props. Swap the import and keep your code.\n   This file adds motion only. Colours, radii, shadows and spacing stay yours. */\n\nimport {\n  TabsIndicator as TabsIndicatorPart,\n  TabsList as TabsListPart,\n  TabsPanel as TabsPanelPart,\n  TabsTab as TabsTabPart,\n} from \"@ui-sdk/react/tabs\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport * from \"@ui-sdk/react/tabs\"\n\nfunction TabsList({ className, ...props }: React.ComponentProps<typeof TabsListPart>) {\n  return <TabsListPart className={cn(\"relative isolate\", className)} {...props} />\n}\n\nfunction TabsTab({ className, ...props }: React.ComponentProps<typeof TabsTabPart>) {\n  return (\n    <TabsTabPart\n      className={cn(\n        \"transition-[scale] duration-[calc(150ms*var(--kf-speed,1))] ease-spring active:scale-[0.96] motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* Stretch: every edge of the marker is tracked twice, once quickly and once slowly with a\n   70ms lag. Each edge then uses whichever of the two is further out, so the edge facing the\n   direction of travel leads and the opposite edge follows: the marker stretches toward where\n   it is going, then closes up. (No spring here: an overshoot would push it out of its track.) It needs no direction attribute, so it is right on the\n   first move and in both directions. The registered properties are inherited, so anything\n   inside the indicator can read the same moving edges. */\nconst stretchProperties = [\"la\", \"lb\", \"ra\", \"rb\", \"ta\", \"tb\", \"ba\", \"bb\"]\n  .map((n) => `@property --kf-${n}{syntax:\"<length>\";inherits:true;initial-value:0px}`)\n  .join(\"\")\n\nfunction TabsIndicator({ className, ...props }: React.ComponentProps<typeof TabsIndicatorPart>) {\n  /* Hold the transitions until UI SDK has measured the first tab, so the marker\n     is simply there on load instead of sliding in from the corner. */\n  const [ready, setReady] = React.useState(false)\n  React.useEffect(() => {\n    const timer = setTimeout(() => setReady(true), 150)\n    return () => clearTimeout(timer)\n  }, [])\n\n  return (\n    <>\n      <style href=\"kf-stretch\" precedence=\"default\">\n        {stretchProperties}\n      </style>\n      <TabsIndicatorPart\n        data-ready={ready || undefined}\n        className={cn(\n          \"pointer-events-none absolute\",\n          \"[--kf-la:var(--active-tab-left,0px)] [--kf-lb:var(--active-tab-left,0px)] [--kf-ra:var(--active-tab-right,0px)] [--kf-rb:var(--active-tab-right,0px)]\",\n          \"[--kf-ba:var(--active-tab-bottom,0px)] [--kf-bb:var(--active-tab-bottom,0px)] [--kf-ta:var(--active-tab-top,0px)] [--kf-tb:var(--active-tab-top,0px)]\",\n          \"top-[min(var(--kf-ta),var(--kf-tb))] right-[min(var(--kf-ra),var(--kf-rb))] bottom-[min(var(--kf-ba),var(--kf-bb))] left-[min(var(--kf-la),var(--kf-lb))]\",\n          \"motion-reduce:transition-none! data-ready:[transition:--kf-la_calc(260ms*var(--kf-speed,1))_var(--ease-house),--kf-ra_calc(260ms*var(--kf-speed,1))_var(--ease-house),--kf-ta_calc(260ms*var(--kf-speed,1))_var(--ease-house),--kf-ba_calc(260ms*var(--kf-speed,1))_var(--ease-house),--kf-lb_calc(380ms*var(--kf-speed,1))_var(--ease-house)_calc(80ms*var(--kf-speed,1)),--kf-rb_calc(380ms*var(--kf-speed,1))_var(--ease-house)_calc(80ms*var(--kf-speed,1)),--kf-tb_calc(380ms*var(--kf-speed,1))_var(--ease-house)_calc(80ms*var(--kf-speed,1)),--kf-bb_calc(380ms*var(--kf-speed,1))_var(--ease-house)_calc(80ms*var(--kf-speed,1))]\",\n          \"motion-reduce:[transition:none]!\",\n          className,\n        )}\n        {...props}\n      />\n    </>\n  )\n}\n\n/* Optional: put the panels inside TabsPanels and the one leaving overlaps the one\n   arriving. Without it, the old panel leaves at once and the new one still animates in. */\nfunction TabsPanels({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <div data-slot=\"tabs-panels\" className={cn(\"group/panels grid min-w-0\", className)} {...props} />\n}\n\nfunction TabsPanel({ className, ...props }: React.ComponentProps<typeof TabsPanelPart>) {\n  return (\n    <TabsPanelPart\n      className={cn(\n        \"transition-[opacity,translate,filter] duration-[calc(460ms*var(--kf-speed,1))] ease-spring\",\n        \"data-starting-style:opacity-0 data-starting-style:blur-[6px]\",\n        \"data-[activation-direction=right]:data-starting-style:translate-x-8 data-[activation-direction=left]:data-starting-style:-translate-x-8\",\n        \"data-[activation-direction=down]:data-starting-style:translate-y-6 data-[activation-direction=up]:data-starting-style:-translate-y-6\",\n        \"data-ending-style:hidden\",\n        \"group-data-[slot=tabs-panels]/panels:[grid-area:1/1] group-data-[slot=tabs-panels]/panels:data-ending-style:block\",\n        \"data-ending-style:opacity-0 data-ending-style:blur-[6px] data-ending-style:duration-[calc(200ms*var(--kf-speed,1))] data-ending-style:ease-house\",\n        \"data-[activation-direction=right]:data-ending-style:-translate-x-6 data-[activation-direction=left]:data-ending-style:translate-x-6\",\n        \"data-[activation-direction=down]:data-ending-style:-translate-y-4 data-[activation-direction=up]:data-ending-style:translate-y-4\",\n        \"motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { TabsIndicator, TabsList, TabsPanel, TabsPanels, TabsTab }\n",
      "type": "registry:component",
      "target": "components/keyframery/primitives/tabs.tsx"
    },
    {
      "path": "registry/components/keyframery/tabs.tsx",
      "content": "\"use client\"\n\n/* Styled tabs: the animated primitive plus the Keyframery look. */\n\nimport * as React from \"react\"\n\nimport {\n  Tabs as TabsRoot,\n  TabsIndicator as TabsIndicatorPrimitive,\n  TabsList as TabsListPrimitive,\n  TabsPanel as TabsPanelPrimitive,\n  TabsPanels as TabsPanelsPrimitive,\n  TabsTab as TabsTabPrimitive,\n} from \"@/components/keyframery/primitives/tabs\"\nimport { cn } from \"@/lib/utils\"\n\n/* One box shared by the real tab and its copy inside the key, so both lay out identically. */\nconst tabBox =\n  \"inline-flex h-8 shrink-0 items-center justify-center gap-1.5 rounded-[9px] px-3 text-[13px] leading-none font-medium whitespace-nowrap [&_svg]:size-3.5 [&_svg]:shrink-0\"\n\nconst listLayout =\n  \"flex items-center gap-0.5 p-1 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch\"\n\nfunction Tabs({ className, ...props }: React.ComponentProps<typeof TabsRoot>) {\n  return (\n    <TabsRoot\n      className={cn(\n        \"flex flex-col data-[orientation=vertical]:flex-row data-[orientation=vertical]:gap-4\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TabsList({\n  className,\n  children,\n  ...props\n}: Omit<React.ComponentProps<typeof TabsListPrimitive>, \"children\"> & {\n  children?: React.ReactNode\n}) {\n  return (\n    <TabsListPrimitive\n      className={cn(\n        listLayout,\n        \"w-fit rounded-[12px] bg-muted\",\n        \"shadow-[inset_0_1px_2px_rgb(0_0_0/0.07),inset_0_0_0_1px_rgb(0_0_0/0.035)]\",\n        \"dark:shadow-[inset_0_1px_2px_rgb(0_0_0/0.5),inset_0_0_0_1px_rgb(255_255_255/0.04)]\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      {/* The key: a raised surface that stretches toward the tab you pick. */}\n      <TabsIndicatorPrimitive\n        aria-hidden\n        className={cn(\n          \"group/key z-10 rounded-[9px] bg-background\",\n          \"shadow-[0_0_0_1px_rgb(0_0_0/0.06),0_1px_1px_rgb(0_0_0/0.05),0_3px_6px_-2px_rgb(0_0_0/0.1)]\",\n          \"dark:bg-accent dark:shadow-[0_0_0_1px_rgb(255_255_255/0.07),inset_0_1px_0_rgb(255_255_255/0.08),0_2px_6px_-1px_rgb(0_0_0/0.6)]\",\n        )}\n      >\n        {/* A copy of the labels in the selected colour, clipped to the key. It is offset by the\n            key's own moving edges, so it stays still while the key passes over it. */}\n        <span className=\"absolute inset-0 overflow-hidden rounded-[inherit]\">\n          <span\n            className={cn(\n              listLayout,\n              \"absolute text-foreground\",\n              \"group-data-[orientation=vertical]/key:flex-col group-data-[orientation=vertical]/key:items-stretch\",\n              \"top-[calc(min(var(--kf-ta),var(--kf-tb))*-1)] left-[calc(min(var(--kf-la),var(--kf-lb))*-1)]\",\n              \"h-[calc(var(--active-tab-top,0px)+var(--active-tab-height,0px)+var(--active-tab-bottom,0px))]\",\n              \"w-[calc(var(--active-tab-left,0px)+var(--active-tab-width,0px)+var(--active-tab-right,0px))]\",\n            )}\n          >\n            {React.Children.map(children, (child) =>\n              React.isValidElement<{ children?: React.ReactNode }>(child) ? (\n                <span className={tabBox}>{child.props.children}</span>\n              ) : null,\n            )}\n          </span>\n        </span>\n      </TabsIndicatorPrimitive>\n    </TabsListPrimitive>\n  )\n}\n\nfunction TabsTab({ className, ...props }: React.ComponentProps<typeof TabsTabPrimitive>) {\n  return (\n    <TabsTabPrimitive\n      className={cn(\n        tabBox,\n        \"relative cursor-pointer text-muted-foreground outline-none select-none\",\n        \"transition-[color,background-color,scale] motion-reduce:transition-none! hover:bg-foreground/[0.045] hover:text-foreground\",\n        \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-muted\",\n        \"data-disabled:pointer-events-none data-disabled:opacity-40\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TabsPanels({ className, ...props }: React.ComponentProps<typeof TabsPanelsPrimitive>) {\n  return <TabsPanelsPrimitive className={cn(\"mt-3 flex-1\", className)} {...props} />\n}\n\nfunction TabsPanel({ className, ...props }: React.ComponentProps<typeof TabsPanelPrimitive>) {\n  return (\n    <TabsPanelPrimitive\n      className={cn(\n        \"min-w-0 outline-none\",\n        \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Tabs, TabsList, TabsPanel, TabsPanels, TabsTab }\n",
      "type": "registry:component",
      "target": "components/keyframery/tabs.tsx"
    }
  ],
  "type": "registry:component"
}