1
1
"use client" ;
2
2
3
+ import hljs from "highlight.js" ;
4
+ // instead of atom-one-dark theme, there are a lot of others: https://highlightjs.org/demo
5
+ import "highlight.js/styles/atom-one-dark-reasonable.css" ;
3
6
import { Check , Copy , Download } from "lucide-react" ;
4
- import { FC , memo } from "react" ;
5
- import { Prism , SyntaxHighlighterProps } from "react-syntax-highlighter" ;
6
- import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism" ;
7
-
7
+ import { FC , memo , useEffect , useRef } from "react" ;
8
8
import { Button } from "../../button" ;
9
9
import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard" ;
10
10
11
- // TODO: Remove this when @type /react-syntax-highlighter is updated
12
- const SyntaxHighlighter = Prism as unknown as FC < SyntaxHighlighterProps > ;
13
-
14
11
interface Props {
15
12
language : string ;
16
13
value : string ;
14
+ className ?: string ;
17
15
}
18
16
19
17
interface languageMap {
@@ -56,8 +54,15 @@ export const generateRandomString = (length: number, lowercase = false) => {
56
54
return lowercase ? result . toLowerCase ( ) : result ;
57
55
} ;
58
56
59
- const CodeBlock : FC < Props > = memo ( ( { language, value } ) => {
57
+ const CodeBlock : FC < Props > = memo ( ( { language, value, className } ) => {
60
58
const { isCopied, copyToClipboard } = useCopyToClipboard ( { timeout : 2000 } ) ;
59
+ const codeRef = useRef < HTMLElement > ( null ) ;
60
+
61
+ useEffect ( ( ) => {
62
+ if ( codeRef . current && codeRef . current . dataset . highlighted !== "yes" ) {
63
+ hljs . highlightElement ( codeRef . current ) ;
64
+ }
65
+ } , [ language , value ] ) ;
61
66
62
67
const downloadAsFile = ( ) => {
63
68
if ( typeof window === "undefined" ) {
@@ -93,7 +98,9 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
93
98
} ;
94
99
95
100
return (
96
- < div className = "codeblock relative w-full bg-zinc-950 font-sans" >
101
+ < div
102
+ className = { `codeblock relative w-full bg-zinc-950 font-sans ${ className } ` }
103
+ >
97
104
< div className = "flex w-full items-center justify-between bg-zinc-800 px-6 py-2 pr-4 text-zinc-100" >
98
105
< span className = "text-xs lowercase" > { language } </ span >
99
106
< div className = "flex items-center space-x-1" >
@@ -111,26 +118,11 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
111
118
</ Button >
112
119
</ div >
113
120
</ div >
114
- < SyntaxHighlighter
115
- language = { language }
116
- style = { coldarkDark }
117
- PreTag = "div"
118
- showLineNumbers
119
- customStyle = { {
120
- width : "100%" ,
121
- background : "transparent" ,
122
- padding : "1.5rem 1rem" ,
123
- borderRadius : "0.5rem" ,
124
- } }
125
- codeTagProps = { {
126
- style : {
127
- fontSize : "0.9rem" ,
128
- fontFamily : "var(--font-mono)" ,
129
- } ,
130
- } }
131
- >
132
- { value }
133
- </ SyntaxHighlighter >
121
+ < pre className = "border border-zinc-700" >
122
+ < code ref = { codeRef } className = { `language-${ language } font-mono` } >
123
+ { value }
124
+ </ code >
125
+ </ pre >
134
126
</ div >
135
127
) ;
136
128
} ) ;
0 commit comments