22 lines
4.8 KiB
JSON
22 lines
4.8 KiB
JSON
{
|
|
"$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"
|
|
}
|
|
]
|
|
} |