From d1a9b0f811ce233feba3055fa83461e935158952 Mon Sep 17 00:00:00 2001 From: Innei Date: Tue, 10 Mar 2026 23:09:36 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(highlighter):=20add=20minimal?= =?UTF-8?q?=20shiki-based=20renderer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add minimal syntax highlighter and export public API - Refactor shiki usage to dynamic imports for langs/themes and streaming Made-with: Cursor --- src/Highlighter/LangSelect.tsx | 112 +++++++----- .../SyntaxHighlighter/StreamRenderer.tsx | 19 +- src/Highlighter/const.ts | 40 +---- src/Highlighter/langUtils.ts | 43 +++++ .../SyntaxHighlighterMinimal.tsx | 58 +++++++ src/HighlighterMinimal/highlighter.ts | 96 +++++++++++ src/HighlighterMinimal/index.ts | 3 + src/awesome/Spline/Spine.tsx | 103 ++++------- src/hooks/useHighlight.ts | 162 +++++++++--------- src/hooks/useStreamHighlight.ts | 37 ++-- src/index.ts | 5 + 11 files changed, 435 insertions(+), 243 deletions(-) create mode 100644 src/Highlighter/langUtils.ts create mode 100644 src/HighlighterMinimal/SyntaxHighlighterMinimal.tsx create mode 100644 src/HighlighterMinimal/highlighter.ts create mode 100644 src/HighlighterMinimal/index.ts diff --git a/src/Highlighter/LangSelect.tsx b/src/Highlighter/LangSelect.tsx index 5bb1c20dd..75fbf4f42 100644 --- a/src/Highlighter/LangSelect.tsx +++ b/src/Highlighter/LangSelect.tsx @@ -1,8 +1,7 @@ 'use client'; import { Select, type SelectProps } from 'antd'; -import { memo, useMemo } from 'react'; -import { bundledLanguagesInfo } from 'shiki'; +import { memo, useEffect, useState } from 'react'; import { Flexbox } from '@/Flex'; import MaterialFileTypeIcon from '@/MaterialFileTypeIcon'; @@ -10,51 +9,70 @@ import Text from '@/Text'; import { stopPropagation } from '@/utils/dom'; export const LangSelect = memo>(({ ...rest }) => { - const options = useMemo( - () => [ - { - aliases: ['text', 'txt'], - label: ( - - - - Plaintext - - - ), - value: 'plaintext', - }, - ...bundledLanguagesInfo.map((item) => ({ - aliases: item.aliases, - label: ( - - - - {item.name} - - - ), - title: (item.aliases || [item.id]) - .filter(Boolean) - .map((item) => `*.${item}`) - .join(','), - value: item.id, - })), - ], - [], - ); + const [options, setOptions] = useState([ + { + label: ( + + + + Plaintext + + + ), + value: 'plaintext', + }, + ]); + + useEffect(() => { + import('shiki/langs').then(({ bundledLanguagesInfo }) => { + setOptions([ + { + label: ( + + + + Plaintext + + + ), + value: 'plaintext', + }, + ...bundledLanguagesInfo.map((item) => ({ + label: ( + + + + {item.name} + + + ), + title: (item.aliases || [item.id]) + .filter(Boolean) + .map((item) => `*.${item}`) + .join(','), + value: item.id, + })), + ]); + }); + }, []); return (