@cloudflare/kumo 2.2.1 → 2.2.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @cloudflare/kumo
2
2
 
3
+ ## 2.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 94d0c22: Fix language alias normalization in ShikiProvider
8
+ - Add `normalizeLanguage()` function that maps common language aliases (js, ts, sh, yml, py, md, gql) to their canonical SupportedLanguage names
9
+ - Normalize language aliases in `ShikiProvider` when preloading grammars, so passing `['js', 'ts']` works the same as `['javascript', 'typescript']`
10
+ - Normalize language aliases in `highlight()` hook at runtime, so code fences using `js` or `ts` highlight correctly without warnings
11
+ - Export `normalizeLanguage` from `@cloudflare/kumo/code` for consumers who need to normalize aliases themselves
12
+ - Intentionally omit `mdx` alias since MDX has a distinct grammar that would lose JSX highlighting if mapped to `markdown`
13
+
3
14
  ## 2.2.1
4
15
 
5
16
  ### Patch Changes
@@ -1 +1 @@
1
- 1778851251288
1
+ 1779284188120
package/dist/code.js CHANGED
@@ -1,9 +1,22 @@
1
1
  "use client";
2
- import { jsx as o, jsxs as v } from "react/jsx-runtime";
3
- import { createContext as T, useState as E, useEffect as A, useMemo as w, useContext as B, useCallback as P } from "react";
2
+ import { jsx as r, jsxs as b } from "react/jsx-runtime";
3
+ import { createContext as T, useState as j, useEffect as q, useMemo as w, useContext as B, useCallback as E } from "react";
4
4
  import { c as C } from "./chunks/cn-ct4n7r74mh8y0f48.js";
5
5
  import { B as F } from "./chunks/button-oevxukl0zmwoq4tb.js";
