"use client"; import React, { useCallback, useEffect, useRef, useState } from "react"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { oneDark } from "react-syntax-highlighter/dist/esm/styles/prism"; import { Check, Copy } from "lucide-react"; import { copyText } from "@/lib/clipboard"; import { errorToast } from "@/lib/errorReporter"; interface CodeBlockProps { language: string; value: string; } export const CodeBlock = React.memo(({ language, value }) => { const [copied, setCopied] = useState(false); // Clear the "copied" timer on unmount so we don't setState on a gone component. const copyResetTimer = useRef | undefined>( undefined ); useEffect( () => () => { if (copyResetTimer.current) clearTimeout(copyResetTimer.current); }, [] ); useEffect(() => { setCopied(false); if (copyResetTimer.current) clearTimeout(copyResetTimer.current); }, [value]); const handleCopy = useCallback(async () => { if (await copyText(value)) { setCopied(true); if (copyResetTimer.current) clearTimeout(copyResetTimer.current); copyResetTimer.current = setTimeout(() => setCopied(false), 2000); } else { errorToast("clipboard", "Couldn't copy to clipboard."); } }, [value]); return (
{value}
); }); CodeBlock.displayName = "CodeBlock";