Files
Perplexica/src/components/MessageRenderer/CodeBlock/index.tsx
2025-12-19 16:26:51 +05:30

65 lines
1.7 KiB
TypeScript

'use client';
import { CheckIcon, CopyIcon } from '@phosphor-icons/react';
import React, { useEffect, useMemo, useState } from 'react';
import { useTheme } from 'next-themes';
import SyntaxHighlighter from 'react-syntax-highlighter';
import darkTheme from './CodeBlockDarkTheme';
import lightTheme from './CodeBlockLightTheme';
const CodeBlock = ({
language,
children,
}: {
language: string;
children: React.ReactNode;
}) => {
const { resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
const [copied, setCopied] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
const syntaxTheme = useMemo(() => {
if (!mounted) return lightTheme;
return resolvedTheme === 'dark' ? darkTheme : lightTheme;
}, [mounted, resolvedTheme]);
return (
<div className="relative">
<button
className="absolute top-2 right-2 p-1"
onClick={() => {
navigator.clipboard.writeText(children as string);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}}
>
{copied ? (
<CheckIcon
size={16}
className="absolute top-2 right-2 text-black/70 dark:text-white/70"
/>
) : (
<CopyIcon
size={16}
className="absolute top-2 right-2 transition duration-200 text-black/70 dark:text-white/70 hover:text-gray-800/70 hover:dark:text-gray-300/70"
/>
)}
</button>
<SyntaxHighlighter
language={language}
style={syntaxTheme}
showInlineLineNumbers
>
{children as string}
</SyntaxHighlighter>
</div>
);
};
export default CodeBlock;