'use client'; import * as React from 'react'; import { useTheme } from 'next-themes'; import { cn } from '@workspace/ui/lib/utils'; import { Tabs, TabsContent, TabsList, TabsTrigger, TabsContents, type TabsProps, } from '@/registry/components/tabs'; import { CopyButton } from '@/registry/buttons/copy'; type CodeTabsProps = { codes: Record; lang?: string; themes?: { light: string; dark: string; }; copyButton?: boolean; onCopy?: (content: string) => void; } & Omit; function CodeTabs({ codes, lang = 'bash', themes = { light: 'github-light', dark: 'github-dark', }, className, defaultValue, value, onValueChange, copyButton = true, onCopy, ...props }: CodeTabsProps) { const { resolvedTheme } = useTheme(); const [highlightedCodes, setHighlightedCodes] = React.useState | null>(null); const [selectedCode, setSelectedCode] = React.useState( value ?? defaultValue ?? Object.keys(codes)[0] ?? '', ); React.useEffect(() => { async function loadHighlightedCode() { try { const { codeToHtml } = await import('shiki'); const newHighlightedCodes: Record = {}; for (const [command, val] of Object.entries(codes)) { const highlighted = await codeToHtml(val, { lang, themes: { light: themes.light, dark: themes.dark, }, defaultColor: resolvedTheme === 'dark' ? 'dark' : 'light', }); newHighlightedCodes[command] = highlighted; } setHighlightedCodes(newHighlightedCodes); } catch (error) { console.error('Error highlighting codes', error); setHighlightedCodes(codes); } } loadHighlightedCode(); }, [resolvedTheme, lang, themes.light, themes.dark, codes]); return ( { setSelectedCode(val); onValueChange?.(val); }} >
{highlightedCodes && Object.keys(highlightedCodes).map((code) => ( {code} ))}
{copyButton && highlightedCodes && ( )}
{highlightedCodes && Object.entries(highlightedCodes).map(([code, val]) => (
))} ); } export { CodeTabs, type CodeTabsProps };