6
- const j = T(null), H = {
6
+ const A = T(null), H = {
7
+ js: "javascript",
8
+ cjs: "javascript",
9
+ mjs: "javascript",
10
+ ts: "typescript",
11
+ cts: "typescript",
12
+ mts: "typescript",
13
+ sh: "bash",
14
+ zsh: "bash",
15
+ yml: "yaml",
16
+ py: "python",
17
+ md: "markdown",
18
+ gql: "graphql"
19
+ }, P = {
7
20
  javascript: () => import("./chunks/javascript-hhx3avh9uv2o27ay.js"),
8
21
  typescript: () => import("./chunks/typescript-k4ggjrxhrhcdni6u.js"),
9
22
  jsx: () => import("./chunks/jsx-ij885l2li2lzfoss.js"),
@@ -22,210 +35,222 @@ const j = T(null), H = {
22
35
  diff: () => import("./chunks/diff-cpj1h9lg0bw716mj.js"),
23
36
  hcl: () => import("./chunks/hcl-hcu7d6ja6t540ijn.js"),
24
37
  toml: () => import("./chunks/toml-nczb2z9n0o23o3ci.js")
25
- }, K = {
38
+ };
39
+ function z(e) {
40
+ return e in P ? e : e in H ? H[e] : null;
41
+ }
42
+ const I = {
26
43
  copy: "Copy",
27
44
  copied: "Copied!"
28
45
  };
29
- function M({
46
+ function K({
30
47
  engine: e,
31
- languages: i,
48
+ languages: o,
32
49
  labels: l,
33
- children: a
50
+ children: s
34
51
  }) {
35
- const [t, s] = E({
52
+ const [i, h] = j({
36
53
  highlighter: null,
37
54
  isLoading: !0,
38
- error: null
55
+ error: null,
56
+ languages: []
39
57
  });
40
- A(() => {
58
+ q(() => {
41
59
  let n = !1;
42
60
  async function c() {
43
61
  try {
44
- const { createHighlighterCore: h } = await import("./chunks/core-dyku7qctyc40nnhh.js"), u = e === "wasm" ? await import("./chunks/engine-oniguruma-g75h8oxao68cjmhg.js").then(
45
- (r) => r.createOnigurumaEngine(import("./chunks/wasm-oj22f8usru9h7dzg.js"))
62
+ const { createHighlighterCore: a } = await import("./chunks/core-dyku7qctyc40nnhh.js"), u = e === "wasm" ? await import("./chunks/engine-oniguruma-g75h8oxao68cjmhg.js").then(
63
+ (t) => t.createOnigurumaEngine(import("./chunks/wasm-oj22f8usru9h7dzg.js"))
46
64
  ) : await import("./chunks/engine-javascript-hi1kqifa6nkcridk.js").then(
47
- (r) => r.createJavaScriptRegexEngine()
65
+ (t) => t.createJavaScriptRegexEngine()
48
66
  ), [x, d] = await Promise.all([
49
67
  import("./chunks/github-light-ulev8flhimfg79ob.js"),
50
68
  import("./chunks/vesper-ebfu9ns65f2v830s.js")
51
- ]), y = i.filter(
52
- (r) => r in H
53
- ), f = await Promise.all(
54
- y.map((r) => H[r]())
55
- ), b = await h({
69
+ ]), v = [
70
+ ...new Set(
71
+ o.map((t) => z(t)).filter((t) => t !== null)
72
+ )
73
+ ], f = await Promise.all(
74
+ v.map((t) => P[t]())
75
+ ), y = await a({
56
76
  themes: [x.default, d.default],
57
- langs: f.map((r) => r.default),
77
+ langs: f.map((t) => t.default),
58
78
  engine: u
59
79
  });
60
- n || s({
61
- highlighter: b,
80
+ n || h({
81
+ highlighter: y,
62
82
  isLoading: !1,
63
- error: null
83
+ error: null,
84
+ languages: v
64
85
  });
65
- } catch (h) {
66
- n || s({
86
+ } catch (a) {
87
+ n || h({
67
88
  highlighter: null,
68
89
  isLoading: !1,
69
- error: h instanceof Error ? h : new Error("Failed to load Shiki")
90
+ error: a instanceof Error ? a : new Error("Failed to load Shiki"),
91
+ languages: []
70
92
  });
71
93
  }
72
94
  }
73
95
  return c(), () => {
74
96
  n = !0;
75
97
  };
76
- }, [e, i]);
98
+ }, [e, o]);
77
99
  const p = w(
78
- () => ({ ...K, ...l }),
100
+ () => ({ ...I, ...l }),
79
101
  [l]
80
102
  ), g = w(
81
103
  () => ({
82
- highlighter: t.highlighter,
83
- isLoading: t.isLoading,
84
- error: t.error,
85
- languages: i,
104
+ highlighter: i.highlighter,
105
+ isLoading: i.isLoading,
106
+ error: i.error,
107
+ languages: i.languages,
86
108
  labels: p
87
109
  }),
88
- [t.highlighter, t.isLoading, t.error, i, p]
110
+ [i.highlighter, i.isLoading, i.error, i.languages, p]
89
111
  );
90
- return /* @__PURE__ */ o(j.Provider, { value: g, children: a });
112
+ return /* @__PURE__ */ r(A.Provider, { value: g, children: s });
91
113
  }
92
- M.displayName = "ShikiProvider";
93
- function z() {
94
- const e = B(j);
114
+ K.displayName = "ShikiProvider";
115
+ function M() {
116
+ const e = B(A);
95
117
  if (!e)
96
118
  throw new Error(
97
119
  "useShikiHighlighter must be used within a ShikiProvider. Wrap your app with <ShikiProvider> from '@cloudflare/kumo/code'."
98
120
  );
99
- const { highlighter: i, isLoading: l, error: a, languages: t, labels: s } = e;
121
+ const { highlighter: o, isLoading: l, error: s, languages: i, labels: h } = e;
100
122
  return {
101
- highlight: P(
123
+ highlight: E(
102
124
  (g, n) => {
103
- if (!i)
125
+ if (!o)
104
126
  return null;
105
- if (!t.includes(n))
127
+ const c = z(n);
128
+ if (!c || !i.includes(c))
106
129
  return console.warn(
107
- `[Kumo CodeHighlighted] Language "${n}" is not in the ShikiProvider's languages list. Add it to the languages array: languages={[...existing, '${n}']}. Rendering as plain text.`
130
+ `[Kumo CodeHighlighted] Language "${n}" is not in the ShikiProvider's languages list. Add it to the languages array: languages={[...existing, '${c || n}']}. Rendering as plain text.`
108
131
  ), null;
109
132
  try {
110
- return i.codeToHtml(g, {
111
- lang: n,
133
+ return o.codeToHtml(g, {
134
+ lang: c,
112
135
  themes: {
113
136
  light: "github-light",
114
137
  dark: "vesper"
115
138
  }
116
139
  });
117
- } catch (c) {
140
+ } catch (a) {
118
141
  return console.warn(
119
142
  `[Kumo CodeHighlighted] Failed to highlight code with language "${n}":`,
120
- c
143
+ a
121
144
  ), null;
122
145
  }
123
146
  },
124
- [i, t]
147
+ [o, i]
125
148
  ),
126
149
  isLoading: l,
127
- isReady: !l && i !== null,
128
- error: a,
129
- labels: s
150
+ isReady: !l && o !== null,
151
+ error: s,
152
+ labels: h
130
153
  };
131
154
  }
132
155
  function D({
133
156
  code: e,
134
- lang: i,
157
+ lang: o,
135
158
  showLineNumbers: l = !1,
136
- highlightLines: a,
137
- showCopyButton: t = !1,
138
- labels: s,
159
+ highlightLines: s,
160
+ showCopyButton: i = !1,
161
+ labels: h,
139
162
  className: p
140
163
  }) {
141
164
  const {
142
165
  highlight: g,
143
166
  isLoading: n,
144
167
  error: c,
145
- labels: h
146
- } = z(), [u, x] = E(!1), d = w(
147
- () => ({ ...h, ...s }),
148
- [h, s]
149
- ), y = P(async () => {
168
+ labels: a
169
+ } = M(), [u, x] = j(!1), d = w(
170
+ () => ({ ...a, ...h }),
171
+ [a, h]
172
+ ), v = E(async () => {
150
173
  try {
151
174
  await navigator.clipboard.writeText(e), x(!0), setTimeout(() => x(!1), 2e3);
152
- } catch (S) {
153
- console.error("[Kumo CodeHighlighted] Failed to copy to clipboard:", S);
175
+ } catch (L) {
176
+ console.error("[Kumo CodeHighlighted] Failed to copy to clipboard:", L);
154
177
  }
155
- }, [e]), f = g(e, i), b = w(() => e.split(`
156
- `).length, [e]), r = b === 1, k = C(
178
+ }, [e]), f = g(e, o), y = w(() => e.split(`
179
+ `).length, [e]), t = y === 1, k = C(
157
180
  "group relative m-0 w-full min-w-0 rounded-md border border-kumo-fill bg-kumo-base p-0",
158
- t && r && "flex items-center",
181
+ i && t && "flex items-center",
159
182
  p
160
- ), N = t ? /* @__PURE__ */ o(
183
+ ), S = i ? /* @__PURE__ */ r(
161
184
  "div",
162
185
  {
163
186
  className: C(
164
- r ? "shrink-0 px-2" : "absolute right-2 top-2",
187
+ t ? "shrink-0 px-2" : "absolute right-2 top-2",
165
188
  !u && "opacity-0 transition-opacity group-hover:opacity-100"
166
189
  ),
167
- children: /* @__PURE__ */ o(
190
+ children: /* @__PURE__ */ r(
168
191
  F,
169
192
  {
170
193
  variant: "secondary",
171
194
  size: "sm",
172
- onClick: y,
195
+ onClick: v,
173
196
  "aria-label": u ? d.copied : d.copy,
174
197
  children: u ? d.copied : d.copy
175
198
  }
176
199
  )
177
200
  }
178
- ) : null, m = l && !r ? /* @__PURE__ */ o(
201
+ ) : null, m = l && !t ? /* @__PURE__ */ r(
179
202
  "div",
180
203
  {
181
204
  className: "kumo-line-numbers shrink-0 select-none py-4 pr-4 text-right font-mono text-sm opacity-40",
182
205
  "aria-hidden": "true",
183
- children: Array.from({ length: b }, (S, L) => /* @__PURE__ */ o("div", { className: "leading-relaxed", children: L + 1 }, L + 1))
206
+ children: Array.from({ length: y }, (L, N) => /* @__PURE__ */ r("div", { className: "leading-relaxed", children: N + 1 }, N + 1))
184
207
  }
185
208
  ) : null;
186
- return c && console.error("[Kumo CodeHighlighted] Shiki initialization error:", c), n || f === null ? /* @__PURE__ */ v("div", { className: k, children: [
187
- m && /* @__PURE__ */ v("div", { className: "flex", children: [
209
+ return c && console.error("[Kumo CodeHighlighted] Shiki initialization error:", c), n || f === null ? /* @__PURE__ */ b("div", { className: k, children: [
210
+ m && /* @__PURE__ */ b("div", { className: "flex", children: [
188
211
  m,
189
- /* @__PURE__ */ o("pre", { className: "!m-0 min-w-0 flex-1 overflow-x-auto !p-4 font-mono text-sm leading-relaxed text-kumo-subtle", children: /* @__PURE__ */ o("code", { className: "!m-0 !p-0", children: e }) })
212
+ /* @__PURE__ */ r("pre", { className: "!m-0 min-w-0 flex-1 overflow-x-auto !p-4 font-mono text-sm leading-relaxed text-kumo-subtle", children: /* @__PURE__ */ r("code", { className: "!m-0 !p-0", children: e }) })
190
213
  ] }),
191
- !m && /* @__PURE__ */ o("pre", { className: "!m-0 min-w-0 flex-1 overflow-x-auto !p-4 font-mono text-sm leading-relaxed text-kumo-subtle", children: /* @__PURE__ */ o("code", { className: "!m-0 !p-0", children: e }) }),
192
- N
193
- ] }) : /* @__PURE__ */ v("div", { className: k, children: [
194
- m && /* @__PURE__ */ v("div", { className: "flex w-full", children: [
214
+ !m && /* @__PURE__ */ r("pre", { className: "!m-0 min-w-0 flex-1 overflow-x-auto !p-4 font-mono text-sm leading-relaxed text-kumo-subtle", children: /* @__PURE__ */ r("code", { className: "!m-0 !p-0", children: e }) }),
215
+ S
216
+ ] }) : /* @__PURE__ */ b("div", { className: k, children: [
217
+ m && /* @__PURE__ */ b("div", { className: "flex w-full", children: [
195
218
  m,
196
- /* @__PURE__ */ o("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ o(
219
+ /* @__PURE__ */ r("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ r(
197
220
  "div",
198
221
  {
199
222
  className: "kumo-shiki [&>pre]:!m-0 [&>pre]:!border-0 [&>pre]:!rounded-none [&>pre]:!bg-transparent [&>pre]:!p-4 [&>pre]:font-mono [&>pre]:text-sm [&>pre]:leading-relaxed [&_code]:!m-0 [&_code]:!p-0 [&_code]:!bg-transparent [&_code]:!border-0",
200
223
  dangerouslySetInnerHTML: {
201
- __html: _(f, a)
224
+ __html: _(f, s)
202
225
  }
203
226
  }
204
227
  ) })
205
228
  ] }),
206
- !m && /* @__PURE__ */ o("div", { className: "overflow-x-auto", children: /* @__PURE__ */ o(
229
+ !m && /* @__PURE__ */ r("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r(
207
230
  "div",
208
231
  {
209
232
  className: "kumo-shiki [&>pre]:!m-0 [&>pre]:!border-0 [&>pre]:!rounded-none [&>pre]:!bg-transparent [&>pre]:!p-4 [&>pre]:font-mono [&>pre]:text-sm [&>pre]:leading-relaxed [&_code]:!m-0 [&_code]:!p-0 [&_code]:!bg-transparent [&_code]:!border-0",
210
233
  dangerouslySetInnerHTML: {
211
- __html: _(f, a)
234
+ __html: _(f, s)
212
235
  }
213
236
  }
214
237
  ) }),
215
- N
238
+ S
216
239
  ] });
217
240
  }
218
241
  D.displayName = "CodeHighlighted";
219
- function _(e, i) {
220
- if (!i?.length)
242
+ function _(e, o) {
243
+ if (!o?.length)
221
244
  return e;
222
- const l = new Set(i);
223
- let a = 0;
224
- return e.replace(/<span class="line">/g, () => (a++, l.has(a) ? '<span class="line line-highlighted">' : '<span class="line">'));
245
+ const l = new Set(o);
246
+ let s = 0;
247
+ return e.replace(/<span class="line">/g, () => (s++, l.has(s) ? '<span class="line line-highlighted">' : '<span class="line">'));
225
248
  }
226
249
  export {
227
250
  D as CodeHighlighted,
228
- M as ShikiProvider,
229
- z as useShikiHighlighter
251
+ H as LANGUAGE_ALIASES,
252
+ K as ShikiProvider,
253
+ z as normalizeLanguage,
254
+ M as useShikiHighlighter
230
255
  };
231
256
  //# sourceMappingURL=code.js.map
package/dist/code.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"code.js","sources":["../src/code/context.ts","../src/code/provider.tsx","../src/code/use-shiki-highlighter.ts","../src/code/code-highlighted.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport type { HighlighterCore } from \"shiki/core\";\nimport type { SupportedLanguage, CodeHighlightedLabels } from \"./types\";\n\nexport interface ShikiContextValue {\n /** The initialized Shiki highlighter instance */\n highlighter: HighlighterCore | null;\n\n /** True while Shiki is loading */\n isLoading: boolean;\n\n /** Error if initialization failed */\n error: Error | null;\n\n /** Configured languages */\n languages: SupportedLanguage[];\n\n /** Localized labels for UI elements */\n labels: CodeHighlightedLabels;\n}\n\nexport const ShikiContext = createContext<ShikiContextValue | null>(null);\n","\"use client\";\n\nimport React, { useState, useEffect, useMemo } from \"react\";\nimport { ShikiContext, type ShikiContextValue } from \"./context\";\nimport type { ShikiProviderProps, SupportedLanguage } from \"./types\";\n\n/**\n * Pre-bundled languages - only these languages are included in the Kumo bundle.\n * Using fine-grained imports from @shikijs/langs to minimize bundle size.\n */\nconst BUNDLED_LANGS: Record<\n SupportedLanguage,\n () => Promise<{ default: unknown }>\n> = {\n javascript: () => import(\"@shikijs/langs/javascript\"),\n typescript: () => import(\"@shikijs/langs/typescript\"),\n jsx: () => import(\"@shikijs/langs/jsx\"),\n tsx: () => import(\"@shikijs/langs/tsx\"),\n json: () => import(\"@shikijs/langs/json\"),\n jsonc: () => import(\"@shikijs/langs/jsonc\"),\n html: () => import(\"@shikijs/langs/html\"),\n css: () => import(\"@shikijs/langs/css\"),\n python: () => import(\"@shikijs/langs/python\"),\n yaml: () => import(\"@shikijs/langs/yaml\"),\n markdown: () => import(\"@shikijs/langs/markdown\"),\n graphql: () => import(\"@shikijs/langs/graphql\"),\n sql: () => import(\"@shikijs/langs/sql\"),\n bash: () => import(\"@shikijs/langs/bash\"),\n shell: () => import(\"@shikijs/langs/shellscript\"),\n diff: () => import(\"@shikijs/langs/diff\"),\n hcl: () => import(\"@shikijs/langs/hcl\"),\n toml: () => import(\"@shikijs/langs/toml\"),\n};\n\n/**\n * Provider component that initializes and manages Shiki highlighting.\n *\n * Shiki is lazy-loaded on first render — no JavaScript is downloaded\n * until this provider mounts. While loading, child components can\n * render code as plain text.\n *\n * Uses hardcoded themes: `github-light` for light mode, `vesper` for dark mode.\n *\n * @example\n * ```tsx\n * import { ShikiProvider, CodeHighlighted } from \"@cloudflare/kumo/code\";\n *\n * function App() {\n * return (\n * <ShikiProvider\n * engine=\"javascript\"\n * languages={['tsx', 'bash', 'json']}\n * >\n * <CodeHighlighted code=\"const x = 1;\" lang=\"tsx\" />\n * </ShikiProvider>\n * );\n * }\n * ```\n */\nconst DEFAULT_LABELS = {\n copy: \"Copy\",\n copied: \"Copied!\",\n};\n\nexport function ShikiProvider({\n engine,\n languages,\n labels,\n children,\n}: ShikiProviderProps): React.JSX.Element {\n const [state, setState] = useState<{\n highlighter: ShikiContextValue[\"highlighter\"];\n isLoading: boolean;\n error: Error | null;\n }>({\n highlighter: null,\n isLoading: true,\n error: null,\n });\n\n useEffect(() => {\n let cancelled = false;\n\n async function initializeShiki() {\n try {\n // Dynamic import of shiki/core — only loads the core, not all languages\n const { createHighlighterCore } = await import(\"shiki/core\");\n\n // Load the appropriate engine\n const engineInstance =\n engine === \"wasm\"\n ? await import(\"shiki/engine/oniguruma\").then((m) =>\n m.createOnigurumaEngine(import(\"shiki/wasm\")),\n )\n : await import(\"shiki/engine/javascript\").then((m) =>\n m.createJavaScriptRegexEngine(),\n );\n\n // Load themes\n const [githubLight, vesper] = await Promise.all([\n import(\"@shikijs/themes/github-light\"),\n import(\"@shikijs/themes/vesper\"),\n ]);\n\n // Load only the requested languages from our bundled set\n const validLanguages = languages.filter(\n (lang): lang is SupportedLanguage => lang in BUNDLED_LANGS,\n );\n\n const langModules = await Promise.all(\n validLanguages.map((lang) => BUNDLED_LANGS[lang]()),\n );\n\n const highlighter = await createHighlighterCore({\n themes: [githubLight.default, vesper.default],\n\n langs: langModules.map((m) => m.default) as any,\n engine: engineInstance,\n });\n\n if (!cancelled) {\n setState({\n highlighter,\n isLoading: false,\n error: null,\n });\n }\n } catch (err) {\n if (!cancelled) {\n setState({\n highlighter: null,\n isLoading: false,\n error:\n err instanceof Error ? err : new Error(\"Failed to load Shiki\"),\n });\n }\n }\n }\n\n void initializeShiki();\n\n return () => {\n cancelled = true;\n };\n }, [engine, languages]);\n\n const mergedLabels = useMemo(\n () => ({ ...DEFAULT_LABELS, ...labels }),\n [labels],\n );\n\n const contextValue = useMemo<ShikiContextValue>(\n () => ({\n highlighter: state.highlighter,\n isLoading: state.isLoading,\n error: state.error,\n languages: languages as SupportedLanguage[],\n labels: mergedLabels,\n }),\n [state.highlighter, state.isLoading, state.error, languages, mergedLabels],\n );\n\n return (\n <ShikiContext.Provider value={contextValue}>\n {children}\n </ShikiContext.Provider>\n );\n}\n\nShikiProvider.displayName = \"ShikiProvider\";\n","\"use client\";\n\nimport { useContext, useCallback } from \"react\";\nimport { ShikiContext } from \"./context\";\nimport type { UseShikiHighlighterResult, SupportedLanguage } from \"./types\";\n\n/**\n * Hook for accessing Shiki highlighting in custom implementations.\n *\n * Must be used within a ShikiProvider.\n *\n * Uses hardcoded themes: `github-light` for light mode, `vesper` for dark mode.\n *\n * @example\n * ```tsx\n * import { useShikiHighlighter } from \"@cloudflare/kumo/code\";\n *\n * function CustomCodeBlock({ code, lang }) {\n * const { highlight, isLoading, isReady, error } = useShikiHighlighter();\n *\n * if (error) {\n * return <div>Failed to load highlighter</div>;\n * }\n *\n * if (isLoading) {\n * return <pre><code>{code}</code></pre>;\n * }\n *\n * const html = highlight(code, lang);\n *\n * // null means highlighting failed — render plain text\n * if (html === null) {\n * return <pre><code>{code}</code></pre>;\n * }\n *\n * return <pre dangerouslySetInnerHTML={{ __html: html }} />;\n * }\n * ```\n */\nexport function useShikiHighlighter(): UseShikiHighlighterResult {\n const context = useContext(ShikiContext);\n\n if (!context) {\n throw new Error(\n \"useShikiHighlighter must be used within a ShikiProvider. \" +\n \"Wrap your app with <ShikiProvider> from '@cloudflare/kumo/code'.\",\n );\n }\n\n const { highlighter, isLoading, error, languages, labels } = context;\n\n const highlight = useCallback(\n (code: string, lang: SupportedLanguage): string | null => {\n if (!highlighter) {\n return null;\n }\n\n // Check if the language is supported\n if (!languages.includes(lang)) {\n console.warn(\n `[Kumo CodeHighlighted] Language \"${lang}\" is not in the ShikiProvider's languages list. ` +\n `Add it to the languages array: languages={[...existing, '${lang}']}. ` +\n `Rendering as plain text.`,\n );\n return null;\n }\n\n try {\n // Use dual theme for light/dark mode support with hardcoded themes\n const html = highlighter.codeToHtml(code, {\n lang,\n themes: {\n light: \"github-light\",\n dark: \"vesper\",\n },\n });\n\n return html;\n } catch (err) {\n console.warn(\n `[Kumo CodeHighlighted] Failed to highlight code with language \"${lang}\":`,\n err,\n );\n return null;\n }\n },\n [highlighter, languages],\n );\n\n return {\n highlight,\n isLoading,\n isReady: !isLoading && highlighter !== null,\n error,\n labels,\n };\n}\n","\"use client\";\n\nimport React, { useState, useCallback, useMemo } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { Button } from \"../components/button\";\nimport { useShikiHighlighter } from \"./use-shiki-highlighter\";\nimport type { CodeHighlightedProps } from \"./types\";\n\n/**\n * Syntax-highlighted code block powered by Shiki.\n *\n * Must be used within a ShikiProvider. While Shiki is loading,\n * displays code as plain text (no layout shift, immediately readable).\n *\n * Uses hardcoded themes: `github-light` for light mode, `vesper` for dark mode.\n *\n * @example\n * ```tsx\n * import { ShikiProvider, CodeHighlighted } from \"@cloudflare/kumo/code\";\n *\n * <ShikiProvider\n * engine=\"javascript\"\n * languages={['tsx', 'bash']}\n * >\n * <CodeHighlighted\n * code={`const greeting = \"Hello!\";`}\n * lang=\"tsx\"\n * showLineNumbers\n * showCopyButton\n * />\n * </ShikiProvider>\n * ```\n */\nexport function CodeHighlighted({\n code,\n lang,\n showLineNumbers = false,\n highlightLines,\n showCopyButton = false,\n labels: labelOverrides,\n className,\n}: CodeHighlightedProps): React.JSX.Element {\n const {\n highlight,\n isLoading,\n error,\n labels: providerLabels,\n } = useShikiHighlighter();\n const [copied, setCopied] = useState(false);\n\n // Merge provider labels with component-level overrides\n const labels = useMemo(\n () => ({ ...providerLabels, ...labelOverrides }),\n [providerLabels, labelOverrides],\n );\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error(\"[Kumo CodeHighlighted] Failed to copy to clipboard:\", err);\n }\n }, [code]);\n\n // Get highlighted HTML (or null if not ready/failed)\n const html = highlight(code, lang);\n\n // Count lines for line numbers\n const lineCount = useMemo(() => code.split(\"\\n\").length, [code]);\n\n // Detect single-line code for layout adjustments\n const isSingleLine = lineCount === 1;\n\n // Container styles - use flex layout for single-line with copy button\n // Includes defensive resets (m-0, p-0) to prevent global CSS pollution\n const containerClasses = cn(\n \"group relative m-0 w-full min-w-0 rounded-md border border-kumo-fill bg-kumo-base p-0\",\n showCopyButton && isSingleLine && \"flex items-center\",\n className,\n );\n\n // Copy button - inline for single-line, absolute for multi-line\n // Hidden until hover (or when showing \"Copied!\" feedback)\n const copyButton = showCopyButton ? (\n <div\n className={cn(\n isSingleLine ? \"shrink-0 px-2\" : \"absolute right-2 top-2\",\n !copied && \"opacity-0 transition-opacity group-hover:opacity-100\",\n )}\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleCopy}\n aria-label={copied ? labels.copied : labels.copy}\n >\n {copied ? labels.copied : labels.copy}\n </Button>\n </div>\n ) : null;\n\n // Line numbers column\n const lineNumbers =\n showLineNumbers && !isSingleLine ? (\n <div\n className=\"kumo-line-numbers shrink-0 select-none py-4 pr-4 text-right font-mono text-sm opacity-40\"\n aria-hidden=\"true\"\n >\n {Array.from({ length: lineCount }, (_, i) => (\n <div key={i + 1} className=\"leading-relaxed\">\n {i + 1}\n </div>\n ))}\n </div>\n ) : null;\n\n // Error state — still show code, just log the error\n if (error) {\n console.error(\"[Kumo CodeHighlighted] Shiki initialization error:\", error);\n }\n\n // Loading or failed to highlight — show plain text\n if (isLoading || html === null) {\n return (\n <div className={containerClasses}>\n {lineNumbers && (\n <div className=\"flex\">\n {lineNumbers}\n <pre className=\"!m-0 min-w-0 flex-1 overflow-x-auto !p-4 font-mono text-sm leading-relaxed text-kumo-subtle\">\n <code className=\"!m-0 !p-0\">{code}</code>\n </pre>\n </div>\n )}\n {!lineNumbers && (\n <pre className=\"!m-0 min-w-0 flex-1 overflow-x-auto !p-4 font-mono text-sm leading-relaxed text-kumo-subtle\">\n <code className=\"!m-0 !p-0\">{code}</code>\n </pre>\n )}\n {copyButton}\n </div>\n );\n }\n\n // Highlighted code\n return (\n <div className={containerClasses}>\n {lineNumbers && (\n <div className=\"flex w-full\">\n {lineNumbers}\n <div className=\"min-w-0 flex-1 overflow-x-auto\">\n <div\n className=\"kumo-shiki [&>pre]:!m-0 [&>pre]:!border-0 [&>pre]:!rounded-none [&>pre]:!bg-transparent [&>pre]:!p-4 [&>pre]:font-mono [&>pre]:text-sm [&>pre]:leading-relaxed [&_code]:!m-0 [&_code]:!p-0 [&_code]:!bg-transparent [&_code]:!border-0\"\n dangerouslySetInnerHTML={{\n __html: processHighlightedHtml(html, highlightLines),\n }}\n />\n </div>\n </div>\n )}\n {!lineNumbers && (\n <div className=\"overflow-x-auto\">\n <div\n className=\"kumo-shiki [&>pre]:!m-0 [&>pre]:!border-0 [&>pre]:!rounded-none [&>pre]:!bg-transparent [&>pre]:!p-4 [&>pre]:font-mono [&>pre]:text-sm [&>pre]:leading-relaxed [&_code]:!m-0 [&_code]:!p-0 [&_code]:!bg-transparent [&_code]:!border-0\"\n dangerouslySetInnerHTML={{\n __html: processHighlightedHtml(html, highlightLines),\n }}\n />\n </div>\n )}\n {copyButton}\n </div>\n );\n}\n\nCodeHighlighted.displayName = \"CodeHighlighted\";\n\n/**\n * Process Shiki's HTML output to add line highlighting classes.\n * Does NOT modify Shiki's token structure - only adds classes to line spans.\n */\nfunction processHighlightedHtml(\n html: string,\n highlightLines?: number[],\n): string {\n // Line numbers are not yet supported - would require more complex approach\n // For now, only handle line highlighting which just adds a class\n\n if (!highlightLines?.length) {\n return html;\n }\n\n const highlightSet = new Set(highlightLines);\n let lineNumber = 0;\n\n // Only add the highlight class to lines, don't restructure the HTML\n return html.replace(/<span class=\"line\">/g, () => {\n lineNumber++;\n const isHighlighted = highlightSet.has(lineNumber);\n return isHighlighted\n ? '<span class=\"line line-highlighted\">'\n : '<span class=\"line\">';\n });\n}\n"],"names":["ShikiContext","createContext","BUNDLED_LANGS","n","DEFAULT_LABELS","ShikiProvider","engine","languages","labels","children","state","setState","useState","useEffect","cancelled","initializeShiki","createHighlighterCore","engineInstance","m","githubLight","vesper","validLanguages","lang","langModules","highlighter","err","mergedLabels","useMemo","contextValue","useShikiHighlighter","context","useContext","isLoading","error","useCallback","code","CodeHighlighted","showLineNumbers","highlightLines","showCopyButton","labelOverrides","className","highlight","providerLabels","copied","setCopied","handleCopy","html","lineCount","isSingleLine","containerClasses","cn","copyButton","jsx","Button","lineNumbers","_","i","jsxs","processHighlightedHtml","highlightSet","lineNumber"],"mappings":"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"}
1
+ {"version":3,"file":"code.js","sources":["../src/code/context.ts","../src/code/types.ts","../src/code/provider.tsx","../src/code/use-shiki-highlighter.ts","../src/code/code-highlighted.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport type { HighlighterCore } from \"shiki/core\";\nimport type { SupportedLanguage, CodeHighlightedLabels } from \"./types\";\n\nexport interface ShikiContextValue {\n /** The initialized Shiki highlighter instance */\n highlighter: HighlighterCore | null;\n\n /** True while Shiki is loading */\n isLoading: boolean;\n\n /** Error if initialization failed */\n error: Error | null;\n\n /** Configured languages */\n languages: SupportedLanguage[];\n\n /** Localized labels for UI elements */\n labels: CodeHighlightedLabels;\n}\n\nexport const ShikiContext = createContext<ShikiContextValue | null>(null);\n","/**\n * Supported languages for syntax highlighting.\n *\n * Kumo bundles a curated subset of Shiki languages to keep bundle size small.\n * These cover the most common use cases for documentation and code snippets.\n *\n * If you need additional languages, use Shiki directly with fine-grained imports.\n */\nexport type SupportedLanguage =\n | \"javascript\"\n | \"typescript\"\n | \"jsx\"\n | \"tsx\"\n | \"json\"\n | \"jsonc\"\n | \"html\"\n | \"css\"\n | \"python\"\n | \"yaml\"\n | \"markdown\"\n | \"graphql\"\n | \"sql\"\n | \"bash\"\n | \"shell\"\n | \"diff\"\n | \"hcl\"\n | \"toml\";\n\n/**\n * Common language aliases mapped to their canonical SupportedLanguage names.\n *\n * Markdown code fences often use short aliases (e.g., `js`, `ts`, `sh`) that\n * don't match the canonical grammar names but should resolve to them.\n *\n * Note: `mdx` is intentionally omitted because it has a distinct grammar\n * (Markdown + JSX) that would lose JSX highlighting if mapped to `markdown`.\n */\nexport const LANGUAGE_ALIASES = {\n js: \"javascript\",\n cjs: \"javascript\",\n mjs: \"javascript\",\n ts: \"typescript\",\n cts: \"typescript\",\n mts: \"typescript\",\n sh: \"bash\",\n zsh: \"bash\",\n yml: \"yaml\",\n py: \"python\",\n md: \"markdown\",\n gql: \"graphql\",\n} as const satisfies Record<string, SupportedLanguage>;\n\n/** A known alias that maps to a SupportedLanguage. */\nexport type LanguageAlias = keyof typeof LANGUAGE_ALIASES;\n\n/** Any language identifier accepted by ShikiProvider and highlight(). */\nexport type LanguageInput = SupportedLanguage | LanguageAlias;\n\n/**\n * Shiki engine choice for syntax highlighting.\n * - `\"javascript\"` — Smaller bundle (~50KB), slightly less accurate\n * - `\"wasm\"` — Larger bundle (~180KB), VS Code-accurate highlighting\n */\nexport type ShikiEngine = \"javascript\" | \"wasm\";\n\n/**\n * Localized labels for the copy button.\n */\nexport interface CodeHighlightedLabels {\n /** Label for copy button (default: \"Copy\") */\n copy?: string;\n /** Label shown after copying (default: \"Copied!\") */\n copied?: string;\n}\n\n/**\n * Props for ShikiProvider component.\n */\nexport interface ShikiProviderProps {\n /**\n * Highlighting engine choice.\n * - `\"javascript\"` — Smaller, faster to load (~50KB gzipped)\n * - `\"wasm\"` — Larger but more accurate (~180KB gzipped)\n */\n engine: ShikiEngine;\n\n /**\n * Languages to support. Only these languages will be loaded.\n * Accepts canonical names (`'javascript'`) or common aliases (`'js'`).\n * @example ['tsx', 'ts', 'bash', 'json']\n */\n languages: LanguageInput[];\n\n /**\n * Localized labels for UI elements (copy button, etc.).\n * Can be overridden at the component level.\n * @example { copy: \"Copier\", copied: \"Copié!\" }\n */\n labels?: CodeHighlightedLabels;\n\n /** React children */\n children: React.ReactNode;\n}\n\n/**\n * Return value from useShikiHighlighter hook.\n */\nexport interface UseShikiHighlighterResult {\n /**\n * Highlight code and return HTML string.\n * Returns `null` if highlighter is not ready or highlighting fails.\n * When `null` is returned, render the code as plain text.\n *\n * Accepts language aliases (e.g., 'js', 'ts', 'sh') which are automatically\n * normalized to their canonical SupportedLanguage names.\n */\n highlight: (code: string, lang: LanguageInput | (string & {})) => string | null;\n\n /** True while Shiki is loading */\n isLoading: boolean;\n\n /** True when highlight() is safe to call */\n isReady: boolean;\n\n /** Error if Shiki initialization failed */\n error: Error | null;\n\n /** Localized labels from provider */\n labels: CodeHighlightedLabels;\n}\n\n/**\n * Props for CodeHighlighted component.\n */\nexport interface CodeHighlightedProps {\n /** Source code to display */\n code: string;\n\n /**\n * Language identifier for syntax highlighting.\n * Accepts canonical names or common aliases (e.g., 'js', 'ts').\n * Must be included in the ShikiProvider's `languages` array.\n */\n lang: LanguageInput | (string & {});\n\n /** Display line numbers */\n showLineNumbers?: boolean;\n\n /**\n * Lines to visually emphasize (1-indexed).\n * @example [1, 5, 6]\n */\n highlightLines?: number[];\n\n /** Show copy-to-clipboard button */\n showCopyButton?: boolean;\n\n /**\n * Override provider labels for this instance.\n * @example { copy: \"Copy code\", copied: \"Done!\" }\n */\n labels?: CodeHighlightedLabels;\n\n /** Additional CSS classes */\n className?: string;\n}\n\n// Re-export for backwards compatibility (deprecated, use SupportedLanguage instead)\n/** @deprecated Use SupportedLanguage instead */\nexport type BundledLanguage = SupportedLanguage;\n","\"use client\";\n\nimport React, { useState, useEffect, useMemo } from \"react\";\nimport { ShikiContext, type ShikiContextValue } from \"./context\";\nimport { LANGUAGE_ALIASES } from \"./types\";\nimport type { ShikiProviderProps, SupportedLanguage, LanguageAlias } from \"./types\";\n\n/**\n * Pre-bundled languages - only these languages are included in the Kumo bundle.\n * Using fine-grained imports from @shikijs/langs to minimize bundle size.\n */\nconst BUNDLED_LANGS: Record<\n SupportedLanguage,\n () => Promise<{ default: unknown }>\n> = {\n javascript: () => import(\"@shikijs/langs/javascript\"),\n typescript: () => import(\"@shikijs/langs/typescript\"),\n jsx: () => import(\"@shikijs/langs/jsx\"),\n tsx: () => import(\"@shikijs/langs/tsx\"),\n json: () => import(\"@shikijs/langs/json\"),\n jsonc: () => import(\"@shikijs/langs/jsonc\"),\n html: () => import(\"@shikijs/langs/html\"),\n css: () => import(\"@shikijs/langs/css\"),\n python: () => import(\"@shikijs/langs/python\"),\n yaml: () => import(\"@shikijs/langs/yaml\"),\n markdown: () => import(\"@shikijs/langs/markdown\"),\n graphql: () => import(\"@shikijs/langs/graphql\"),\n sql: () => import(\"@shikijs/langs/sql\"),\n bash: () => import(\"@shikijs/langs/bash\"),\n shell: () => import(\"@shikijs/langs/shellscript\"),\n diff: () => import(\"@shikijs/langs/diff\"),\n hcl: () => import(\"@shikijs/langs/hcl\"),\n toml: () => import(\"@shikijs/langs/toml\"),\n};\n\n/**\n * Normalize a language identifier to its canonical SupportedLanguage name.\n * Returns the canonical name if the input is a known alias or already canonical,\n * otherwise returns null.\n */\nexport function normalizeLanguage(lang: string): SupportedLanguage | null {\n if (lang in BUNDLED_LANGS) return lang as SupportedLanguage;\n if (lang in LANGUAGE_ALIASES) return LANGUAGE_ALIASES[lang as LanguageAlias];\n return null;\n}\n\n/**\n * Provider component that initializes and manages Shiki highlighting.\n *\n * Shiki is lazy-loaded on first render — no JavaScript is downloaded\n * until this provider mounts. While loading, child components can\n * render code as plain text.\n *\n * Uses hardcoded themes: `github-light` for light mode, `vesper` for dark mode.\n *\n * @example\n * ```tsx\n * import { ShikiProvider, CodeHighlighted } from \"@cloudflare/kumo/code\";\n *\n * function App() {\n * return (\n * <ShikiProvider\n * engine=\"javascript\"\n * languages={['tsx', 'bash', 'json']}\n * >\n * <CodeHighlighted code=\"const x = 1;\" lang=\"tsx\" />\n * </ShikiProvider>\n * );\n * }\n * ```\n */\nconst DEFAULT_LABELS = {\n copy: \"Copy\",\n copied: \"Copied!\",\n};\n\nexport function ShikiProvider({\n engine,\n languages,\n labels,\n children,\n}: ShikiProviderProps): React.JSX.Element {\n const [state, setState] = useState<{\n highlighter: ShikiContextValue[\"highlighter\"];\n isLoading: boolean;\n error: Error | null;\n languages: SupportedLanguage[];\n }>({\n highlighter: null,\n isLoading: true,\n error: null,\n languages: [],\n });\n\n useEffect(() => {\n let cancelled = false;\n\n async function initializeShiki() {\n try {\n // Dynamic import of shiki/core — only loads the core, not all languages\n const { createHighlighterCore } = await import(\"shiki/core\");\n\n // Load the appropriate engine\n const engineInstance =\n engine === \"wasm\"\n ? await import(\"shiki/engine/oniguruma\").then((m) =>\n m.createOnigurumaEngine(import(\"shiki/wasm\")),\n )\n : await import(\"shiki/engine/javascript\").then((m) =>\n m.createJavaScriptRegexEngine(),\n );\n\n // Load themes\n const [githubLight, vesper] = await Promise.all([\n import(\"@shikijs/themes/github-light\"),\n import(\"@shikijs/themes/vesper\"),\n ]);\n\n // Load only the requested languages from our bundled set,\n // normalizing aliases (e.g., 'js' -> 'javascript') first\n const validLanguages = [\n ...new Set(\n languages\n .map((lang) => normalizeLanguage(lang))\n .filter((lang): lang is SupportedLanguage => lang !== null),\n ),\n ];\n\n const langModules = await Promise.all(\n validLanguages.map((lang) => BUNDLED_LANGS[lang]()),\n );\n\n const highlighter = await createHighlighterCore({\n themes: [githubLight.default, vesper.default],\n\n langs: langModules.map((m) => m.default) as any,\n engine: engineInstance,\n });\n\n if (!cancelled) {\n setState({\n highlighter,\n isLoading: false,\n error: null,\n languages: validLanguages,\n });\n }\n } catch (err) {\n if (!cancelled) {\n setState({\n highlighter: null,\n isLoading: false,\n error:\n err instanceof Error ? err : new Error(\"Failed to load Shiki\"),\n languages: [],\n });\n }\n }\n }\n\n void initializeShiki();\n\n return () => {\n cancelled = true;\n };\n }, [engine, languages]);\n\n const mergedLabels = useMemo(\n () => ({ ...DEFAULT_LABELS, ...labels }),\n [labels],\n );\n\n const contextValue = useMemo<ShikiContextValue>(\n () => ({\n highlighter: state.highlighter,\n isLoading: state.isLoading,\n error: state.error,\n languages: state.languages,\n labels: mergedLabels,\n }),\n [state.highlighter, state.isLoading, state.error, state.languages, mergedLabels],\n );\n\n return (\n <ShikiContext.Provider value={contextValue}>\n {children}\n </ShikiContext.Provider>\n );\n}\n\nShikiProvider.displayName = \"ShikiProvider\";\n","\"use client\";\n\nimport { useContext, useCallback } from \"react\";\nimport { ShikiContext } from \"./context\";\nimport { normalizeLanguage } from \"./provider\";\nimport type { UseShikiHighlighterResult } from \"./types\";\n\n/**\n * Hook for accessing Shiki highlighting in custom implementations.\n *\n * Must be used within a ShikiProvider.\n *\n * Uses hardcoded themes: `github-light` for light mode, `vesper` for dark mode.\n *\n * @example\n * ```tsx\n * import { useShikiHighlighter } from \"@cloudflare/kumo/code\";\n *\n * function CustomCodeBlock({ code, lang }) {\n * const { highlight, isLoading, isReady, error } = useShikiHighlighter();\n *\n * if (error) {\n * return <div>Failed to load highlighter</div>;\n * }\n *\n * if (isLoading) {\n * return <pre><code>{code}</code></pre>;\n * }\n *\n * const html = highlight(code, lang);\n *\n * // null means highlighting failed — render plain text\n * if (html === null) {\n * return <pre><code>{code}</code></pre>;\n * }\n *\n * return <pre dangerouslySetInnerHTML={{ __html: html }} />;\n * }\n * ```\n */\nexport function useShikiHighlighter(): UseShikiHighlighterResult {\n const context = useContext(ShikiContext);\n\n if (!context) {\n throw new Error(\n \"useShikiHighlighter must be used within a ShikiProvider. \" +\n \"Wrap your app with <ShikiProvider> from '@cloudflare/kumo/code'.\",\n );\n }\n\n const { highlighter, isLoading, error, languages, labels } = context;\n\n const highlight = useCallback(\n (code: string, lang: string): string | null => {\n if (!highlighter) {\n return null;\n }\n\n // Normalize language aliases (e.g., 'js' -> 'javascript')\n const normalizedLang = normalizeLanguage(lang);\n\n // Check if the language is supported\n if (!normalizedLang || !languages.includes(normalizedLang)) {\n console.warn(\n `[Kumo CodeHighlighted] Language \"${lang}\" is not in the ShikiProvider's languages list. ` +\n `Add it to the languages array: languages={[...existing, '${normalizedLang || lang}']}. ` +\n `Rendering as plain text.`,\n );\n return null;\n }\n\n try {\n // Use dual theme for light/dark mode support with hardcoded themes\n const html = highlighter.codeToHtml(code, {\n lang: normalizedLang,\n themes: {\n light: \"github-light\",\n dark: \"vesper\",\n },\n });\n\n return html;\n } catch (err) {\n console.warn(\n `[Kumo CodeHighlighted] Failed to highlight code with language \"${lang}\":`,\n err,\n );\n return null;\n }\n },\n [highlighter, languages],\n );\n\n return {\n highlight,\n isLoading,\n isReady: !isLoading && highlighter !== null,\n error,\n labels,\n };\n}\n","\"use client\";\n\nimport React, { useState, useCallback, useMemo } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { Button } from \"../components/button\";\nimport { useShikiHighlighter } from \"./use-shiki-highlighter\";\nimport type { CodeHighlightedProps } from \"./types\";\n\n/**\n * Syntax-highlighted code block powered by Shiki.\n *\n * Must be used within a ShikiProvider. While Shiki is loading,\n * displays code as plain text (no layout shift, immediately readable).\n *\n * Uses hardcoded themes: `github-light` for light mode, `vesper` for dark mode.\n *\n * @example\n * ```tsx\n * import { ShikiProvider, CodeHighlighted } from \"@cloudflare/kumo/code\";\n *\n * <ShikiProvider\n * engine=\"javascript\"\n * languages={['tsx', 'bash']}\n * >\n * <CodeHighlighted\n * code={`const greeting = \"Hello!\";`}\n * lang=\"tsx\"\n * showLineNumbers\n * showCopyButton\n * />\n * </ShikiProvider>\n * ```\n */\nexport function CodeHighlighted({\n code,\n lang,\n showLineNumbers = false,\n highlightLines,\n showCopyButton = false,\n labels: labelOverrides,\n className,\n}: CodeHighlightedProps): React.JSX.Element {\n const {\n highlight,\n isLoading,\n error,\n labels: providerLabels,\n } = useShikiHighlighter();\n const [copied, setCopied] = useState(false);\n\n // Merge provider labels with component-level overrides\n const labels = useMemo(\n () => ({ ...providerLabels, ...labelOverrides }),\n [providerLabels, labelOverrides],\n );\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error(\"[Kumo CodeHighlighted] Failed to copy to clipboard:\", err);\n }\n }, [code]);\n\n // Get highlighted HTML (or null if not ready/failed)\n const html = highlight(code, lang);\n\n // Count lines for line numbers\n const lineCount = useMemo(() => code.split(\"\\n\").length, [code]);\n\n // Detect single-line code for layout adjustments\n const isSingleLine = lineCount === 1;\n\n // Container styles - use flex layout for single-line with copy button\n // Includes defensive resets (m-0, p-0) to prevent global CSS pollution\n const containerClasses = cn(\n \"group relative m-0 w-full min-w-0 rounded-md border border-kumo-fill bg-kumo-base p-0\",\n showCopyButton && isSingleLine && \"flex items-center\",\n className,\n );\n\n // Copy button - inline for single-line, absolute for multi-line\n // Hidden until hover (or when showing \"Copied!\" feedback)\n const copyButton = showCopyButton ? (\n <div\n className={cn(\n isSingleLine ? \"shrink-0 px-2\" : \"absolute right-2 top-2\",\n !copied && \"opacity-0 transition-opacity group-hover:opacity-100\",\n )}\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleCopy}\n aria-label={copied ? labels.copied : labels.copy}\n >\n {copied ? labels.copied : labels.copy}\n </Button>\n </div>\n ) : null;\n\n // Line numbers column\n const lineNumbers =\n showLineNumbers && !isSingleLine ? (\n <div\n className=\"kumo-line-numbers shrink-0 select-none py-4 pr-4 text-right font-mono text-sm opacity-40\"\n aria-hidden=\"true\"\n >\n {Array.from({ length: lineCount }, (_, i) => (\n <div key={i + 1} className=\"leading-relaxed\">\n {i + 1}\n </div>\n ))}\n </div>\n ) : null;\n\n // Error state — still show code, just log the error\n if (error) {\n console.error(\"[Kumo CodeHighlighted] Shiki initialization error:\", error);\n }\n\n // Loading or failed to highlight — show plain text\n if (isLoading || html === null) {\n return (\n <div className={containerClasses}>\n {lineNumbers && (\n <div className=\"flex\">\n {lineNumbers}\n <pre className=\"!m-0 min-w-0 flex-1 overflow-x-auto !p-4 font-mono text-sm leading-relaxed text-kumo-subtle\">\n <code className=\"!m-0 !p-0\">{code}</code>\n </pre>\n </div>\n )}\n {!lineNumbers && (\n <pre className=\"!m-0 min-w-0 flex-1 overflow-x-auto !p-4 font-mono text-sm leading-relaxed text-kumo-subtle\">\n <code className=\"!m-0 !p-0\">{code}</code>\n </pre>\n )}\n {copyButton}\n </div>\n );\n }\n\n // Highlighted code\n return (\n <div className={containerClasses}>\n {lineNumbers && (\n <div className=\"flex w-full\">\n {lineNumbers}\n <div className=\"min-w-0 flex-1 overflow-x-auto\">\n <div\n className=\"kumo-shiki [&>pre]:!m-0 [&>pre]:!border-0 [&>pre]:!rounded-none [&>pre]:!bg-transparent [&>pre]:!p-4 [&>pre]:font-mono [&>pre]:text-sm [&>pre]:leading-relaxed [&_code]:!m-0 [&_code]:!p-0 [&_code]:!bg-transparent [&_code]:!border-0\"\n dangerouslySetInnerHTML={{\n __html: processHighlightedHtml(html, highlightLines),\n }}\n />\n </div>\n </div>\n )}\n {!lineNumbers && (\n <div className=\"overflow-x-auto\">\n <div\n className=\"kumo-shiki [&>pre]:!m-0 [&>pre]:!border-0 [&>pre]:!rounded-none [&>pre]:!bg-transparent [&>pre]:!p-4 [&>pre]:font-mono [&>pre]:text-sm [&>pre]:leading-relaxed [&_code]:!m-0 [&_code]:!p-0 [&_code]:!bg-transparent [&_code]:!border-0\"\n dangerouslySetInnerHTML={{\n __html: processHighlightedHtml(html, highlightLines),\n }}\n />\n </div>\n )}\n {copyButton}\n </div>\n );\n}\n\nCodeHighlighted.displayName = \"CodeHighlighted\";\n\n/**\n * Process Shiki's HTML output to add line highlighting classes.\n * Does NOT modify Shiki's token structure - only adds classes to line spans.\n */\nfunction processHighlightedHtml(\n html: string,\n highlightLines?: number[],\n): string {\n // Line numbers are not yet supported - would require more complex approach\n // For now, only handle line highlighting which just adds a class\n\n if (!highlightLines?.length) {\n return html;\n }\n\n const highlightSet = new Set(highlightLines);\n let lineNumber = 0;\n\n // Only add the highlight class to lines, don't restructure the HTML\n return html.replace(/<span class=\"line\">/g, () => {\n lineNumber++;\n const isHighlighted = highlightSet.has(lineNumber);\n return isHighlighted\n ? '<span class=\"line line-highlighted\">'\n : '<span class=\"line\">';\n });\n}\n"],"names":["ShikiContext","createContext","LANGUAGE_ALIASES","BUNDLED_LANGS","n","normalizeLanguage","lang","DEFAULT_LABELS","ShikiProvider","engine","languages","labels","children","state","setState","useState","useEffect","cancelled","initializeShiki","createHighlighterCore","engineInstance","m","githubLight","vesper","validLanguages","langModules","highlighter","err","mergedLabels","useMemo","contextValue","useShikiHighlighter","context","useContext","isLoading","error","useCallback","code","normalizedLang","CodeHighlighted","showLineNumbers","highlightLines","showCopyButton","labelOverrides","className","highlight","providerLabels","copied","setCopied","handleCopy","html","lineCount","isSingleLine","containerClasses","cn","copyButton","jsx","Button","lineNumbers","_","i","jsxs","processHighlightedHtml","highlightSet","lineNumber"],"mappings":"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"}
@@ -24,8 +24,9 @@
24
24
  *
25
25
  * @packageDocumentation
26
26
  */
27
- export { ShikiProvider } from './provider';
27
+ export { ShikiProvider, normalizeLanguage } from './provider';
28
28
  export { CodeHighlighted } from './code-highlighted';
29
29
  export { useShikiHighlighter } from './use-shiki-highlighter';
30
- export type { ShikiProviderProps, CodeHighlightedProps, UseShikiHighlighterResult, ShikiEngine, BundledLanguage, } from './types';
30
+ export { LANGUAGE_ALIASES } from './types';
31
+ export type { ShikiProviderProps, CodeHighlightedProps, UseShikiHighlighterResult, ShikiEngine, BundledLanguage, LanguageAlias, LanguageInput, } from './types';
31
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG9D,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,WAAW,EACX,eAAe,GAChB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,WAAW,EACX,eAAe,EACf,aAAa,EACb,aAAa,GACd,MAAM,SAAS,CAAC"}
@@ -1,5 +1,11 @@
1
1
  import { default as React } from 'react';
2
- import { ShikiProviderProps } from './types';
2
+ import { ShikiProviderProps, SupportedLanguage } from './types';
3
+ /**
4
+ * Normalize a language identifier to its canonical SupportedLanguage name.
5
+ * Returns the canonical name if the input is a known alias or already canonical,
6
+ * otherwise returns null.
7
+ */
8
+ export declare function normalizeLanguage(lang: string): SupportedLanguage | null;
3
9
  export declare function ShikiProvider({ engine, languages, labels, children, }: ShikiProviderProps): React.JSX.Element;
4
10
  export declare namespace ShikiProvider {
5
11
  var displayName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/code/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,kBAAkB,EAAqB,MAAM,SAAS,CAAC;AA4DrE,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,SAAS,EACT,MAAM,EACN,QAAQ,GACT,EAAE,kBAAkB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAkGxC;yBAvGe,aAAa"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/code/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAG5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAiB,MAAM,SAAS,CAAC;AA8BpF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAIxE;AAgCD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,SAAS,EACT,MAAM,EACN,QAAQ,GACT,EAAE,kBAAkB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA2GxC;yBAhHe,aAAa"}
@@ -7,6 +7,33 @@
7
7
  * If you need additional languages, use Shiki directly with fine-grained imports.
8
8
  */
9
9
  export type SupportedLanguage = "javascript" | "typescript" | "jsx" | "tsx" | "json" | "jsonc" | "html" | "css" | "python" | "yaml" | "markdown" | "graphql" | "sql" | "bash" | "shell" | "diff" | "hcl" | "toml";
10
+ /**
11
+ * Common language aliases mapped to their canonical SupportedLanguage names.
12
+ *
13
+ * Markdown code fences often use short aliases (e.g., `js`, `ts`, `sh`) that
14
+ * don't match the canonical grammar names but should resolve to them.
15
+ *
16
+ * Note: `mdx` is intentionally omitted because it has a distinct grammar
17
+ * (Markdown + JSX) that would lose JSX highlighting if mapped to `markdown`.
18
+ */
19
+ export declare const LANGUAGE_ALIASES: {
20
+ readonly js: "javascript";
21
+ readonly cjs: "javascript";
22
+ readonly mjs: "javascript";
23
+ readonly ts: "typescript";
24
+ readonly cts: "typescript";
25
+ readonly mts: "typescript";
26
+ readonly sh: "bash";
27
+ readonly zsh: "bash";
28
+ readonly yml: "yaml";
29
+ readonly py: "python";
30
+ readonly md: "markdown";
31
+ readonly gql: "graphql";
32
+ };
33
+ /** A known alias that maps to a SupportedLanguage. */
34
+ export type LanguageAlias = keyof typeof LANGUAGE_ALIASES;
35
+ /** Any language identifier accepted by ShikiProvider and highlight(). */
36
+ export type LanguageInput = SupportedLanguage | LanguageAlias;
10
37
  /**
11
38
  * Shiki engine choice for syntax highlighting.
12
39
  * - `"javascript"` — Smaller bundle (~50KB), slightly less accurate
@@ -34,10 +61,10 @@ export interface ShikiProviderProps {
34
61
  engine: ShikiEngine;
35
62
  /**
36
63
  * Languages to support. Only these languages will be loaded.
37
- * Must be from the supported language set.
38
- * @example ['tsx', 'typescript', 'bash', 'json']
64
+ * Accepts canonical names (`'javascript'`) or common aliases (`'js'`).
65
+ * @example ['tsx', 'ts', 'bash', 'json']
39
66
  */
40
- languages: SupportedLanguage[];
67
+ languages: LanguageInput[];
41
68
  /**
42
69
  * Localized labels for UI elements (copy button, etc.).
43
70
  * Can be overridden at the component level.
@@ -55,8 +82,11 @@ export interface UseShikiHighlighterResult {
55
82
  * Highlight code and return HTML string.
56
83
  * Returns `null` if highlighter is not ready or highlighting fails.
57
84
  * When `null` is returned, render the code as plain text.
85
+ *
86
+ * Accepts language aliases (e.g., 'js', 'ts', 'sh') which are automatically
87
+ * normalized to their canonical SupportedLanguage names.
58
88
  */
59
- highlight: (code: string, lang: SupportedLanguage) => string | null;
89
+ highlight: (code: string, lang: LanguageInput | (string & {})) => string | null;
60
90
  /** True while Shiki is loading */
61
91
  isLoading: boolean;
62
92
  /** True when highlight() is safe to call */
@@ -74,9 +104,10 @@ export interface CodeHighlightedProps {
74
104
  code: string;
75
105
  /**
76
106
  * Language identifier for syntax highlighting.
107
+ * Accepts canonical names or common aliases (e.g., 'js', 'ts').
77
108
  * Must be included in the ShikiProvider's `languages` array.
78
109
  */
79
- lang: SupportedLanguage;
110
+ lang: LanguageInput | (string & {});
80
111
  /** Display line numbers */
81
112
  showLineNumbers?: boolean;
82
113
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/code/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,YAAY,GACZ,KAAK,GACL,KAAK,GACL,MAAM,GACN,OAAO,GACP,MAAM,GACN,KAAK,GACL,QAAQ,GACR,MAAM,GACN,UAAU,GACV,SAAS,GACT,KAAK,GACL,MAAM,GACN,OAAO,GACP,MAAM,GACN,KAAK,GACL,MAAM,CAAC;AAEX;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;;;OAIG;IACH,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAE/B;;;;OAIG;IACH,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAE/B,qBAAqB;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,KAAK,MAAM,GAAG,IAAI,CAAC;IAEpE,kCAAkC;IAClC,SAAS,EAAE,OAAO,CAAC;IAEnB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IAEjB,2CAA2C;IAC3C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB,qCAAqC;IACrC,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,IAAI,EAAE,iBAAiB,CAAC;IAExB,2BAA2B;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B,oCAAoC;IACpC,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAE/B,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,gDAAgD;AAChD,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/code/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,YAAY,GACZ,KAAK,GACL,KAAK,GACL,MAAM,GACN,OAAO,GACP,MAAM,GACN,KAAK,GACL,QAAQ,GACR,MAAM,GACN,UAAU,GACV,SAAS,GACT,KAAK,GACL,MAAM,GACN,OAAO,GACP,MAAM,GACN,KAAK,GACL,MAAM,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;CAayB,CAAC;AAEvD,sDAAsD;AACtD,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,gBAAgB,CAAC;AAE1D,yEAAyE;AACzE,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,aAAa,CAAC;AAE9D;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;;;OAIG;IACH,SAAS,EAAE,aAAa,EAAE,CAAC;IAE3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAE/B,qBAAqB;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;;;;;OAOG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAC;IAEhF,kCAAkC;IAClC,SAAS,EAAE,OAAO,CAAC;IAEnB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IAEjB,2CAA2C;IAC3C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB,qCAAqC;IACrC,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,IAAI,EAAE,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAEpC,2BAA2B;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B,oCAAoC;IACpC,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAE/B,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,gDAAgD;AAChD,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-shiki-highlighter.d.ts","sourceRoot":"","sources":["../../../src/code/use-shiki-highlighter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAqB,MAAM,SAAS,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,mBAAmB,IAAI,yBAAyB,CAyD/D"}
1
+ {"version":3,"file":"use-shiki-highlighter.d.ts","sourceRoot":"","sources":["../../../src/code/use-shiki-highlighter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,mBAAmB,IAAI,yBAAyB,CA4D/D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/kumo",
3
- "version": "2.2.1",
3
+ "version": "2.2.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Kumo - Cloudflare's component library for building modern web applications",