Skip to content

Commit dbf1dd4

Browse files
committed
fix: remove shiki vercel not support this
Signed-off-by: Innei <[email protected]>
1 parent dd9619f commit dbf1dd4

File tree

3 files changed

+129
-16
lines changed

3 files changed

+129
-16
lines changed

src/components/ui/code-highlighter/CodeHighlighter.tsx

+60-15
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import React, { useCallback, useLayoutEffect, useRef } from 'react'
1+
import React, { useCallback, useInsertionEffect, useRef } from 'react'
22
import type { FC } from 'react'
33

44
import { useIsPrintMode } from '~/atoms/css-media'
55
import { useIsDark } from '~/hooks/common/use-is-dark'
6+
import { loadScript, loadStyleSheet } from '~/lib/load-script'
67
import { toast } from '~/lib/toast'
78

89
import styles from './CodeHighlighter.module.css'
9-
import { renderCodeHighlighter } from './render.server'
1010

1111
declare global {
1212
interface Window {
@@ -24,25 +24,70 @@ export const HighLighter: FC<Props> = (props) => {
2424

2525
const handleCopy = useCallback(() => {
2626
navigator.clipboard.writeText(value)
27-
toast.success('COPIED!')
27+
toast('COPIED!', 'success')
2828
}, [value])
2929

30+
const prevThemeCSS = useRef<ReturnType<typeof loadStyleSheet>>()
3031
const isPrintMode = useIsPrintMode()
3132
const isDark = useIsDark()
3233

33-
useLayoutEffect(() => {
34-
;(async () => {
35-
const html = await renderCodeHighlighter(
36-
value,
37-
language as string,
38-
isPrintMode ? 'github-light' : isDark ? 'github-dark' : 'github-light',
39-
)
40-
if (!ref.current) {
41-
return
34+
useInsertionEffect(() => {
35+
const css = loadStyleSheet(
36+
`https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism-themes/1.9.0/prism-one-${
37+
isPrintMode ? 'light' : isDark ? 'dark' : 'light'
38+
}.css`,
39+
)
40+
41+
if (prevThemeCSS.current) {
42+
const $prev = prevThemeCSS.current
43+
css.$link.onload = () => {
44+
$prev.remove()
4245
}
43-
ref.current.innerHTML = html
44-
})()
45-
}, [isDark, value, language, isPrintMode])
46+
}
47+
48+
prevThemeCSS.current = css
49+
}, [isDark, isPrintMode])
50+
useInsertionEffect(() => {
51+
loadStyleSheet(
52+
'https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism/1.23.0/plugins/line-numbers/prism-line-numbers.min.css',
53+
)
54+
55+
Promise.all([
56+
loadScript(
57+
'https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism/1.23.0/components/prism-core.min.js',
58+
),
59+
])
60+
.then(() =>
61+
Promise.all([
62+
loadScript(
63+
'https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism/1.23.0/plugins/autoloader/prism-autoloader.min.js',
64+
),
65+
loadScript(
66+
'https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/prism/1.23.0/plugins/line-numbers/prism-line-numbers.min.js',
67+
),
68+
]),
69+
)
70+
.then(() => {
71+
if (ref.current) {
72+
requestAnimationFrame(() => {
73+
window.Prism?.highlightElement(ref.current)
74+
75+
requestAnimationFrame(() => {
76+
window.Prism?.highlightElement(ref.current)
77+
})
78+
})
79+
} else {
80+
requestAnimationFrame(() => {
81+
window.Prism?.highlightAll()
82+
// highlightAll twice
83+
84+
requestAnimationFrame(() => {
85+
window.Prism?.highlightAll()
86+
})
87+
})
88+
}
89+
})
90+
}, [])
4691

4792
const ref = useRef<HTMLElement>(null)
4893
return (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React, { useCallback, useLayoutEffect, useRef } from 'react'
2+
import type { FC } from 'react'
3+
4+
import { useIsPrintMode } from '~/atoms/css-media'
5+
import { useIsDark } from '~/hooks/common/use-is-dark'
6+
import { toast } from '~/lib/toast'
7+
8+
import styles from './CodeHighlighter.module.css'
9+
import { renderCodeHighlighter } from './render.server'
10+
11+
declare global {
12+
interface Window {
13+
Prism: any
14+
}
15+
}
16+
17+
interface Props {
18+
lang: string | undefined
19+
content: string
20+
}
21+
22+
export const HighLighter: FC<Props> = (props) => {
23+
const { lang: language, content: value } = props
24+
25+
const handleCopy = useCallback(() => {
26+
navigator.clipboard.writeText(value)
27+
toast.success('COPIED!')
28+
}, [value])
29+
30+
const isPrintMode = useIsPrintMode()
31+
const isDark = useIsDark()
32+
33+
useLayoutEffect(() => {
34+
;(async () => {
35+
const html = await renderCodeHighlighter(
36+
value,
37+
language as string,
38+
isPrintMode ? 'github-light' : isDark ? 'github-dark' : 'github-light',
39+
)
40+
if (!ref.current) {
41+
return
42+
}
43+
ref.current.innerHTML = html
44+
})()
45+
}, [isDark, value, language, isPrintMode])
46+
47+
const ref = useRef<HTMLElement>(null)
48+
return (
49+
<div className={styles['code-wrap']}>
50+
<span className={styles['language-tip']} aria-hidden>
51+
{language?.toUpperCase()}
52+
</span>
53+
54+
<pre className="line-numbers !bg-transparent" data-start="1">
55+
<code
56+
className={`language-${language ?? 'markup'} !bg-transparent`}
57+
ref={ref}
58+
>
59+
{value}
60+
</code>
61+
</pre>
62+
63+
<div className={styles['copy-tip']} onClick={handleCopy} aria-hidden>
64+
Copy
65+
</div>
66+
</div>
67+
)
68+
}

tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"next-env.d.ts",
3535
"**/*.ts",
3636
"**/*.tsx",
37-
".next/types/**/*.ts"
37+
".next/types/**/*.ts",
3838
],
3939
"exclude": [
4040
"node_modules",

0 commit comments

Comments
 (0)