{ "$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;\n lang?: string;\n themes?: {\n light: string;\n dark: string;\n };\n copyButton?: boolean;\n onCopy?: (content: string) => void;\n} & Omit;\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 | null>(null);\n const [selectedCode, setSelectedCode] = React.useState(\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 = {};\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 {\n setSelectedCode(val);\n onValueChange?.(val);\n }}\n >\n \n
\n {highlightedCodes &&\n Object.keys(highlightedCodes).map((code) => (\n \n {code}\n \n ))}\n
\n\n {copyButton && highlightedCodes && (\n \n )}\n \n \n {highlightedCodes &&\n Object.entries(highlightedCodes).map(([code, val]) => (\n \n pre,_&_code]:!bg-transparent [&>pre,_&_code]:[background:transparent_!important] [&>pre,_&_code]:border-none [&_code]:!text-[13px]\"\n dangerouslySetInnerHTML={{ __html: val }}\n />\n \n ))}\n \n \n );\n}\n\nexport { CodeTabs, type CodeTabsProps };\n", "type": "registry:ui", "target": "components/animate-ui/components/code-tabs.tsx" } ] }