"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 ( ); };