7
7
EyeIcon ,
8
8
CodeIcon
9
9
} from "lucide-react"
10
- import { FC , useState , useRef , useEffect } from "react"
10
+ import { FC , useState , useRef , useEffect , useCallback } from "react"
11
11
import { useTranslation } from "react-i18next"
12
12
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
13
13
import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism"
@@ -20,6 +20,9 @@ interface Props {
20
20
21
21
export const CodeBlock : FC < Props > = ( { language, value } ) => {
22
22
const [ isBtnPressed , setIsBtnPressed ] = useState ( false )
23
+ const [ previewValue , setPreviewValue ] = useState ( value )
24
+ const debounceTimeoutRef = useRef < NodeJS . Timeout | null > ( null )
25
+
23
26
const computeKey = ( ) => {
24
27
const base = `${ language } ::${ value ?. slice ( 0 , 200 ) } `
25
28
let hash = 0
@@ -61,8 +64,8 @@ export const CodeBlock: FC<Props> = ({ language, value }) => {
61
64
( language || "" ) . toLowerCase ( )
62
65
)
63
66
64
- const buildPreviewDoc = ( ) => {
65
- const code = value || ""
67
+ const buildPreviewDoc = useCallback ( ( ) => {
68
+ const code = previewValue || ""
66
69
if ( ( language || "" ) . toLowerCase ( ) === "svg" ) {
67
70
const hasSvgTag = / < s v g [ \s > ] / i. test ( code )
68
71
const svgMarkup = hasSvgTag
@@ -71,7 +74,7 @@ export const CodeBlock: FC<Props> = ({ language, value }) => {
71
74
return `<!doctype html><html><head><meta charset='utf-8'/><style>html,body{margin:0;padding:0;display:flex;align-items:center;justify-content:center;background:#fff;height:100%;}</style></head><body>${ svgMarkup } </body></html>`
72
75
}
73
76
return `<!doctype html><html><head><meta charset='utf-8'/></head><body>${ code } </body></html>`
74
- }
77
+ } , [ previewValue , language ] )
75
78
76
79
const handleDownload = ( ) => {
77
80
const blob = new Blob ( [ value ] , { type : "text/plain" } )
@@ -89,6 +92,22 @@ export const CodeBlock: FC<Props> = ({ language, value }) => {
89
92
globalStateMap . set ( keyRef . current , showPreview )
90
93
} , [ showPreview ] )
91
94
95
+ useEffect ( ( ) => {
96
+ if ( debounceTimeoutRef . current ) {
97
+ clearTimeout ( debounceTimeoutRef . current )
98
+ }
99
+
100
+ debounceTimeoutRef . current = setTimeout ( ( ) => {
101
+ setPreviewValue ( value )
102
+ } , 300 )
103
+
104
+ return ( ) => {
105
+ if ( debounceTimeoutRef . current ) {
106
+ clearTimeout ( debounceTimeoutRef . current )
107
+ }
108
+ }
109
+ } , [ value ] )
110
+
92
111
useEffect ( ( ) => {
93
112
const newKey = computeKey ( )
94
113
if ( newKey !== keyRef . current ) {
0 commit comments