UNPKG

react-shiki

Version:

Syntax highlighter component for react using shiki

237 lines (229 loc) 7.96 kB
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 };