import { Button, ButtonProps } from "@/components/ui/button.tsx"; import { Check, Copy } from "lucide-react"; import { HTMLProps, ReactNode, useEffect, useState } from "react"; import { CopyToClipboard } from "react-copy-to-clipboard"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { materialDark } from "react-syntax-highlighter/dist/esm/styles/prism"; import { toast } from "sonner"; interface CopyButtonProps extends ButtonProps { value: string; src?: string; } export function CopyButton({ value, className, src, variant = "ghost", ...props }: CopyButtonProps) { const [hasCopied, setHasCopied] = useState(false); useEffect(() => { if (hasCopied) { setTimeout(() => { setHasCopied(false); }, 1000); } }, [hasCopied]); return ( { setHasCopied(true); toast.success("倍刢成功", { duration: 1000 }); }} > ); } export function CodeViewer({ code, header, language, height, showLineNumbers = true, wrapLongLines = true, }: CodeViewerProps) { const lineProps: lineTagPropsFunction | HTMLProps | undefined = wrapLongLines ? { style: { overflowWrap: "break-word", whiteSpace: "pre-wrap" } } : undefined; return (
{header && (
{header}
)} {!header && (
)}
{code}
); } interface CodeViewerProps { code: string; language: string; header?: ReactNode; height?: string | number; showLineNumbers?: boolean; wrapLongLines?: boolean; lineProps?: (lineNumber: number) => React.HTMLProps; }