From ec59b1096e70799f49a40955cca79d94287e450b Mon Sep 17 00:00:00 2001 From: Bassim Shahidy <122117267+AVGVSTVS96@users.noreply.github.com> Date: Wed, 29 Jan 2025 20:17:05 -0500 Subject: [PATCH] fix: Add langStyle prop, separate from style, update README (#8) fix: Add langStyle prop, separate from style, update README --- package/CHANGELOG.md | 7 ++++++ package/README.md | 18 +++++++++------ package/package.json | 2 +- package/src/ShikiHighlighter.tsx | 8 ++++++- package/src/useShiki.ts | 38 ++++++++++++++++---------------- 5 files changed, 45 insertions(+), 28 deletions(-) diff --git a/package/CHANGELOG.md b/package/CHANGELOG.md index 032ed05..513de5e 100644 --- a/package/CHANGELOG.md +++ b/package/CHANGELOG.md @@ -1,5 +1,12 @@ # react-shiki +## 0.2.3 + +### Patch Changes + +- Add `langStyle` prop, separate from code block's `style` + Update README + ## 0.2.2 ### Patch Changes diff --git a/package/README.md b/package/README.md index 703558a..a2514f9 100644 --- a/package/README.md +++ b/package/README.md @@ -4,7 +4,7 @@ > This package is still a work in progress, fully functional but not > extensively tested. -Performant server and client side syntax highlighting component + hook +Performant client side syntax highlighting component + hook for react using [Shiki](https://shiki.matsu.io/) [See the demo page with highlighted code blocks showcasing several Shiki themes!](https://react-shiki.vercel.app/) @@ -17,7 +17,7 @@ for react using [Shiki](https://shiki.matsu.io/) - [Usage](#usage) - [`react-markdown`](#react-markdown) - [Custom themes](#custom-themes) - - [Client-side highlighting](#client-side-highlighting) + - [Performance](#performance) - [Throttling real-time highlighting](#throttling-real-time-highlighting) - [Streaming and LLM chat UI](#streaming-and-llm-chat-ui) @@ -74,6 +74,8 @@ function CodeBlock() { } ``` +The `ShikiHighlighter` component will follow a similar API to `react-syntax-highlighter`, but uses Shiki and is optimized for performant sequential highlighting. As of now, not all of `react-syntax-highlighter` functionality is supported, but the goal of this component is to eventually act as a drop in replacement for `react-syntax-highlighter`. + The component accepts several props in addition to language and theme: - `showLanguage: boolean` - Shows the language name in the top right corner of @@ -84,13 +86,15 @@ The component accepts several props in addition to language and theme: - `delay: number` - Delay between highlights in milliseconds, useful for throttling rapid highlighting on the client - `className: string` - Class name to be passed to the component -- `style: object` - Style object to be passed to the component +- `style: object` - Inline style object to be passed to the component +- `langStyle: object` - Inline style object to be passed to the language label ```tsx function Houston() { return ( ; ``` -## Client-side highlighting +## Performance -react-shiki supports performance-optimized highlighting on the client. +`react-shiki` supports performance-optimized highlighting on the client. ### Throttling real-time highlighting @@ -190,7 +194,7 @@ const highlightedCode = useShikiHighlighter(code, language, theme, { ### Streaming and LLM chat UI -react-shiki can be used to highlight streamed code from LLM responses in real-time. +`react-shiki` can be used to highlight streamed code from LLM responses in real-time. I use it for an LLM chatbot UI, it renders markdown and highlights code in memoized chat messages. diff --git a/package/package.json b/package/package.json index da603ac..656ddcd 100644 --- a/package/package.json +++ b/package/package.json @@ -1,7 +1,7 @@ { "name": "react-shiki", "description": "Syntax highlighter component for react using shiki", - "version": "0.2.2", + "version": "0.2.3", "license": "MIT", "author": { "name": "Bassim Shahidy", diff --git a/package/src/ShikiHighlighter.tsx b/package/src/ShikiHighlighter.tsx index 20aa57b..978ddf9 100644 --- a/package/src/ShikiHighlighter.tsx +++ b/package/src/ShikiHighlighter.tsx @@ -46,6 +46,11 @@ export interface ShikiHighlighterProps extends HighlighterOptions { */ style?: React.CSSProperties; + /** + * Add custom inline styles to the language label + */ + langStyle?: React.CSSProperties; + /** * Add custom CSS class names to the generated code block */ @@ -85,6 +90,7 @@ export const ShikiHighlighter = ({ delay, addDefaultStyles = true, style, + langStyle, className, showLanguage = true, children: code, @@ -102,7 +108,7 @@ export const ShikiHighlighter = ({ style={style} > {showLanguage && language ? ( - + {language} ) : null} diff --git a/package/src/useShiki.ts b/package/src/useShiki.ts index 66ac642..874ba93 100644 --- a/package/src/useShiki.ts +++ b/package/src/useShiki.ts @@ -18,15 +18,15 @@ import type { import { removeTabIndexFromPre } from '@/utils'; -/************************************ - ** Singleton highlighter instance ** - ************************************/ +/** +* Singleton highlighter instance +*/ let highlighterPromise: Promise | null = null; -/*********************************************************** - ** Creates or returns the singleton highlighter instance ** - ***********************************************************/ +/** +* Creates or returns the singleton highlighter instance +*/ const makeHighlighter = async (theme: Theme): Promise => { if (!highlighterPromise) { highlighterPromise = createHighlighter({ @@ -41,9 +41,9 @@ const makeHighlighter = async (theme: Theme): Promise => { }; -/************************************************************ - ** Loads a theme dynamically if it hasn't been loaded yet ** - ************************************************************/ +/** +* Loads a theme dynamically if it hasn't been loaded yet +*/ const loadTheme = async ( highlighter: Highlighter, theme: Theme @@ -59,9 +59,9 @@ const loadTheme = async ( }; -/****************************************************************************** - ** Loads a language dynamically, falling back to plaintext if not available ** ** - ******************************************************************************/ +/** +* Loads a language dynamically, falling back to plaintext if not available +*/ const loadLanguage = async ( highlighter: Highlighter, lang: Language @@ -80,9 +80,9 @@ const loadLanguage = async ( }; -/******************************************************************************* - ** Throttles highlighting operations to prevent overwhelming the highlighter ** ** - *******************************************************************************/ +/** +* Optionally throttles rapid sequential highlighting operations to conserve resources +*/ const throttleHighlighting = ( performHighlight: () => Promise, timeoutControl: React.MutableRefObject, @@ -99,10 +99,10 @@ const throttleHighlighting = ( }; -/************************************************************************ - ** A React hook that provides syntax highlighting using Shiki. Uses a ** - ** singleton highlighter instance and supports throttled updates. ** -*************************************************************************/ +/** +* A React hook that provides syntax highlighting using Shiki. Uses a +* singleton highlighter instance and supports optional throttled highlights +*/ export const useShikiHighlighter = ( code: string, lang: Language,