-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathSyntaxHighlighter.tsx
More file actions
82 lines (76 loc) · 2.32 KB
/
SyntaxHighlighter.tsx
File metadata and controls
82 lines (76 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import React from "react";
import { Prism as PrismHighlighter } from "react-syntax-highlighter";
import { oneLight } from "react-syntax-highlighter/dist/esm/styles/prism";
import { Check, Copy } from "lucide-react";
export interface SyntaxHighlighterProps {
/** Code content to highlight */
children: string;
/** Programming language for syntax highlighting */
language?: string;
/** Show copy button on hover (default: true) */
enableCopy?: boolean;
/** Custom styles to apply to the code block */
customStyle?: React.CSSProperties;
/** Additional class name for the container */
className?: string;
/** Show line numbers (default: false) */
showLineNumbers?: boolean;
}
const defaultStyle: React.CSSProperties = {
margin: 0,
padding: "0.75rem",
fontSize: "0.875rem",
overflow: "auto",
background: "#fafafa",
borderRadius: "0.375rem",
};
/**
* Syntax highlighter component using Prism.
* Supports copy-to-clipboard and configurable styling.
*/
export const SyntaxHighlighter: React.FC<SyntaxHighlighterProps> = ({
children,
language = "",
enableCopy = true,
customStyle,
className,
showLineNumbers = false,
}) => {
const [copied, setCopied] = React.useState(false);
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(children);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
} catch (err) {
console.error("Failed to copy code:", err);
}
};
return (
<div className={`group/codeblock relative ${className || ""}`}>
<PrismHighlighter
language={language}
style={oneLight}
PreTag="div"
showLineNumbers={showLineNumbers}
customStyle={{ ...defaultStyle, ...customStyle }}
>
{children}
</PrismHighlighter>
{enableCopy && (
<button
onClick={handleCopy}
className="absolute top-2 right-2 z-10 rounded border border-gray-200 bg-white p-1.5 text-gray-600 opacity-0 shadow-sm transition-opacity group-hover/codeblock:opacity-100 hover:bg-gray-50 hover:text-gray-800"
title={copied ? "Copied!" : "Copy code"}
>
{copied ? (
<Check className="h-3 w-3" />
) : (
<Copy className="h-3 w-3" />
)}
</button>
)}
</div>
);
};
export default SyntaxHighlighter;