@@ -29,20 +29,6 @@ function syntaxTokenStyle(token: SyntaxToken): CSSProperties {
2929 * Suspends while the grammar loads; wrap it in Suspense with the plain text as
3030 * the fallback.
3131 */
32- function useHighlightedLines (
33- highlighter : Awaited < ReturnType < typeof getSyntaxHighlighterPromise > > ,
34- code : string ,
35- language : string ,
36- embedded : ReadonlyArray < EmbeddedScript > ,
37- theme : "light" | "dark" ,
38- ) {
39- "use memo" ;
40- const themeName = resolveDiffThemeName ( theme ) ;
41- const tokenize = ( text : string , lang : string ) =>
42- highlighter . codeToTokens ( text , { lang, theme : themeName } ) . tokens ;
43- return keyedLines ( code , withEmbeddedScripts ( code , tokenize ( code , language ) , embedded , tokenize ) ) ;
44- }
45-
4632export function HighlightedTokens ( {
4733 code,
4834 language,
@@ -58,32 +44,44 @@ export function HighlightedTokens({
5844} ) {
5945 const highlighter = use ( getSyntaxHighlighterPromise ( language ) ) ;
6046 for ( const script of embedded ) use ( getSyntaxHighlighterPromise ( script . language ) ) ;
61- const lines = useHighlightedLines ( highlighter , code , language , embedded , theme ) ;
47+ const themeName = resolveDiffThemeName ( theme ) ;
48+ const tokenize = ( text : string , lang : string ) =>
49+ highlighter . codeToTokens ( text , { lang, theme : themeName } ) . tokens ;
50+ const lines = keyedLines (
51+ code ,
52+ withEmbeddedScripts ( code , tokenize ( code , language ) , embedded , tokenize ) ,
53+ ) ;
6254
63- return lines . map ( ( { key, tokens, ending } ) => (
64- < span key = { key } >
65- { wordClassName
66- ? wordsOf ( tokens ) . map ( ( part ) =>
67- typeof part === "string" ? (
68- part
69- ) : (
70- < span key = { part . key } className = { wordClassName } >
71- { part . pieces . map ( ( piece ) => (
72- < span key = { piece . key } style = { syntaxTokenStyle ( piece . token ) } >
73- { piece . text }
55+ // A fragment, not the bare array: the compiler only treats this as a component when it
56+ // returns JSX, since `use` alone does not count as a hook call for that inference.
57+ return (
58+ < >
59+ { lines . map ( ( { key, tokens, ending } ) => (
60+ < span key = { key } >
61+ { wordClassName
62+ ? wordsOf ( tokens ) . map ( ( part ) =>
63+ typeof part === "string" ? (
64+ part
65+ ) : (
66+ < span key = { part . key } className = { wordClassName } >
67+ { part . pieces . map ( ( piece ) => (
68+ < span key = { piece . key } style = { syntaxTokenStyle ( piece . token ) } >
69+ { piece . text }
70+ </ span >
71+ ) ) }
7472 </ span >
75- ) ) }
76- </ span >
77- ) ,
78- )
79- : tokens . map ( ( token ) => (
80- < span key = { ` ${ token . offset } : ${ token . content } ` } style = { syntaxTokenStyle ( token ) } >
81- { token . content }
82- </ span >
83- ) ) }
84- { ending }
85- </ span >
86- ) ) ;
73+ ) ,
74+ )
75+ : tokens . map ( ( token ) => (
76+ < span key = { ` ${ token . offset } : ${ token . content } ` } style = { syntaxTokenStyle ( token ) } >
77+ { token . content }
78+ </ span >
79+ ) ) }
80+ { ending }
81+ </ span >
82+ ) ) }
83+ </ >
84+ ) ;
8785}
8886
8987export function withEmbeddedScripts (
0 commit comments