1
- 'use server' ;
2
-
1
+ import { useEffect , useState } from 'react' ;
3
2
import { createHighlighter , Highlighter } from 'shiki' ;
4
- import { FC } from 'react' ;
5
3
6
4
interface ShikiHighlighterProps {
7
5
lang : string ;
@@ -21,30 +19,36 @@ const allowLanguages = [
21
19
'typescript' ,
22
20
] ;
23
21
24
- let highlighter : Highlighter | null = null ;
25
-
26
- // 初始化 Shiki highlighter
27
- const getHighlighter = async ( ) => {
28
- if ( ! highlighter ) {
29
- highlighter = await createHighlighter ( {
30
- themes : [ 'min-light' , 'nord' ] ,
31
- langs : [ ...allowLanguages ] ,
32
- } ) ;
33
- }
34
-
35
- return highlighter ;
36
- } ;
37
-
38
- export const ShikiHighlighter : FC < ShikiHighlighterProps > = async ( { lang, content } ) => {
39
- const highlighter = await getHighlighter ( ) ;
40
-
41
- const highlightedCode = highlighter . codeToHtml ( content , {
42
- lang : allowLanguages . includes ( lang ) ? lang : 'javascript' ,
43
- themes : {
44
- light : 'min-light' ,
45
- dark : 'nord' ,
46
- } ,
47
- } ) ;
48
-
49
- return < div className = "code-card" dangerouslySetInnerHTML = { { __html : highlightedCode } } /> ;
22
+ export const ShikiHighlighter : React . FC < ShikiHighlighterProps > = ( { lang, content } ) => {
23
+ const [ highlightedCode , setHighlightedCode ] = useState < string | null > ( null ) ;
24
+
25
+ useEffect ( ( ) => {
26
+ let highlighter : Highlighter ;
27
+
28
+ const loadHighlighter = async ( ) => {
29
+ highlighter = await createHighlighter ( {
30
+ themes : [ 'min-light' , 'nord' ] ,
31
+ langs : [ ...allowLanguages ] ,
32
+ } ) ;
33
+
34
+ const code = highlighter . codeToHtml ( content , {
35
+ lang : allowLanguages . includes ( lang ) ? lang : 'javascript' ,
36
+ themes : {
37
+ light : 'min-light' ,
38
+ dark : 'nord' ,
39
+ } ,
40
+ } ) ;
41
+ setHighlightedCode ( code ) ;
42
+ } ;
43
+
44
+ loadHighlighter ( ) ;
45
+
46
+ return ( ) => {
47
+ highlighter = null as any ;
48
+ } ;
49
+ } , [ lang , content ] ) ;
50
+
51
+ return highlightedCode ? (
52
+ < div className = "code-card" dangerouslySetInnerHTML = { { __html : highlightedCode } } />
53
+ ) : null ;
50
54
} ;
0 commit comments