import { Button, type ButtonProps } from "@/components/ui/button.tsx";
import { Check, Copy } from "lucide-react";
import { type HTMLProps, type ReactNode, useCallback, useEffect, useState } from "react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { useTranslation } from "react-i18next";
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 }: CopyButtonProps) {
const [hasCopied, setHasCopied] = useState(false);
const { t } = useTranslation();
useEffect(() => {
if (hasCopied) {
const timer = setTimeout(() => {
setHasCopied(false);
}, 1000);
return () => clearTimeout(timer);
}
}, [hasCopied]);
const handleCopy = useCallback(() => {
if (!hasCopied) {
setHasCopied(true);
toast.success(t("copySuccess"), { duration: 1000 });
}
}, [hasCopied, t]);
return (
);
}
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;
}