{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "code-tabs",
  "type": "registry:ui",
  "title": "Code Tabs",
  "description": "A tabs component that displays code for different languages.",
  "dependencies": [
    "shiki"
  ],
  "registryDependencies": [
    "https://animate-ui.com/r/tabs",
    "https://animate-ui.com/r/copy-button"
  ],
  "files": [
    {
      "path": "registry/components/code-tabs/index.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { useTheme } from 'next-themes';\n\nimport { cn } from '@/lib/utils';\nimport {\n  Tabs,\n  TabsContent,\n  TabsList,\n  TabsTrigger,\n  TabsContents,\n  type TabsProps,\n} from '@/components/animate-ui/components/tabs';\nimport { CopyButton } from '@/components/animate-ui/buttons/copy';\n\ntype CodeTabsProps = {\n  codes: Record<string, string>;\n  lang?: string;\n  themes?: {\n    light: string;\n    dark: string;\n  };\n  copyButton?: boolean;\n  onCopy?: (content: string) => void;\n} & Omit<TabsProps, 'children'>;\n\nfunction CodeTabs({\n  codes,\n  lang = 'bash',\n  themes = {\n    light: 'github-light',\n    dark: 'github-dark',\n  },\n  className,\n  defaultValue,\n  value,\n  onValueChange,\n  copyButton = true,\n  onCopy,\n  ...props\n}: CodeTabsProps) {\n  const { resolvedTheme } = useTheme();\n\n  const [highlightedCodes, setHighlightedCodes] = React.useState<Record<\n    string,\n    string\n  > | null>(null);\n  const [selectedCode, setSelectedCode] = React.useState<string>(\n    value ?? defaultValue ?? Object.keys(codes)[0] ?? '',\n  );\n\n  React.useEffect(() => {\n    async function loadHighlightedCode() {\n      try {\n        const { codeToHtml } = await import('shiki');\n        const newHighlightedCodes: Record<string, string> = {};\n\n        for (const [command, val] of Object.entries(codes)) {\n          const highlighted = await codeToHtml(val, {\n            lang,\n            themes: {\n              light: themes.light,\n              dark: themes.dark,\n            },\n            defaultColor: resolvedTheme === 'dark' ? 'dark' : 'light',\n          });\n\n          newHighlightedCodes[command] = highlighted;\n        }\n\n        setHighlightedCodes(newHighlightedCodes);\n      } catch (error) {\n        console.error('Error highlighting codes', error);\n        setHighlightedCodes(codes);\n      }\n    }\n    loadHighlightedCode();\n  }, [resolvedTheme, lang, themes.light, themes.dark, codes]);\n\n  return (\n    <Tabs\n      data-slot=\"install-tabs\"\n      className={cn(\n        'w-full gap-0 bg-muted/50 rounded-xl border overflow-hidden',\n        className,\n      )}\n      {...props}\n      value={selectedCode}\n      onValueChange={(val) => {\n        setSelectedCode(val);\n        onValueChange?.(val);\n      }}\n    >\n      <TabsList\n        data-slot=\"install-tabs-list\"\n        className=\"w-full relative justify-between rounded-none h-10 bg-muted border-b border-border/75 dark:border-border/50 text-current py-0 px-4\"\n        activeClassName=\"rounded-none shadow-none bg-transparent after:content-[''] after:absolute after:inset-x-0 after:h-0.5 after:bottom-0 dark:after:bg-white after:bg-black after:rounded-t-full\"\n      >\n        <div className=\"flex gap-x-3 h-full\">\n          {highlightedCodes &&\n            Object.keys(highlightedCodes).map((code) => (\n              <TabsTrigger\n                key={code}\n                value={code}\n                className=\"text-muted-foreground data-[state=active]:text-current px-0\"\n              >\n                {code}\n              </TabsTrigger>\n            ))}\n        </div>\n\n        {copyButton && highlightedCodes && (\n          <CopyButton\n            content={codes[selectedCode]}\n            size=\"sm\"\n            variant=\"ghost\"\n            className=\"-me-2 bg-transparent hover:bg-black/5 dark:hover:bg-white/10\"\n            onCopy={onCopy}\n          />\n        )}\n      </TabsList>\n      <TabsContents data-slot=\"install-tabs-contents\">\n        {highlightedCodes &&\n          Object.entries(highlightedCodes).map(([code, val]) => (\n            <TabsContent\n              data-slot=\"install-tabs-content\"\n              key={code}\n              className=\"w-full text-sm flex items-center p-4 overflow-auto\"\n              value={code}\n            >\n              <div\n                className=\"[&>pre,_&_code]:!bg-transparent [&>pre,_&_code]:[background:transparent_!important] [&>pre,_&_code]:border-none [&_code]:!text-[13px]\"\n                dangerouslySetInnerHTML={{ __html: val }}\n              />\n            </TabsContent>\n          ))}\n      </TabsContents>\n    </Tabs>\n  );\n}\n\nexport { CodeTabs, type CodeTabsProps };\n",
      "type": "registry:ui",
      "target": "components/animate-ui/components/code-tabs.tsx"
    }
  ]
}