'use client'; import { Button } from '../ui/button'; import { cn } from '../../src/lib/utils'; import { CheckIcon, CopyIcon } from 'lucide-react'; import { type ComponentProps, createContext, type HTMLAttributes, useContext, useState } from 'react'; type CodeBlockProps = HTMLAttributes & { code: string; language?: string; showLineNumbers?: boolean; }; type CodeBlockContextType = { code: string; }; const CodeBlockContext = createContext({ code: '', }); export const CodeBlock = ({ code, language, showLineNumbers = false, className, children, ...props }: CodeBlockProps) => { const lines = code.split('\n'); return (
{lines.map((line, i) => ( {showLineNumbers && ( )} ))}
{i + 1}
                        {line || '\u00A0'}
                      
{children &&
{children}
}
); }; export type CodeBlockCopyButtonProps = ComponentProps & { onCopy?: () => void; onError?: (error: Error) => void; timeout?: number; }; export const CodeBlockCopyButton = ({ onCopy, onError, timeout = 2000, children, className, ...props }: CodeBlockCopyButtonProps) => { const [isCopied, setIsCopied] = useState(false); const { code } = useContext(CodeBlockContext); const copyToClipboard = async () => { if (typeof window === 'undefined' || !navigator?.clipboard?.writeText) { onError?.(new Error('Clipboard API not available')); return; } try { await navigator.clipboard.writeText(code); setIsCopied(true); onCopy?.(); setTimeout(() => setIsCopied(false), timeout); } catch (error) { onError?.(error as Error); } }; const Icon = isCopied ? CheckIcon : CopyIcon; return ( ); };