react-shiki 0.11.1 → 0.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/core.d.mts +4 -7
- package/dist/core.mjs +3 -5
- package/dist/core.mjs.map +1 -1
- package/dist/{factory-DySLHBEo.mjs → factory-Ds5IsDw-.mjs} +4 -5
- package/dist/{factory-DySLHBEo.mjs.map → factory-Ds5IsDw-.mjs.map} +1 -1
- package/dist/index.d.mts +4 -7
- package/dist/index.mjs +4 -6
- package/dist/index.mjs.map +1 -1
- package/dist/{component-Cf8Topxy.mjs → plugins-C0Uf67_P.mjs} +125 -90
- package/dist/plugins-C0Uf67_P.mjs.map +1 -0
- package/dist/plugins-DdjjMnbY.d.mts +1208 -0
- package/dist/web.d.mts +4 -7
- package/dist/web.mjs +4 -6
- package/dist/web.mjs.map +1 -1
- package/package.json +51 -51
- package/dist/component-Cf8Topxy.mjs.map +0 -1
- package/dist/component-DlK6KonE.d.mts +0 -558
package/README.md
CHANGED
|
@@ -306,6 +306,7 @@ The core inputs, positional arguments on the hook, props/children on the compone
|
|
|
306
306
|
| Option | Type | Default | Description |
|
|
307
307
|
| ------------------- | ------------------ | --------------- | ----------------------------------------------------------------------------- |
|
|
308
308
|
| `delay` | `number` | - | Minimum time between highlights (in milliseconds), no throttling by default |
|
|
309
|
+
| `cache` | `Map` | - | Keeps highlighted output across unmounts, see [Caching Across Remounts](#caching-across-remounts) |
|
|
309
310
|
| `engine` | `'javascript' \| 'oniguruma' \| RegexEngine` | `'oniguruma'` | RegExp engine for syntax highlighting; named engines are created and cached internally |
|
|
310
311
|
| `highlighter` | `Highlighter \| HighlighterCore` | - | Custom highlighter instance, required for the core bundle |
|
|
311
312
|
| `outputFormat` | `string` | `'react'` | Output format: 'react' for React nodes, 'html' for HTML string, or 'tokens' for Shiki tokens (hook only, experimental) |
|
|
@@ -798,6 +799,22 @@ const highlightedCode = useShikiHighlighter(code, "tsx", "github-dark", {
|
|
|
798
799
|
});
|
|
799
800
|
```
|
|
800
801
|
|
|
802
|
+
### Caching Across Remounts
|
|
803
|
+
|
|
804
|
+
Lists that remount their content, like chat transcripts when switching threads or virtualized lists while scrolling, highlight every code block again by default. Pass a `Map` as `cache` and unchanged blocks paint on their first render instead:
|
|
805
|
+
|
|
806
|
+
```tsx
|
|
807
|
+
const cache = new Map();
|
|
808
|
+
|
|
809
|
+
<ShikiHighlighter language="tsx" theme="github-dark" cache={cache}>
|
|
810
|
+
{code}
|
|
811
|
+
</ShikiHighlighter>
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
- A block's output is stored when it unmounts, so the partial code of a streaming block is never cached.
|
|
815
|
+
- Entries are keyed by code, language, theme and options, so blocks with different settings can share one cache. Transformers are told apart by `name`, so give blocks with different transformers of the same name their own cache.
|
|
816
|
+
- The cache is yours: keep one per app or per conversation and `clear()` it when that content goes away.
|
|
817
|
+
|
|
801
818
|
---
|
|
802
819
|
|
|
803
820
|
Made with ❤️ by [Bassim (AVGVSTVS96)](https://github.com/AVGVSTVS96)
|
package/dist/core.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { a as EngineName, c as
|
|
1
|
+
import { a as EngineName, c as HighlighterOptions, d as OutputFormat, f as PreloadLanguage, h as UseShikiHighlighter, i as Element, l as HighlighterOptionsFor, m as Themes, n as rehypeInlineCodeProperty, o as HighlightCache, p as Theme, r as ShikiHighlighterProps, s as HighlightResult, t as isInlineCode, u as Language } from "./plugins-DdjjMnbY.mjs";
|
|
2
2
|
import { LanguageRegistration, TokensResult, createHighlighterCore } from "shiki/core";
|
|
3
3
|
import { createOnigurumaEngine } from "shiki/engine/oniguruma";
|
|
4
4
|
import { createJavaScriptRawEngine, createJavaScriptRegexEngine } from "shiki/engine/javascript";
|
|
5
|
-
//#region src/core.d.ts
|
|
6
5
|
/**
|
|
7
6
|
* Highlight code with shiki (core bundle)
|
|
8
7
|
*
|
|
@@ -36,12 +35,10 @@ import { createJavaScriptRawEngine, createJavaScriptRegexEngine } from "shiki/en
|
|
|
36
35
|
*
|
|
37
36
|
* Core bundle (minimal). For plug-and-play: `react-shiki` or `react-shiki/web`
|
|
38
37
|
*/
|
|
39
|
-
declare const useShikiHighlighter: UseShikiHighlighter;
|
|
38
|
+
export declare const useShikiHighlighter: UseShikiHighlighter;
|
|
40
39
|
/**
|
|
41
40
|
* ShikiHighlighter component using a custom highlighter.
|
|
42
41
|
* Requires a highlighter to be provided.
|
|
43
42
|
*/
|
|
44
|
-
declare const ShikiHighlighter: import("react").ForwardRefExoticComponent<ShikiHighlighterProps & import("react").RefAttributes<HTMLElement>>;
|
|
45
|
-
|
|
46
|
-
export { type Element, type EngineName, type HighlightResult, type HighlighterOptions, type HighlighterOptionsFor, type Language, type LanguageRegistration, type OutputFormat, type PreloadLanguage, ShikiHighlighter, ShikiHighlighter as default, type ShikiHighlighterProps, type Theme, type Themes, type TokensResult, type UseShikiHighlighter, createHighlighterCore, createJavaScriptRawEngine, createJavaScriptRegexEngine, createOnigurumaEngine, isInlineCode, rehypeInlineCodeProperty, useShikiHighlighter };
|
|
47
|
-
//# sourceMappingURL=core.d.mts.map
|
|
43
|
+
export declare const ShikiHighlighter: import("react").ForwardRefExoticComponent<ShikiHighlighterProps & import("react").RefAttributes<HTMLElement>>;
|
|
44
|
+
export { type Element, type EngineName, type HighlightCache, type HighlightResult, type HighlighterOptions, type HighlighterOptionsFor, type Language, type LanguageRegistration, type OutputFormat, type PreloadLanguage, ShikiHighlighter as default, type ShikiHighlighterProps, type Theme, type Themes, type TokensResult, type UseShikiHighlighter, createHighlighterCore, createJavaScriptRawEngine, createJavaScriptRegexEngine, createOnigurumaEngine, isInlineCode, rehypeInlineCodeProperty };
|
package/dist/core.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { i as useHighlight, n as
|
|
1
|
+
import { i as useHighlight, n as rehypeInlineCodeProperty, r as createShikiHighlighterComponent, t as isInlineCode } from "./plugins-C0Uf67_P.mjs";
|
|
2
2
|
import { createHighlighterCore } from "shiki/core";
|
|
3
3
|
import { createOnigurumaEngine } from "shiki/engine/oniguruma";
|
|
4
4
|
import { createJavaScriptRawEngine, createJavaScriptRegexEngine } from "shiki/engine/javascript";
|
|
5
|
-
|
|
5
|
+
// src/bundles/core.ts
|
|
6
6
|
/**
|
|
7
7
|
* Validates that a highlighter is provided for the core bundle.
|
|
8
8
|
* The core bundle requires users to provide their own highlighter instance.
|
|
@@ -11,8 +11,7 @@ function validateCoreHighlighter(highlighter) {
|
|
|
11
11
|
if (!highlighter) throw new Error("react-shiki/core requires a custom highlighter. Use createHighlighterCore() from react-shiki or switch to react-shiki for plug-and-play usage.");
|
|
12
12
|
return highlighter;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
//#region src/core.ts
|
|
14
|
+
// src/core.ts
|
|
16
15
|
/**
|
|
17
16
|
* Highlight code with shiki (core bundle)
|
|
18
17
|
*
|
|
@@ -58,7 +57,6 @@ const useShikiHighlighter = (code, lang, themeInput, options = {}) => {
|
|
|
58
57
|
* Requires a highlighter to be provided.
|
|
59
58
|
*/
|
|
60
59
|
const ShikiHighlighter = /*#__PURE__*/ createShikiHighlighterComponent(useShikiHighlighter);
|
|
61
|
-
//#endregion
|
|
62
60
|
export { ShikiHighlighter, ShikiHighlighter as default, createHighlighterCore, createJavaScriptRawEngine, createJavaScriptRegexEngine, createOnigurumaEngine, isInlineCode, rehypeInlineCodeProperty, useShikiHighlighter };
|
|
63
61
|
|
|
64
62
|
//# sourceMappingURL=core.mjs.map
|
package/dist/core.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.mjs","names":[],"sources":["../src/bundles/core.ts","../src/core.ts"],"sourcesContent":["import type { HighlighterCore } from 'shiki';\n\n/**\n * Validates that a highlighter is provided for the core bundle.\n * The core bundle requires users to provide their own highlighter instance.\n */\nexport function validateCoreHighlighter(\n highlighter: HighlighterCore | undefined\n): HighlighterCore {\n if (!highlighter) {\n throw new Error(\n 'react-shiki/core requires a custom highlighter. ' +\n 'Use createHighlighterCore() from react-shiki or switch to react-shiki for plug-and-play usage.'\n );\n }\n return highlighter;\n}\n","import { useHighlight } from './lib/hook';\nimport { validateCoreHighlighter } from './bundles/core';\nimport type { UseShikiHighlighter } from './lib/types';\
|
|
1
|
+
{"version":3,"file":"core.mjs","names":[],"sources":["../src/bundles/core.ts","../src/core.ts"],"sourcesContent":["import type { HighlighterCore } from 'shiki';\n\n/**\n * Validates that a highlighter is provided for the core bundle.\n * The core bundle requires users to provide their own highlighter instance.\n */\nexport function validateCoreHighlighter(\n highlighter: HighlighterCore | undefined\n): HighlighterCore {\n if (!highlighter) {\n throw new Error(\n 'react-shiki/core requires a custom highlighter. ' +\n 'Use createHighlighterCore() from react-shiki or switch to react-shiki for plug-and-play usage.'\n );\n }\n\n return highlighter;\n}\n","import { useHighlight } from './lib/hook';\nimport { validateCoreHighlighter } from './bundles/core';\nimport type { UseShikiHighlighter } from './lib/types';\nimport { createShikiHighlighterComponent } from './lib/component';\n// oxlint-disable-next-line unicorn/prefer-export-from -- `export type … from` here makes tsdown fold the core entry's declarations into the shared .d.mts chunk\nimport type { ShikiHighlighterProps } from './lib/component';\n\nexport { isInlineCode, rehypeInlineCodeProperty } from './lib/plugins';\n\nexport type { ShikiHighlighterProps };\n\nexport type {\n UseShikiHighlighter,\n Language,\n PreloadLanguage,\n Theme,\n Themes,\n Element,\n EngineName,\n HighlighterOptions,\n HighlighterOptionsFor,\n HighlightCache,\n HighlightResult,\n OutputFormat,\n} from './lib/types';\n\nexport { createHighlighterCore } from 'shiki/core';\n\nexport { createOnigurumaEngine } from 'shiki/engine/oniguruma';\n\nexport {\n createJavaScriptRegexEngine,\n createJavaScriptRawEngine,\n} from 'shiki/engine/javascript';\n\nexport type { LanguageRegistration, TokensResult } from 'shiki/core';\n\n/**\n * Highlight code with shiki (core bundle)\n *\n * @param code - Code to highlight\n * @param lang - Language (bundled or custom)\n * @param theme - Theme (bundled, multi-theme, or custom)\n * @param options - react-shiki options + shiki options\n * @returns Highlighted code as React elements (default), HTML string, or Shiki tokens, based on `outputFormat`\n *\n * @example\n * ```tsx\n * import { createHighlighterCore, createOnigurumaEngine } from 'react-shiki/core';\n *\n *\n * const highlighter = await createHighlighterCore({\n * themes: [import('@shikijs/themes/github-light'), import('@shikijs/themes/github-dark')],\n * langs: [import('@shikijs/langs/typescript')],\n * engine: createOnigurumaEngine(import('shiki/wasm'))\n * });\n *\n * const highlighted = useShikiHighlighter(\n * 'const x = 1;',\n * 'typescript',\n * {\n * light: 'github-light',\n * dark: 'github-dark'\n * },\n * { highlighter }\n * );\n * ```\n *\n * Core bundle (minimal). For plug-and-play: `react-shiki` or `react-shiki/web`\n */\nexport const useShikiHighlighter: UseShikiHighlighter = (\n code,\n lang,\n themeInput,\n options = {}\n) => {\n const highlighter = validateCoreHighlighter(options.highlighter);\n\n return useHighlight(\n code,\n lang,\n themeInput,\n {\n ...options,\n highlighter,\n },\n async () => highlighter\n );\n};\n\n/**\n * ShikiHighlighter component using a custom highlighter.\n * Requires a highlighter to be provided.\n */\nexport const ShikiHighlighter =\n // oxlint-disable-next-line eslint/no-inline-comments -- the #__PURE__ annotation lets bundlers drop the component when only the hook is used\n /*#__PURE__*/ createShikiHighlighterComponent(useShikiHighlighter);\n\nexport default ShikiHighlighter;\n"],"mappings":";;;;;;;;;AAMA,SAAgB,wBACd,aACiB;CACjB,IAAI,CAAC,aACH,MAAM,IAAI,MACR,gJAEF;CAGF,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACqDA,MAAa,uBACX,MACA,MACA,YACA,UAAU,CAAC,MACR;CACH,MAAM,cAAc,wBAAwB,QAAQ,WAAW;CAE/D,OAAO,aACL,MACA,MACA,YACA;EACE,GAAG;EACH;CACF,GACA,YAAY,WACd;AACF;;;;;AAMA,MAAa,mBAEG,8CAAgC,mBAAmB"}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { a as isLoadableLanguage } from "./
|
|
1
|
+
import { a as isLoadableLanguage } from "./plugins-C0Uf67_P.mjs";
|
|
2
2
|
import { createOnigurumaEngine } from "shiki/engine/oniguruma";
|
|
3
|
-
|
|
3
|
+
// src/bundles/factory.ts
|
|
4
4
|
/**
|
|
5
5
|
* Builds a highlighter factory for a Shiki bundle (full or web).
|
|
6
6
|
* Unloadable languages are filtered out so unknown ids fall back to
|
|
7
7
|
* plaintext instead of throwing.
|
|
8
8
|
*/
|
|
9
|
-
const bundledHighlighterFactory = (getSingletonHighlighter, bundledLanguages) => (langsToLoad, themesToLoad, engine) => getSingletonHighlighter({
|
|
9
|
+
const bundledHighlighterFactory = (getSingletonHighlighter, bundledLanguages) => async (langsToLoad, themesToLoad, engine) => await getSingletonHighlighter({
|
|
10
10
|
langs: langsToLoad.filter((lang) => isLoadableLanguage(lang, bundledLanguages)),
|
|
11
11
|
themes: themesToLoad,
|
|
12
12
|
engine: engine ?? createOnigurumaEngine(import("shiki/wasm"))
|
|
13
13
|
});
|
|
14
|
-
//#endregion
|
|
15
14
|
export { bundledHighlighterFactory as t };
|
|
16
15
|
|
|
17
|
-
//# sourceMappingURL=factory-
|
|
16
|
+
//# sourceMappingURL=factory-Ds5IsDw-.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory-
|
|
1
|
+
{"version":3,"file":"factory-Ds5IsDw-.mjs","names":[],"sources":["../src/bundles/factory.ts"],"sourcesContent":["import { createOnigurumaEngine } from 'shiki/engine/oniguruma';\nimport type {\n Awaitable,\n DynamicImportLanguageRegistration,\n HighlighterCore,\n RegexEngine,\n} from 'shiki/core';\nimport type {\n HighlighterFactory,\n PreloadLanguage,\n Theme,\n} from '../lib/types';\nimport { isLoadableLanguage } from '../lib/language';\n\ntype GetSingletonHighlighter = (options: {\n langs: NonNullable<PreloadLanguage>[];\n themes: Theme[];\n engine: Awaitable<RegexEngine>;\n}) => Promise<HighlighterCore>;\n\n/**\n * Builds a highlighter factory for a Shiki bundle (full or web).\n * Unloadable languages are filtered out so unknown ids fall back to\n * plaintext instead of throwing.\n */\nexport const bundledHighlighterFactory =\n (\n getSingletonHighlighter: GetSingletonHighlighter,\n bundledLanguages: Record<string, DynamicImportLanguageRegistration>\n ): HighlighterFactory =>\n async (langsToLoad, themesToLoad, engine) =>\n await getSingletonHighlighter({\n langs: langsToLoad.filter((lang) =>\n isLoadableLanguage(lang, bundledLanguages)\n ),\n themes: themesToLoad,\n engine: engine ?? createOnigurumaEngine(import('shiki/wasm')),\n });\n"],"mappings":";;;;;;;;AAyBA,MAAa,6BAET,yBACA,qBAEF,OAAO,aAAa,cAAc,WAChC,MAAM,wBAAwB;CAC5B,OAAO,YAAY,QAAQ,SACzB,mBAAmB,MAAM,gBAAgB,CAC3C;CACA,QAAQ;CACR,QAAQ,UAAU,sBAAsB,OAAO,aAAa;AAC9D,CAAC"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { a as EngineName, c as
|
|
1
|
+
import { a as EngineName, c as HighlighterOptions, d as OutputFormat, f as PreloadLanguage, h as UseShikiHighlighter, i as Element, l as HighlighterOptionsFor, m as Themes, n as rehypeInlineCodeProperty, o as HighlightCache, p as Theme, r as ShikiHighlighterProps, s as HighlightResult, t as isInlineCode, u as Language } from "./plugins-DdjjMnbY.mjs";
|
|
2
2
|
import { LanguageRegistration, TokensResult } from "shiki";
|
|
3
3
|
import { createJavaScriptRawEngine, createJavaScriptRegexEngine } from "shiki/engine/javascript";
|
|
4
|
-
//#region src/index.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Highlight code with shiki (full bundle)
|
|
7
6
|
*
|
|
@@ -25,12 +24,10 @@ import { createJavaScriptRawEngine, createJavaScriptRegexEngine } from "shiki/en
|
|
|
25
24
|
*
|
|
26
25
|
* Full bundle (~6.4MB minified, 1.2MB gzipped). For smaller bundles: `react-shiki/web` or `react-shiki/core`
|
|
27
26
|
*/
|
|
28
|
-
declare const useShikiHighlighter: UseShikiHighlighter;
|
|
27
|
+
export declare const useShikiHighlighter: UseShikiHighlighter;
|
|
29
28
|
/**
|
|
30
29
|
* ShikiHighlighter component using the full bundle.
|
|
31
30
|
* Includes all languages and themes for maximum compatibility.
|
|
32
31
|
*/
|
|
33
|
-
declare const ShikiHighlighter: import("react").ForwardRefExoticComponent<ShikiHighlighterProps & import("react").RefAttributes<HTMLElement>>;
|
|
34
|
-
|
|
35
|
-
export { type Element, type EngineName, type HighlightResult, type HighlighterOptions, type HighlighterOptionsFor, type Language, type LanguageRegistration, type OutputFormat, type PreloadLanguage, ShikiHighlighter, ShikiHighlighter as default, type ShikiHighlighterProps, type Theme, type Themes, type TokensResult, type UseShikiHighlighter, createJavaScriptRawEngine, createJavaScriptRegexEngine, isInlineCode, rehypeInlineCodeProperty, useShikiHighlighter };
|
|
36
|
-
//# sourceMappingURL=index.d.mts.map
|
|
32
|
+
export declare const ShikiHighlighter: import("react").ForwardRefExoticComponent<ShikiHighlighterProps & import("react").RefAttributes<HTMLElement>>;
|
|
33
|
+
export { type Element, type EngineName, type HighlightCache, type HighlightResult, type HighlighterOptions, type HighlighterOptionsFor, type Language, type LanguageRegistration, type OutputFormat, type PreloadLanguage, ShikiHighlighter as default, type ShikiHighlighterProps, type Theme, type Themes, type TokensResult, type UseShikiHighlighter, createJavaScriptRawEngine, createJavaScriptRegexEngine, isInlineCode, rehypeInlineCodeProperty };
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { i as useHighlight, n as
|
|
2
|
-
import { t as bundledHighlighterFactory } from "./factory-
|
|
1
|
+
import { i as useHighlight, n as rehypeInlineCodeProperty, r as createShikiHighlighterComponent, t as isInlineCode } from "./plugins-C0Uf67_P.mjs";
|
|
2
|
+
import { t as bundledHighlighterFactory } from "./factory-Ds5IsDw-.mjs";
|
|
3
3
|
import { bundledLanguages, getSingletonHighlighter } from "shiki";
|
|
4
4
|
import { createJavaScriptRawEngine, createJavaScriptRegexEngine } from "shiki/engine/javascript";
|
|
5
|
-
|
|
5
|
+
// src/bundles/full.ts
|
|
6
6
|
/**
|
|
7
7
|
* Highlighter factory for the full Shiki bundle: every language and
|
|
8
8
|
* theme, largest size, maximum compatibility.
|
|
9
9
|
*/
|
|
10
10
|
const createFullHighlighter = bundledHighlighterFactory(getSingletonHighlighter, bundledLanguages);
|
|
11
|
-
|
|
12
|
-
//#region src/index.ts
|
|
11
|
+
// src/index.ts
|
|
13
12
|
/**
|
|
14
13
|
* Highlight code with shiki (full bundle)
|
|
15
14
|
*
|
|
@@ -39,7 +38,6 @@ const useShikiHighlighter = (code, lang, themeInput, options = {}) => useHighlig
|
|
|
39
38
|
* Includes all languages and themes for maximum compatibility.
|
|
40
39
|
*/
|
|
41
40
|
const ShikiHighlighter = /*#__PURE__*/ createShikiHighlighterComponent(useShikiHighlighter);
|
|
42
|
-
//#endregion
|
|
43
41
|
export { ShikiHighlighter, ShikiHighlighter as default, createJavaScriptRawEngine, createJavaScriptRegexEngine, isInlineCode, rehypeInlineCodeProperty, useShikiHighlighter };
|
|
44
42
|
|
|
45
43
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/bundles/full.ts","../src/index.ts"],"sourcesContent":["import { getSingletonHighlighter, bundledLanguages } from 'shiki';\nimport { bundledHighlighterFactory } from './factory';\n\n/**\n * Highlighter factory for the full Shiki bundle: every language and\n * theme, largest size, maximum compatibility.\n */\nexport const createFullHighlighter = bundledHighlighterFactory(\n getSingletonHighlighter,\n bundledLanguages\n);\n","import { useHighlight } from './lib/hook';\nimport { createFullHighlighter } from './bundles/full';\nimport type { UseShikiHighlighter } from './lib/types';\
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/bundles/full.ts","../src/index.ts"],"sourcesContent":["import { getSingletonHighlighter, bundledLanguages } from 'shiki';\nimport { bundledHighlighterFactory } from './factory';\n\n/**\n * Highlighter factory for the full Shiki bundle: every language and\n * theme, largest size, maximum compatibility.\n */\nexport const createFullHighlighter = bundledHighlighterFactory(\n getSingletonHighlighter,\n bundledLanguages\n);\n","import { useHighlight } from './lib/hook';\nimport { createFullHighlighter } from './bundles/full';\nimport type { UseShikiHighlighter } from './lib/types';\nimport { createShikiHighlighterComponent } from './lib/component';\n// oxlint-disable-next-line unicorn/prefer-export-from -- `export type … from` here makes tsdown fold the core entry's declarations into the shared .d.mts chunk\nimport type { ShikiHighlighterProps } from './lib/component';\n\nexport { isInlineCode, rehypeInlineCodeProperty } from './lib/plugins';\n\nexport type { ShikiHighlighterProps };\n\nexport type {\n UseShikiHighlighter,\n Language,\n PreloadLanguage,\n Theme,\n Themes,\n Element,\n EngineName,\n HighlighterOptions,\n HighlighterOptionsFor,\n HighlightCache,\n HighlightResult,\n OutputFormat,\n} from './lib/types';\n\nexport {\n createJavaScriptRegexEngine,\n createJavaScriptRawEngine,\n} from 'shiki/engine/javascript';\n\nexport type { LanguageRegistration, TokensResult } from 'shiki';\n\n/**\n * Highlight code with shiki (full bundle)\n *\n * @param code - Code to highlight\n * @param lang - Language (bundled or custom)\n * @param theme - Theme (bundled, multi-theme, or custom)\n * @param options - react-shiki options + shiki options\n * @returns Highlighted code as React elements (default), HTML string, or Shiki tokens, based on `outputFormat`\n *\n * @example\n * ```tsx\n * const highlighted = useShikiHighlighter(\n * 'const x = 1;',\n * 'typescript',\n * {\n * light: 'github-light',\n * dark: 'github-dark'\n * }\n * );\n * ```\n *\n * Full bundle (~6.4MB minified, 1.2MB gzipped). For smaller bundles: `react-shiki/web` or `react-shiki/core`\n */\nexport const useShikiHighlighter: UseShikiHighlighter = (\n code,\n lang,\n themeInput,\n options = {}\n) => useHighlight(code, lang, themeInput, options, createFullHighlighter);\n\n/**\n * ShikiHighlighter component using the full bundle.\n * Includes all languages and themes for maximum compatibility.\n */\nexport const ShikiHighlighter =\n // oxlint-disable-next-line eslint/no-inline-comments -- the #__PURE__ annotation lets bundlers drop the component when only the hook is used\n /*#__PURE__*/ createShikiHighlighterComponent(useShikiHighlighter);\n\nexport default ShikiHighlighter;\n"],"mappings":";;;;;;;;;AAOA,MAAa,wBAAwB,0BACnC,yBACA,gBACF;;;;;;;;;;;;;;;;;;;;;;;;;AC8CA,MAAa,uBACX,MACA,MACA,YACA,UAAU,CAAC,MACR,aAAa,MAAM,MAAM,YAAY,SAAS,qBAAqB;;;;;AAMxE,MAAa,mBAEG,8CAAgC,mBAAmB"}
|
|
@@ -4,9 +4,9 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
|
|
5
5
|
import { dequal } from "dequal";
|
|
6
6
|
import { guessEmbeddedLanguages, isSpecialLang } from "shiki/core";
|
|
7
|
-
import { visit } from "unist-util-visit";
|
|
8
7
|
import { clsx } from "clsx";
|
|
9
|
-
|
|
8
|
+
import { visit } from "unist-util-visit";
|
|
9
|
+
// src/lib/utils.ts
|
|
10
10
|
/**
|
|
11
11
|
* Returns a referentially stable version of `value` that only updates when content changes.
|
|
12
12
|
* Uses reference equality as a fast path and deep comparison to prevent unnecessary updates.
|
|
@@ -35,14 +35,11 @@ const throttleHighlighting = (performHighlight, timeoutControl, throttleMs) => {
|
|
|
35
35
|
timeoutControl.current.nextAllowedTime = Date.now() + throttleMs;
|
|
36
36
|
}, delay);
|
|
37
37
|
};
|
|
38
|
-
|
|
39
|
-
//#region src/styles/component.css?inline
|
|
38
|
+
// src/styles/component.css?inline
|
|
40
39
|
var component_default = ":where(.rs-root){position:relative}:where(.rs-root.rs-default-styles pre){border-radius:.5rem;padding-block:1.25rem;padding-inline:1.5rem;overflow:auto}:where(.rs-root .rs-language-label){z-index:1;letter-spacing:-.05em;color:#6b7280d9;font-family:monospace;font-size:.75rem;position:absolute;top:.5rem;right:.75rem}\n";
|
|
41
|
-
|
|
42
|
-
//#region src/styles/features.css?inline
|
|
40
|
+
// src/styles/features.css?inline
|
|
43
41
|
var features_default = ":where(.rs-has-line-numbers){counter-reset:line-number calc(var(--line-start,1) - 1)}:where(.rs-has-line-numbers .rs-line-number):before{counter-increment:line-number;content:counter(line-number);box-sizing:content-box;min-width:var(--rs-line-numbers-width,2ch);padding-left:var(--rs-line-numbers-padding-left,0ch);padding-right:var(--rs-line-numbers-padding-right,2ch);color:var(--rs-line-numbers-foreground,#6b728080);font-size:var(--rs-line-numbers-font-size,inherit);font-weight:var(--rs-line-numbers-font-weight,inherit);line-height:var(--rs-line-numbers-line-height,inherit);font-family:var(--rs-line-numbers-font-family,inherit);opacity:var(--rs-line-numbers-opacity,1);user-select:none;pointer-events:none;justify-content:flex-end;align-items:flex-start;display:inline-flex}:where(.rs-has-highlighted-lines){width:fit-content;min-width:100%;display:block}:where(.rs-highlighted-line){--_rs-hl-background:var(--rs-highlighted-line-background,color-mix(in srgb, currentColor 10%, transparent));background-color:var(--_rs-hl-background);width:100%;min-height:1lh;display:inline-block}:where(.rs-default-styles .rs-highlighted-line){border-image:linear-gradient(var(--_rs-hl-background) 0 0) fill 0 / 0 / 0 100vw;background-color:#0000}:where(.rs-has-line-numbers .rs-highlighted-line):before{color:var(--rs-highlighted-line-number-foreground,color-mix(in srgb, currentColor 65%, transparent))}\n";
|
|
44
|
-
|
|
45
|
-
//#region src/lib/styles.ts
|
|
42
|
+
// src/lib/styles.ts
|
|
46
43
|
const injected = /* @__PURE__ */ new Set();
|
|
47
44
|
const useStyleInsertionEffect = React.useInsertionEffect ?? React.useLayoutEffect;
|
|
48
45
|
const inject = (css, key) => {
|
|
@@ -71,10 +68,12 @@ const useFeatureStyles = (enabled) => {
|
|
|
71
68
|
if (enabled) inject(features_default, "features");
|
|
72
69
|
}, [enabled]);
|
|
73
70
|
};
|
|
74
|
-
|
|
75
|
-
//#region src/lib/language.ts
|
|
71
|
+
// src/lib/language.ts
|
|
76
72
|
const FALLBACK_LANGUAGE = "plaintext";
|
|
77
|
-
const toArray = (value) =>
|
|
73
|
+
const toArray = (value) => {
|
|
74
|
+
if (value == null) return [];
|
|
75
|
+
return Array.isArray(value) ? value : [value];
|
|
76
|
+
};
|
|
78
77
|
const isDynamicLanguage = (lang) => typeof lang === "function" || lang instanceof Promise || Array.isArray(lang) || typeof lang === "object" && lang != null && "default" in lang;
|
|
79
78
|
const isRegistration = (lang) => typeof lang === "object" && lang != null && !isDynamicLanguage(lang);
|
|
80
79
|
/** Dedupe identity: strings and registrations by value, dynamic inputs by reference */
|
|
@@ -144,17 +143,15 @@ const getEmbeddedLanguages = (code, languageId, highlighter) => {
|
|
|
144
143
|
const bundled = highlighter.getBundledLanguages();
|
|
145
144
|
return guessEmbeddedLanguages(code, languageId).flatMap((language) => bundled[language] ?? []);
|
|
146
145
|
};
|
|
147
|
-
|
|
148
|
-
//#region src/lib/theme.ts
|
|
146
|
+
// src/lib/theme.ts
|
|
149
147
|
const DEFAULT_THEMES = {
|
|
150
148
|
light: "github-light",
|
|
151
149
|
dark: "github-dark"
|
|
152
150
|
};
|
|
153
151
|
const isTextmateTheme = (value) => {
|
|
154
152
|
if (typeof value !== "object" || value === null) return false;
|
|
155
|
-
const
|
|
156
|
-
const
|
|
157
|
-
const hasIdentity = typeof v.name === "string" || typeof v.type === "string";
|
|
153
|
+
const hasTokens = "tokenColors" in value && Array.isArray(value.tokenColors) || "settings" in value && Array.isArray(value.settings);
|
|
154
|
+
const hasIdentity = "name" in value && typeof value.name === "string" || "type" in value && typeof value.type === "string";
|
|
158
155
|
return hasTokens && hasIdentity;
|
|
159
156
|
};
|
|
160
157
|
function resolveTheme(themeInput) {
|
|
@@ -179,12 +176,17 @@ function resolveTheme(themeInput) {
|
|
|
179
176
|
themesToLoad: validEntries.map(([, value]) => value)
|
|
180
177
|
};
|
|
181
178
|
}
|
|
182
|
-
|
|
183
|
-
//#region src/lib/engine.ts
|
|
179
|
+
// src/lib/engine.ts
|
|
184
180
|
const engines = /* @__PURE__ */ new Map();
|
|
185
181
|
const loaders = {
|
|
186
|
-
javascript:
|
|
187
|
-
|
|
182
|
+
javascript: async () => {
|
|
183
|
+
const { createJavaScriptRegexEngine } = await import("shiki/engine/javascript");
|
|
184
|
+
return createJavaScriptRegexEngine();
|
|
185
|
+
},
|
|
186
|
+
oniguruma: async () => {
|
|
187
|
+
const { createOnigurumaEngine } = await import("shiki/engine/oniguruma");
|
|
188
|
+
return await createOnigurumaEngine(import("shiki/wasm"));
|
|
189
|
+
}
|
|
188
190
|
};
|
|
189
191
|
/**
|
|
190
192
|
* Resolves a named engine to a lazily created, cached instance.
|
|
@@ -195,17 +197,15 @@ const loaders = {
|
|
|
195
197
|
*/
|
|
196
198
|
const resolveEngine = (engine) => {
|
|
197
199
|
if (typeof engine !== "string") return engine;
|
|
198
|
-
|
|
199
|
-
if (!load) throw new Error(`[react-shiki] unknown engine '${engine}', expected 'javascript' or 'oniguruma'`);
|
|
200
|
+
if (!Object.hasOwn(loaders, engine)) throw new Error(`[react-shiki] unknown engine '${engine}', expected 'javascript' or 'oniguruma'`);
|
|
200
201
|
const cached = engines.get(engine);
|
|
201
202
|
if (cached) return cached;
|
|
202
|
-
const instance =
|
|
203
|
+
const instance = loaders[engine]();
|
|
203
204
|
instance.catch(() => engines.delete(engine));
|
|
204
205
|
engines.set(engine, instance);
|
|
205
206
|
return instance;
|
|
206
207
|
};
|
|
207
|
-
|
|
208
|
-
//#region src/lib/transformers.ts
|
|
208
|
+
// src/lib/transformers.ts
|
|
209
209
|
const toLineNumberSet = (lineNumbers) => new Set(lineNumbers.filter(Number.isInteger));
|
|
210
210
|
/**
|
|
211
211
|
* Creates a transformer that enables line numbers display
|
|
@@ -249,8 +249,7 @@ function highlightedLinesTransformer(lineNumbers, startLine = 1) {
|
|
|
249
249
|
}
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
|
-
|
|
253
|
-
//#region src/lib/options.ts
|
|
252
|
+
// src/lib/options.ts
|
|
254
253
|
const buildThemeOptions = (resolvedTheme, defaultColor, cssVariablePrefix) => {
|
|
255
254
|
if (resolvedTheme.isMulti) return {
|
|
256
255
|
themes: resolvedTheme.themes,
|
|
@@ -261,7 +260,7 @@ const buildThemeOptions = (resolvedTheme, defaultColor, cssVariablePrefix) => {
|
|
|
261
260
|
};
|
|
262
261
|
const buildShikiOptions = (languageId, resolvedTheme, options) => {
|
|
263
262
|
const { delay, customLanguages, preloadLanguages, outputFormat, highlighter, langAlias, engine, defaultColor, cssVariablePrefix, showLineNumbers, startingLineNumber, highlightLineNumbers, transformers: userTransformers, ...shikiPassthrough } = options;
|
|
264
|
-
const transformers = [...userTransformers
|
|
263
|
+
const transformers = [...userTransformers ?? []];
|
|
265
264
|
if (showLineNumbers) transformers.push(lineNumbersTransformer(startingLineNumber));
|
|
266
265
|
if (highlightLineNumbers?.length) transformers.push(highlightedLinesTransformer(highlightLineNumbers, startingLineNumber));
|
|
267
266
|
return {
|
|
@@ -271,8 +270,7 @@ const buildShikiOptions = (languageId, resolvedTheme, options) => {
|
|
|
271
270
|
transformers
|
|
272
271
|
};
|
|
273
272
|
};
|
|
274
|
-
|
|
275
|
-
//#region src/lib/hook.ts
|
|
273
|
+
// src/lib/hook.ts
|
|
276
274
|
async function highlight(code, resolved, opts, factory) {
|
|
277
275
|
const { languageId, langsToLoad, themesToLoad, shikiOptions } = resolved;
|
|
278
276
|
const format = opts.outputFormat ?? "react";
|
|
@@ -297,12 +295,19 @@ async function highlight(code, resolved, opts, factory) {
|
|
|
297
295
|
};
|
|
298
296
|
return (outputs[format] ?? outputs.react)();
|
|
299
297
|
}
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
298
|
+
const readCache = (cache, key) => {
|
|
299
|
+
if (!key) return null;
|
|
300
|
+
const cached = cache?.get(key);
|
|
301
|
+
return cached === void 0 || cached === "" ? null : cached;
|
|
302
|
+
};
|
|
303
|
+
const useHighlight = (code, lang, themeInput, optionsInput, highlighterFactory) => {
|
|
304
|
+
const { cache, ...rest } = optionsInput ?? {};
|
|
305
|
+
const cacheRef = useRef(cache);
|
|
306
|
+
cacheRef.current = cache;
|
|
307
|
+
useFeatureStyles(Boolean(rest.showLineNumbers || rest.highlightLineNumbers?.length));
|
|
303
308
|
const stableLang = useStableValue(lang);
|
|
304
309
|
const stableTheme = useStableValue(themeInput);
|
|
305
|
-
const stableOpts = useStableValue(
|
|
310
|
+
const stableOpts = useStableValue(rest);
|
|
306
311
|
const resolved = useMemo(() => {
|
|
307
312
|
const { languageId, langsToLoad } = resolveLanguage(stableLang, stableOpts.customLanguages, stableOpts.langAlias, stableOpts.preloadLanguages);
|
|
308
313
|
const theme = resolveTheme(stableTheme);
|
|
@@ -318,6 +323,27 @@ const useHighlight = (code, lang, themeInput, options = {}, highlighterFactory)
|
|
|
318
323
|
stableTheme,
|
|
319
324
|
stableOpts
|
|
320
325
|
]);
|
|
326
|
+
const hasCache = Boolean(cache);
|
|
327
|
+
const cacheScope = useMemo(() => hasCache ? JSON.stringify([
|
|
328
|
+
stableOpts.outputFormat ?? "react",
|
|
329
|
+
resolved.shikiOptions,
|
|
330
|
+
stableOpts.startingLineNumber,
|
|
331
|
+
stableOpts.highlightLineNumbers
|
|
332
|
+
]) : void 0, [
|
|
333
|
+
hasCache,
|
|
334
|
+
resolved,
|
|
335
|
+
stableOpts
|
|
336
|
+
]);
|
|
337
|
+
const cacheKey = cacheScope && `${cacheScope}\n${code}`;
|
|
338
|
+
const [highlightedCode, setHighlightedCode] = useState(() => readCache(cache, cacheKey));
|
|
339
|
+
const shown = useRef({
|
|
340
|
+
key: cacheKey,
|
|
341
|
+
result: highlightedCode
|
|
342
|
+
});
|
|
343
|
+
useEffect(() => () => {
|
|
344
|
+
const { key, result } = shown.current;
|
|
345
|
+
if (key && result !== null && result !== "") cacheRef.current?.set(key, result);
|
|
346
|
+
}, []);
|
|
321
347
|
const requestIdRef = useRef(0);
|
|
322
348
|
const timeoutControl = useRef({
|
|
323
349
|
nextAllowedTime: 0,
|
|
@@ -327,29 +353,85 @@ const useHighlight = (code, lang, themeInput, options = {}, highlighterFactory)
|
|
|
327
353
|
highlighterFactoryRef.current = highlighterFactory;
|
|
328
354
|
useEffect(() => {
|
|
329
355
|
const requestId = ++requestIdRef.current;
|
|
330
|
-
|
|
356
|
+
const timeouts = timeoutControl.current;
|
|
357
|
+
const show = (result) => {
|
|
358
|
+
shown.current = {
|
|
359
|
+
key: cacheKey,
|
|
360
|
+
result
|
|
361
|
+
};
|
|
362
|
+
setHighlightedCode(result);
|
|
363
|
+
};
|
|
331
364
|
const run = async () => {
|
|
332
365
|
try {
|
|
333
366
|
const result = await highlight(code, resolved, stableOpts, highlighterFactoryRef.current);
|
|
334
|
-
if (requestId === requestIdRef.current)
|
|
367
|
+
if (requestId === requestIdRef.current) show(result);
|
|
335
368
|
} catch (error) {
|
|
336
369
|
console.error("[react-shiki] highlight failed", error);
|
|
337
370
|
}
|
|
338
371
|
};
|
|
339
|
-
|
|
372
|
+
const cached = readCache(cacheRef.current, cacheKey);
|
|
373
|
+
if (!resolved.languageId) return () => {
|
|
374
|
+
clearTimeout(timeouts.timeoutId);
|
|
375
|
+
};
|
|
376
|
+
if (cached !== null) {
|
|
377
|
+
if (shown.current.result !== cached) show(cached);
|
|
378
|
+
} else if (stableOpts.delay) throttleHighlighting(run, timeoutControl, stableOpts.delay);
|
|
340
379
|
else run();
|
|
341
380
|
return () => {
|
|
342
|
-
clearTimeout(
|
|
381
|
+
clearTimeout(timeouts.timeoutId);
|
|
343
382
|
};
|
|
344
383
|
}, [
|
|
345
384
|
code,
|
|
385
|
+
cacheKey,
|
|
346
386
|
resolved,
|
|
347
387
|
stableOpts
|
|
348
388
|
]);
|
|
349
389
|
return highlightedCode;
|
|
350
390
|
};
|
|
351
|
-
|
|
352
|
-
|
|
391
|
+
// src/lib/component.tsx
|
|
392
|
+
let warnedTokensOutputFormat = false;
|
|
393
|
+
/**
|
|
394
|
+
* The component's props exclude `outputFormat: 'tokens'`, but plain-JS
|
|
395
|
+
* callers can still pass it. Tokens are not renderable React children,
|
|
396
|
+
* so fall back to 'react' instead of crashing the render.
|
|
397
|
+
*/
|
|
398
|
+
const resolveOutputFormat = (outputFormat) => {
|
|
399
|
+
if (outputFormat !== "tokens") return outputFormat;
|
|
400
|
+
if (!warnedTokensOutputFormat) {
|
|
401
|
+
warnedTokensOutputFormat = true;
|
|
402
|
+
console.warn("[react-shiki] outputFormat 'tokens' is only supported by the useShikiHighlighter hook, falling back to 'react'");
|
|
403
|
+
}
|
|
404
|
+
return "react";
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* Base ShikiHighlighter component factory.
|
|
408
|
+
* This creates a component that uses the provided hook implementation.
|
|
409
|
+
*/
|
|
410
|
+
const createShikiHighlighterComponent = (useShikiHighlighterImpl) => forwardRef(({ language, theme, addDefaultStyles = true, style, langStyle, className, langClassName, showLanguage = true, children: code, as: Element = "div", outputFormat, ...options }, ref) => {
|
|
411
|
+
useComponentStyles();
|
|
412
|
+
const displayLanguageId = typeof language === "object" ? language.name || null : language?.trim() || null;
|
|
413
|
+
const highlightedCode = useShikiHighlighterImpl(code, language, theme, {
|
|
414
|
+
...options,
|
|
415
|
+
outputFormat: resolveOutputFormat(outputFormat)
|
|
416
|
+
});
|
|
417
|
+
return /* @__PURE__ */ jsxs(Element, {
|
|
418
|
+
ref,
|
|
419
|
+
"data-testid": "shiki-container",
|
|
420
|
+
"data-slot": "container",
|
|
421
|
+
className: clsx("rs-root", "not-prose", addDefaultStyles && "rs-default-styles", className),
|
|
422
|
+
style,
|
|
423
|
+
children: [showLanguage && displayLanguageId ? /* @__PURE__ */ jsx("span", {
|
|
424
|
+
"data-slot": "language-label",
|
|
425
|
+
className: clsx("rs-language-label", langClassName),
|
|
426
|
+
style: langStyle,
|
|
427
|
+
children: displayLanguageId
|
|
428
|
+
}) : null, typeof highlightedCode === "string" ? /* @__PURE__ */ jsx("div", {
|
|
429
|
+
"data-slot": "content",
|
|
430
|
+
dangerouslySetInnerHTML: { __html: highlightedCode }
|
|
431
|
+
}) : highlightedCode]
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
// src/lib/plugins.ts
|
|
353
435
|
/**
|
|
354
436
|
* Rehype plugin to add an 'inline' property to <code> elements
|
|
355
437
|
* Sets 'inline' property to true if the <code> is not within a <pre> tag
|
|
@@ -374,55 +456,8 @@ function rehypeInlineCodeProperty() {
|
|
|
374
456
|
* const isInline = node && isInlineCode(node: Element)
|
|
375
457
|
*/
|
|
376
458
|
const isInlineCode = (node) => {
|
|
377
|
-
return !(node.children
|
|
378
|
-
};
|
|
379
|
-
//#endregion
|
|
380
|
-
//#region src/lib/component.tsx
|
|
381
|
-
let warnedTokensOutputFormat = false;
|
|
382
|
-
/**
|
|
383
|
-
* The component's props exclude `outputFormat: 'tokens'`, but plain-JS
|
|
384
|
-
* callers can still pass it. Tokens are not renderable React children,
|
|
385
|
-
* so fall back to 'react' instead of crashing the render.
|
|
386
|
-
*/
|
|
387
|
-
const resolveOutputFormat = (outputFormat) => {
|
|
388
|
-
if (outputFormat !== "tokens") return outputFormat;
|
|
389
|
-
if (!warnedTokensOutputFormat) {
|
|
390
|
-
warnedTokensOutputFormat = true;
|
|
391
|
-
console.warn("[react-shiki] outputFormat 'tokens' is only supported by the useShikiHighlighter hook, falling back to 'react'");
|
|
392
|
-
}
|
|
393
|
-
return "react";
|
|
394
|
-
};
|
|
395
|
-
/**
|
|
396
|
-
* Base ShikiHighlighter component factory.
|
|
397
|
-
* This creates a component that uses the provided hook implementation.
|
|
398
|
-
*/
|
|
399
|
-
const createShikiHighlighterComponent = (useShikiHighlighterImpl) => {
|
|
400
|
-
return forwardRef(({ language, theme, addDefaultStyles = true, style, langStyle, className, langClassName, showLanguage = true, children: code, as: Element = "div", outputFormat, ...options }, ref) => {
|
|
401
|
-
useComponentStyles();
|
|
402
|
-
const displayLanguageId = typeof language === "object" ? language.name || null : language?.trim() || null;
|
|
403
|
-
const highlightedCode = useShikiHighlighterImpl(code, language, theme, {
|
|
404
|
-
...options,
|
|
405
|
-
outputFormat: resolveOutputFormat(outputFormat)
|
|
406
|
-
});
|
|
407
|
-
return /* @__PURE__ */ jsxs(Element, {
|
|
408
|
-
ref,
|
|
409
|
-
"data-testid": "shiki-container",
|
|
410
|
-
"data-slot": "container",
|
|
411
|
-
className: clsx("rs-root", "not-prose", addDefaultStyles && "rs-default-styles", className),
|
|
412
|
-
style,
|
|
413
|
-
children: [showLanguage && displayLanguageId ? /* @__PURE__ */ jsx("span", {
|
|
414
|
-
"data-slot": "language-label",
|
|
415
|
-
className: clsx("rs-language-label", langClassName),
|
|
416
|
-
style: langStyle,
|
|
417
|
-
children: displayLanguageId
|
|
418
|
-
}) : null, typeof highlightedCode === "string" ? /* @__PURE__ */ jsx("div", {
|
|
419
|
-
"data-slot": "content",
|
|
420
|
-
dangerouslySetInnerHTML: { __html: highlightedCode }
|
|
421
|
-
}) : highlightedCode]
|
|
422
|
-
});
|
|
423
|
-
});
|
|
459
|
+
return !(node.children ?? []).filter((child) => child.type === "text").map((child) => child.value).join("").includes("\n");
|
|
424
460
|
};
|
|
425
|
-
|
|
426
|
-
export { isLoadableLanguage as a, useHighlight as i, isInlineCode as n, rehypeInlineCodeProperty as r, createShikiHighlighterComponent as t };
|
|
461
|
+
export { isLoadableLanguage as a, useHighlight as i, rehypeInlineCodeProperty as n, createShikiHighlighterComponent as r, isInlineCode as t };
|
|
427
462
|
|
|
428
|
-
//# sourceMappingURL=
|
|
463
|
+
//# sourceMappingURL=plugins-C0Uf67_P.mjs.map
|