react-shiki
Version:
Syntax highlighter component for react using shiki
237 lines (229 loc) • 7.96 kB
TypeScript
import { ReactNode } from 'react';
import { LanguageRegistration as LanguageRegistration$1, StringLiteralUnion, BundledLanguage, SpecialLanguage, ThemeRegistrationAny, BundledTheme, CodeOptionsMultipleThemes, CodeToHastOptionsCommon } from 'shiki';
import { Element as Element$1 } from 'hast';
/**
* Attribution:
* This code was written by github:hippotastic in expressive-code/expressive-code
* https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-shiki/src/languages.ts
*/
type IShikiRawRepository = LanguageRegistration$1['repository'];
type IShikiRawRule = IShikiRawRepository[keyof IShikiRawRepository];
type ILocation = IShikiRawRepository['$vscodeTextmateLocation'];
interface ILocatable {
readonly $vscodeTextmateLocation?: ILocation;
}
interface IRawRepositoryMap {
[name: string]: IRawRule;
}
type IRawRepository = IRawRepositoryMap & ILocatable;
interface IRawCapturesMap {
[captureId: string]: IRawRule;
}
type IRawCaptures = IRawCapturesMap & ILocatable;
interface IRawRule extends Omit<IShikiRawRule, 'applyEndPatternLast' | 'captures' | 'patterns'> {
readonly applyEndPatternLast?: boolean | number;
readonly captures?: IRawCaptures;
readonly comment?: string;
readonly patterns?: IRawRule[];
}
/**
* A less strict version of Shiki's `LanguageRegistration` interface that aligns better with
* actual grammars found in the wild. This version attempts to reduce the amount
* of type errors that would occur when importing and adding external grammars,
* while still being supported by the language processing code.
*/
interface LanguageRegistration extends Omit<LanguageRegistration$1, 'repository'> {
repository?: IRawRepository;
}
/**
* HTML Element, use to type `node` from react-markdown
*/
type Element = Element$1;
/**
* A Shiki BundledLanguage or a custom textmate grammar object
* @see https://shiki.style/languages
*/
type Language = LanguageRegistration | StringLiteralUnion<BundledLanguage | SpecialLanguage> | undefined;
/**
* A Shiki BundledTheme or a custom textmate theme object
* @see https://shiki.style/themes
*/
type Theme = ThemeRegistrationAny | StringLiteralUnion<BundledTheme>;
/**
* A map of color names to themes.
* This allows you to specify multiple themes for the generated code.
* Supports custom textmate theme objects in addition to Shiki's bundled themes
*
* @example
* ```ts
* useShikiHighlighter(code, language, {
* light: 'github-light',
* dark: 'github-dark',
* dim: 'github-dark-dimmed'
* })
* ```
*
* @see https://shiki.style/guide/dual-themes
*/
type Themes = {
[key: string]: ThemeRegistrationAny | StringLiteralUnion<BundledTheme>;
};
/**
* Configuration options specific to react-shiki
*/
interface ReactShikiOptions {
/**
* Minimum time (in milliseconds) between highlight operations.
* @default undefined (no throttling)
*/
delay?: number;
/**
* Custom textmate grammars to be preloaded for highlighting.
*/
customLanguages?: LanguageRegistration | LanguageRegistration[];
}
/**
* Configuration options for the syntax highlighter
*/
interface HighlighterOptions extends ReactShikiOptions, Pick<CodeOptionsMultipleThemes<BundledTheme>, 'defaultColor' | 'cssVariablePrefix'>, Pick<CodeToHastOptionsCommon, 'transformers'> {
}
/**
* A React hook that provides syntax highlighting using Shiki.
* Supports single theme and multi-theme highlighting, custom themes
* and languages, custom transformers, and optional throttling.
*
* ```ts
* // Basic Usage
* const highlightedCode = useShikiHighlighter( code, 'typescript', 'github-dark');
* ```
*
* ```ts
* // Custom Languages, Transformers, and Delay
* const highlightedCode = useShikiHighlighter(code, language, theme, {
* transformers: [customTransformer],
* delay: 150
* customLanguages: ['bosque', 'mcfunction']
* });
* ```
*
* ```ts
* // Multiple Themes, Custom Languages, Delay, and Custom Transformers
* const highlightedCode = useShikiHighlighter(
* code,
* language,
* {
* light: 'github-light',
* dark: 'github-dark',
* dim: 'github-dark-dimmed'
* },
* {
* delay: 150,
* defaultColor: 'dim',
* transformers: [customTransformer],
* customLanguages: ['bosque', 'mcfunction']
* }
* );
* ```
*/
declare const useShikiHighlighter: (code: string, lang: Language, themeInput: Theme | Themes, options?: HighlighterOptions) => ReactNode;
/**
* Rehype plugin to add an 'inline' property to <code> elements
* Sets 'inline' property to true if the <code> is not within a <pre> tag
*
* Pass this plugin to the `rehypePlugins` prop of react-markdown
* You can then access `inline` as a prop in components passed to react-markdown
*
* @example
* <ReactMarkdown rehypePlugins={[rehypeInlineCodeProperty]} />
*/
declare function rehypeInlineCodeProperty(): (tree: any) => undefined;
/**
* Function to determine if code is inline based on the presence of line breaks
*
* @example
* const isInline = node && isInlineCode(node: Element)
*/
declare const isInlineCode: (node: Element) => boolean;
/**
* Props for the ShikiHighlighter component
*/
interface ShikiHighlighterProps extends HighlighterOptions {
/**
* The programming language for syntax highlighting
* Supports custom textmate grammar objects in addition to Shiki's bundled languages
* @see https://shiki.style/languages
*/
language: Language;
/**
* The code to be highlighted
*/
children: string;
/**
* The color theme or themes for syntax highlighting
* Supports single, dual, or multiple themes
* Supports custom textmate theme objects in addition to Shiki's bundled themes
*
* @example
* theme='github-dark' // single theme
* theme={{ light: 'github-light', dark: 'github-dark' }} // multi-theme
*
* @see https://shiki.style/themes
*/
theme: Theme | Themes;
/**
* Controls the application of default styles to the generated code blocks
*
* Default styles include padding, overflow handling, border radius, language label styling, and font settings
* @default true
*/
addDefaultStyles?: boolean;
/**
* Add custom inline styles to the generated code block
*/
style?: React.CSSProperties;
/**
* Add custom inline styles to the language label
*/
langStyle?: React.CSSProperties;
/**
* Add custom CSS class names to the generated code block
*/
className?: string;
/**
* Add custom CSS class names to the language label
*/
langClassName?: string;
/**
* Whether to show the language label
* @default true
*/
showLanguage?: boolean;
/**
* The HTML element that wraps the generated code block.
* @default 'pre'
*/
as?: React.ElementType;
}
/**
* ShikiHighlighter is a React component that provides syntax highlighting for code snippets.
* It uses Shiki to render beautiful, theme-based syntax highlighting with optimized performance.
*
* @example
* ```tsx
* <ShikiHighlighter
* language="typescript"
* theme="github-dark"
* delay={100}
* transformers={[customTransformer]}
* addDefaultStyles={false}
* className="code-block"
* langClassName="lang-label"
* langStyle={{ color: 'blue' }},
* style={{ fontSize: '1.2rem' }}
* >
* {code}
* </ShikiHighlighter>
* ```
*/
declare const ShikiHighlighter: ({ language, theme, delay, transformers, defaultColor, cssVariablePrefix, addDefaultStyles, style, langStyle, className, langClassName, showLanguage, children: code, as: Element, customLanguages, }: ShikiHighlighterProps) => React.ReactElement;
export { type Element, type HighlighterOptions, type Language, type ShikiHighlighterProps, type Theme, type Themes, ShikiHighlighter as default, isInlineCode, rehypeInlineCodeProperty, useShikiHighlighter };