-
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathCodeHighlighter.tsx
More file actions
110 lines (105 loc) · 2.99 KB
/
CodeHighlighter.tsx
File metadata and controls
110 lines (105 loc) · 2.99 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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { Box, Code } from "@mantine/core";
import Prism from "prismjs";
import "prismjs/components/prism-bash";
import "prismjs/components/prism-shell-session";
import "prismjs/themes/prism-dark.css";
import "prismjs/themes/prism.css";
import { useEffect, useRef } from "react";
import { useNotifier } from "../../hooks/useNotifier";
import { ThemeName } from "../../theme/types";
import { NotificationType } from "../../types/notification";
import { getConfigForTheme } from "./config";
interface CodeHighlighterProps {
children: string;
className?: string;
copyButton?: boolean;
theme?: ThemeName;
}
export function CodeHighlighter({
children,
className,
copyButton,
theme,
}: CodeHighlighterProps) {
const codeRef = useRef<HTMLElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
const { setNotification } = useNotifier();
const config = getConfigForTheme(theme);
const finalCopyButton =
copyButton !== undefined ? copyButton : config.defaultCopyButton;
const language = "bash";
useEffect(() => {
if (codeRef.current) {
Prism.highlightElement(codeRef.current);
}
}, [children]);
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(children);
setNotification({
title: "Code copied to clipboard",
message: "The code has been copied to your clipboard.",
type: NotificationType.Success,
autoClose: true,
});
} catch (error) {
setNotification({
title: "Failed to copy code",
message: "The code has not been copied to your clipboard.",
type: NotificationType.Error,
autoClose: true,
});
console.error(error);
}
};
return (
<Box className={className}>
<Box
ref={containerRef}
pos="relative"
style={{
borderRadius: config.styling.borderRadius,
overflow: "hidden",
}}
>
{finalCopyButton && (
<Box pos="absolute" top={8} right={8} style={{ zIndex: 10 }}>
<Code
component="button"
onClick={handleCopy}
style={{
cursor: "pointer",
...config.styling.copyButtonStyle,
color: "inherit",
fontFamily: "inherit",
}}
>
Copy
</Code>
</Box>
)}
<pre
style={{
margin: 0,
padding: config.styling.padding,
background: config.styling.backgroundColor,
borderRadius: config.styling.borderRadius,
overflow: "auto",
fontSize: config.styling.fontSize,
lineHeight: config.styling.lineHeight,
}}
>
<code
ref={codeRef}
className={`language-${language}`}
style={{
fontFamily: "var(--mantine-font-family-monospace)",
}}
>
{children}
</code>
</pre>
</Box>
</Box>
);
}