fumadocs-core 14.0.1 → 14.1.0
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/dist/chunk-7CSWJQ5H.js +59 -0
- package/dist/chunk-EMWGTXSW.js +19 -0
- package/dist/mdx-plugins/index.js +258 -21
- package/dist/search/client.js +1 -1
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.js +8 -0
- package/dist/shiki-FJwEmGMA.d.ts +16 -0
- package/dist/sidebar.js +2 -3
- package/dist/toc.js +1 -1
- package/dist/utils/use-on-change.js +1 -1
- package/dist/utils/use-shiki.d.ts +11 -0
- package/dist/utils/use-shiki.js +38 -0
- package/package.json +30 -11
- package/dist/chunk-I5BWASD6.js +0 -13
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// src/server/shiki.ts
|
|
2
|
+
import {
|
|
3
|
+
getSingletonHighlighter
|
|
4
|
+
} from "shiki";
|
|
5
|
+
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
|
|
6
|
+
import { Fragment } from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { createOnigurumaEngine } from "shiki/engine/oniguruma";
|
|
9
|
+
function createStyleTransformer() {
|
|
10
|
+
return {
|
|
11
|
+
name: "rehype-code:styles",
|
|
12
|
+
line(hast) {
|
|
13
|
+
if (hast.children.length === 0) {
|
|
14
|
+
hast.children.push({
|
|
15
|
+
type: "text",
|
|
16
|
+
value: " "
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
var defaultThemes = {
|
|
23
|
+
light: "github-light",
|
|
24
|
+
dark: "github-dark"
|
|
25
|
+
};
|
|
26
|
+
async function highlight(code, options) {
|
|
27
|
+
const { lang, components, engine, ...rest } = options;
|
|
28
|
+
let themes = { themes: defaultThemes };
|
|
29
|
+
if ("theme" in options && options.theme) {
|
|
30
|
+
themes = { theme: options.theme };
|
|
31
|
+
} else if ("themes" in options && options.themes) {
|
|
32
|
+
themes = { themes: options.themes };
|
|
33
|
+
}
|
|
34
|
+
const highlighter = await getSingletonHighlighter({
|
|
35
|
+
langs: [lang],
|
|
36
|
+
engine: engine ?? createOnigurumaEngine(() => import("shiki/wasm")),
|
|
37
|
+
themes: "theme" in themes ? [themes.theme] : Object.values(themes.themes).filter((v) => v !== void 0)
|
|
38
|
+
});
|
|
39
|
+
const hast = highlighter.codeToHast(code, {
|
|
40
|
+
lang,
|
|
41
|
+
...rest,
|
|
42
|
+
...themes,
|
|
43
|
+
transformers: [createStyleTransformer(), ...rest.transformers ?? []],
|
|
44
|
+
defaultColor: "themes" in themes ? false : void 0
|
|
45
|
+
});
|
|
46
|
+
return toJsxRuntime(hast, {
|
|
47
|
+
jsx,
|
|
48
|
+
jsxs,
|
|
49
|
+
development: false,
|
|
50
|
+
components,
|
|
51
|
+
Fragment
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
createStyleTransformer,
|
|
57
|
+
defaultThemes,
|
|
58
|
+
highlight
|
|
59
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/utils/use-on-change.ts
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
function isDifferent(a, b) {
|
|
4
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
5
|
+
return b.length !== a.length || a.some((v, i) => isDifferent(v, b[i]));
|
|
6
|
+
}
|
|
7
|
+
return a !== b;
|
|
8
|
+
}
|
|
9
|
+
function useOnChange(value, onChange, isUpdated = isDifferent) {
|
|
10
|
+
const [prev, setPrev] = useState(value);
|
|
11
|
+
if (isUpdated(prev, value)) {
|
|
12
|
+
onChange(value, prev);
|
|
13
|
+
setPrev(value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
useOnChange
|
|
19
|
+
};
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
slash
|
|
3
|
-
} from "../chunk-UWEEHUJV.js";
|
|
4
1
|
import {
|
|
5
2
|
flattenNode,
|
|
6
3
|
remarkHeading
|
|
7
4
|
} from "../chunk-4MNUWZIW.js";
|
|
5
|
+
import {
|
|
6
|
+
createStyleTransformer,
|
|
7
|
+
defaultThemes
|
|
8
|
+
} from "../chunk-7CSWJQ5H.js";
|
|
9
|
+
import {
|
|
10
|
+
slash
|
|
11
|
+
} from "../chunk-UWEEHUJV.js";
|
|
8
12
|
import "../chunk-MLKGABMK.js";
|
|
9
13
|
|
|
10
14
|
// src/mdx-plugins/index.ts
|
|
@@ -14,11 +18,254 @@ import {
|
|
|
14
18
|
|
|
15
19
|
// src/mdx-plugins/rehype-code.ts
|
|
16
20
|
import rehypeShikiFromHighlighter from "@shikijs/rehype/core";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
// ../../node_modules/.pnpm/shiki-transformers@1.0.0_shiki@1.22.2/node_modules/shiki-transformers/dist/index.js
|
|
23
|
+
var matchers = [
|
|
24
|
+
[/^(<!--)(.+)(-->)$/, true],
|
|
25
|
+
[/^(\/\*)(.+)(\*\/)$/, true],
|
|
26
|
+
[/^(\/\/|["']|;{1,2}|%{1,2}|--|#)(.+)$/, false]
|
|
27
|
+
];
|
|
28
|
+
function parseComments(lines, jsx) {
|
|
29
|
+
const out = [];
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
const elements = line.children;
|
|
32
|
+
const start = jsx ? elements.length - 2 : elements.length - 1;
|
|
33
|
+
for (let i = Math.max(start, 0); i < elements.length; i++) {
|
|
34
|
+
const token = elements[i];
|
|
35
|
+
if (token.type !== "element")
|
|
36
|
+
continue;
|
|
37
|
+
const isLast = i === elements.length - 1;
|
|
38
|
+
const match = matchToken(token, isLast);
|
|
39
|
+
if (!match) continue;
|
|
40
|
+
if (jsx && !isLast && i !== 0) {
|
|
41
|
+
const left = elements[i - 1];
|
|
42
|
+
const right = elements[i + 1];
|
|
43
|
+
out.push({
|
|
44
|
+
info: match,
|
|
45
|
+
line,
|
|
46
|
+
token,
|
|
47
|
+
jsxIntercept: isValue(left, "{") && isValue(right, "}")
|
|
48
|
+
});
|
|
49
|
+
} else {
|
|
50
|
+
out.push({
|
|
51
|
+
info: match,
|
|
52
|
+
line,
|
|
53
|
+
token,
|
|
54
|
+
jsxIntercept: false
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
function isValue(element, value) {
|
|
62
|
+
if (element.type !== "element") return false;
|
|
63
|
+
const text = element.children[0];
|
|
64
|
+
if (text.type !== "text")
|
|
65
|
+
return false;
|
|
66
|
+
return text.value.trim() === value;
|
|
67
|
+
}
|
|
68
|
+
function matchToken(token, last) {
|
|
69
|
+
const text = token.children[0];
|
|
70
|
+
if (text.type !== "text")
|
|
71
|
+
return;
|
|
72
|
+
for (const [matcher, lastOnly] of matchers) {
|
|
73
|
+
if (!lastOnly && !last) continue;
|
|
74
|
+
let trimmed = text.value.trimStart();
|
|
75
|
+
const spaceFront = text.value.length - trimmed.length;
|
|
76
|
+
trimmed = trimmed.trimEnd();
|
|
77
|
+
const spaceEnd = text.value.length - trimmed.length - spaceFront;
|
|
78
|
+
const result = matcher.exec(trimmed);
|
|
79
|
+
if (!result) continue;
|
|
80
|
+
return [
|
|
81
|
+
" ".repeat(spaceFront) + result[1],
|
|
82
|
+
result[2],
|
|
83
|
+
result[3] ? result[3] + " ".repeat(spaceEnd) : void 0
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function createCommentNotationTransformer(name, regex, onMatch) {
|
|
88
|
+
return {
|
|
89
|
+
name,
|
|
90
|
+
code(code) {
|
|
91
|
+
const lines = code.children.filter((i) => i.type === "element");
|
|
92
|
+
const linesToRemove = [];
|
|
93
|
+
code.data ??= {};
|
|
94
|
+
const data = code.data;
|
|
95
|
+
const parsed = data._shiki_notation ??= parseComments(lines, ["jsx", "tsx"].includes(this.options.lang));
|
|
96
|
+
for (const comment of parsed) {
|
|
97
|
+
if (comment.info[1].length === 0) continue;
|
|
98
|
+
const isLineCommentOnly = comment.line.children.length === (comment.jsxIntercept ? 3 : 1);
|
|
99
|
+
let lineIdx = lines.indexOf(comment.line);
|
|
100
|
+
if (isLineCommentOnly) lineIdx++;
|
|
101
|
+
comment.info[1] = comment.info[1].replace(regex, (...match) => {
|
|
102
|
+
if (onMatch.call(this, match, comment.line, comment.token, lines, lineIdx)) {
|
|
103
|
+
return "";
|
|
104
|
+
}
|
|
105
|
+
return match[0];
|
|
106
|
+
});
|
|
107
|
+
const isEmpty = comment.info[1].trim().length === 0;
|
|
108
|
+
if (isEmpty) comment.info[1] = "";
|
|
109
|
+
if (isEmpty && isLineCommentOnly) {
|
|
110
|
+
linesToRemove.push(comment.line);
|
|
111
|
+
} else if (isEmpty && comment.jsxIntercept) {
|
|
112
|
+
comment.line.children.splice(comment.line.children.indexOf(comment.token) - 1, 3);
|
|
113
|
+
} else if (isEmpty) {
|
|
114
|
+
comment.line.children.splice(comment.line.children.indexOf(comment.token), 1);
|
|
115
|
+
} else {
|
|
116
|
+
const head = comment.token.children[0];
|
|
117
|
+
if (head.type === "text") {
|
|
118
|
+
head.value = comment.info.join("");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const line of linesToRemove)
|
|
123
|
+
code.children.splice(code.children.indexOf(line), 1);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function escapeRegExp(str) {
|
|
128
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
129
|
+
}
|
|
130
|
+
function transformerNotationMap(options = {}, name = "@shikijs/transformers:notation-map") {
|
|
131
|
+
const {
|
|
132
|
+
classMap = {},
|
|
133
|
+
classActivePre = void 0
|
|
134
|
+
} = options;
|
|
135
|
+
return createCommentNotationTransformer(
|
|
136
|
+
name,
|
|
137
|
+
new RegExp(`\\s*\\[!code (${Object.keys(classMap).map(escapeRegExp).join("|")})(:\\d+)?\\]`),
|
|
138
|
+
function([_, match, range = ":1"], _line, _comment, lines, index) {
|
|
139
|
+
const lineNum = Number.parseInt(range.slice(1), 10);
|
|
140
|
+
lines.slice(index, index + lineNum).forEach((line) => {
|
|
141
|
+
this.addClassToHast(line, classMap[match]);
|
|
142
|
+
});
|
|
143
|
+
if (classActivePre)
|
|
144
|
+
this.addClassToHast(this.pre, classActivePre);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
function transformerNotationDiff(options = {}) {
|
|
150
|
+
const {
|
|
151
|
+
classLineAdd = "diff add",
|
|
152
|
+
classLineRemove = "diff remove",
|
|
153
|
+
classActivePre = "has-diff"
|
|
154
|
+
} = options;
|
|
155
|
+
return transformerNotationMap(
|
|
156
|
+
{
|
|
157
|
+
classMap: {
|
|
158
|
+
"++": classLineAdd,
|
|
159
|
+
"--": classLineRemove
|
|
160
|
+
},
|
|
161
|
+
classActivePre
|
|
162
|
+
},
|
|
163
|
+
"@shikijs/transformers:notation-diff"
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
function transformerNotationHighlight(options = {}) {
|
|
167
|
+
const {
|
|
168
|
+
classActiveLine = "highlighted",
|
|
169
|
+
classActivePre = "has-highlighted"
|
|
170
|
+
} = options;
|
|
171
|
+
return transformerNotationMap(
|
|
172
|
+
{
|
|
173
|
+
classMap: {
|
|
174
|
+
highlight: classActiveLine,
|
|
175
|
+
hl: classActiveLine
|
|
176
|
+
},
|
|
177
|
+
classActivePre
|
|
178
|
+
},
|
|
179
|
+
"@shikijs/transformers:notation-highlight"
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
function highlightWordInLine(line, ignoredElement, word, className) {
|
|
183
|
+
const content = getTextContent(line);
|
|
184
|
+
let index = content.indexOf(word);
|
|
185
|
+
while (index !== -1) {
|
|
186
|
+
highlightRange.call(this, line.children, ignoredElement, index, word.length, className);
|
|
187
|
+
index = content.indexOf(word, index + 1);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function getTextContent(element) {
|
|
191
|
+
if (element.type === "text")
|
|
192
|
+
return element.value;
|
|
193
|
+
if (element.type === "element" && element.tagName === "span")
|
|
194
|
+
return element.children.map(getTextContent).join("");
|
|
195
|
+
return "";
|
|
196
|
+
}
|
|
197
|
+
function highlightRange(elements, ignoredElement, index, len, className) {
|
|
198
|
+
let currentIdx = 0;
|
|
199
|
+
for (let i = 0; i < elements.length; i++) {
|
|
200
|
+
const element = elements[i];
|
|
201
|
+
if (element.type !== "element" || element.tagName !== "span" || element === ignoredElement)
|
|
202
|
+
continue;
|
|
203
|
+
const textNode = element.children[0];
|
|
204
|
+
if (textNode.type !== "text")
|
|
205
|
+
continue;
|
|
206
|
+
if (hasOverlap([currentIdx, currentIdx + textNode.value.length - 1], [index, index + len])) {
|
|
207
|
+
const start = Math.max(0, index - currentIdx);
|
|
208
|
+
const length = len - Math.max(0, currentIdx - index);
|
|
209
|
+
if (length === 0)
|
|
210
|
+
continue;
|
|
211
|
+
const separated = separateToken(element, textNode, start, length);
|
|
212
|
+
this.addClassToHast(separated[1], className);
|
|
213
|
+
const output = separated.filter(Boolean);
|
|
214
|
+
elements.splice(i, 1, ...output);
|
|
215
|
+
i += output.length - 1;
|
|
216
|
+
}
|
|
217
|
+
currentIdx += textNode.value.length;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function hasOverlap(range1, range2) {
|
|
221
|
+
return range1[0] <= range2[1] && range1[1] >= range2[0];
|
|
222
|
+
}
|
|
223
|
+
function separateToken(span, textNode, index, len) {
|
|
224
|
+
const text = textNode.value;
|
|
225
|
+
const createNode = (value) => inheritElement(span, {
|
|
226
|
+
children: [
|
|
227
|
+
{
|
|
228
|
+
type: "text",
|
|
229
|
+
value
|
|
230
|
+
}
|
|
231
|
+
]
|
|
232
|
+
});
|
|
233
|
+
return [
|
|
234
|
+
index > 0 ? createNode(text.slice(0, index)) : void 0,
|
|
235
|
+
createNode(text.slice(index, index + len)),
|
|
236
|
+
index + len < text.length ? createNode(text.slice(index + len)) : void 0
|
|
237
|
+
];
|
|
238
|
+
}
|
|
239
|
+
function inheritElement(original, overrides) {
|
|
240
|
+
return {
|
|
241
|
+
...original,
|
|
242
|
+
properties: {
|
|
243
|
+
...original.properties
|
|
244
|
+
},
|
|
245
|
+
...overrides
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function transformerNotationWordHighlight(options = {}) {
|
|
249
|
+
const {
|
|
250
|
+
classActiveWord = "highlighted-word",
|
|
251
|
+
classActivePre = void 0
|
|
252
|
+
} = options;
|
|
253
|
+
return createCommentNotationTransformer(
|
|
254
|
+
"@shikijs/transformers:notation-highlight-word",
|
|
255
|
+
/\s*\[!code word:((?:\\.|[^:\]])+)(:\d+)?\]/,
|
|
256
|
+
function([_, word, range], _line, comment, lines, index) {
|
|
257
|
+
const lineNum = range ? Number.parseInt(range.slice(1), 10) : lines.length;
|
|
258
|
+
word = word.replace(/\\(.)/g, "$1");
|
|
259
|
+
lines.slice(index, index + lineNum).forEach((line) => highlightWordInLine.call(this, line, comment, word, classActiveWord));
|
|
260
|
+
if (classActivePre)
|
|
261
|
+
this.addClassToHast(this.pre, classActivePre);
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
var symbol = Symbol("highlighted-lines");
|
|
267
|
+
|
|
268
|
+
// src/mdx-plugins/rehype-code.ts
|
|
22
269
|
import {
|
|
23
270
|
getSingletonHighlighter,
|
|
24
271
|
bundledLanguages
|
|
@@ -185,14 +432,12 @@ var metaValues = [
|
|
|
185
432
|
}
|
|
186
433
|
];
|
|
187
434
|
var rehypeCodeDefaultOptions = {
|
|
188
|
-
themes:
|
|
189
|
-
|
|
190
|
-
dark: "github-dark"
|
|
191
|
-
},
|
|
435
|
+
themes: defaultThemes,
|
|
436
|
+
defaultColor: false,
|
|
192
437
|
defaultLanguage: "plaintext",
|
|
193
438
|
experimentalJSEngine: false,
|
|
194
|
-
defaultColor: false,
|
|
195
439
|
transformers: [
|
|
440
|
+
createStyleTransformer(),
|
|
196
441
|
transformerNotationHighlight(),
|
|
197
442
|
transformerNotationWordHighlight(),
|
|
198
443
|
transformerNotationDiff()
|
|
@@ -229,14 +474,6 @@ function rehypeCode(options = {}) {
|
|
|
229
474
|
meta.__raw = codeOptions.filterMetaString(meta.__raw ?? "");
|
|
230
475
|
}
|
|
231
476
|
return code.replace(/\n$/, "");
|
|
232
|
-
},
|
|
233
|
-
line(hast) {
|
|
234
|
-
if (hast.children.length === 0) {
|
|
235
|
-
hast.children.push({
|
|
236
|
-
type: "text",
|
|
237
|
-
value: " "
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
477
|
}
|
|
241
478
|
},
|
|
242
479
|
...codeOptions.transformers
|
package/dist/search/client.js
CHANGED
package/dist/server/index.d.ts
CHANGED
|
@@ -5,8 +5,12 @@ export { S as SortedResult } from '../types-Ch8gnVgO.js';
|
|
|
5
5
|
import { Metadata } from 'next';
|
|
6
6
|
import { NextRequest } from 'next/server';
|
|
7
7
|
import { LoaderOutput, LoaderConfig, InferPageType } from '../source/index.js';
|
|
8
|
+
export { H as HighlightOptions, c as createStyleTransformer, d as defaultThemes, h as highlight } from '../shiki-FJwEmGMA.js';
|
|
8
9
|
import 'react';
|
|
9
10
|
import '../config-inq6kP6y.js';
|
|
11
|
+
import 'shiki';
|
|
12
|
+
import 'shiki/themes';
|
|
13
|
+
import 'hast-util-to-jsx-runtime';
|
|
10
14
|
|
|
11
15
|
/**
|
|
12
16
|
* Flatten tree to an array of page nodes
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
remarkHeading
|
|
3
3
|
} from "../chunk-4MNUWZIW.js";
|
|
4
|
+
import {
|
|
5
|
+
createStyleTransformer,
|
|
6
|
+
defaultThemes,
|
|
7
|
+
highlight
|
|
8
|
+
} from "../chunk-7CSWJQ5H.js";
|
|
4
9
|
import "../chunk-MLKGABMK.js";
|
|
5
10
|
|
|
6
11
|
// src/server/get-toc.ts
|
|
@@ -147,9 +152,12 @@ function createMetadataImage(options) {
|
|
|
147
152
|
export {
|
|
148
153
|
page_tree_exports as PageTree,
|
|
149
154
|
createMetadataImage,
|
|
155
|
+
createStyleTransformer,
|
|
156
|
+
defaultThemes,
|
|
150
157
|
findNeighbour,
|
|
151
158
|
flattenTree,
|
|
152
159
|
getGithubLastEdit,
|
|
153
160
|
getTableOfContents,
|
|
161
|
+
highlight,
|
|
154
162
|
separatePageTree
|
|
155
163
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ShikiTransformer, CodeToHastOptionsCommon, BundledLanguage, HighlighterCoreOptions, CodeOptionsThemes, CodeOptionsMeta } from 'shiki';
|
|
2
|
+
import { BundledTheme } from 'shiki/themes';
|
|
3
|
+
import { Components } from 'hast-util-to-jsx-runtime';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
declare function createStyleTransformer(): ShikiTransformer;
|
|
7
|
+
declare const defaultThemes: {
|
|
8
|
+
light: string;
|
|
9
|
+
dark: string;
|
|
10
|
+
};
|
|
11
|
+
type HighlightOptions = CodeToHastOptionsCommon<BundledLanguage> & Pick<HighlighterCoreOptions, 'engine'> & Partial<CodeOptionsThemes<BundledTheme>> & CodeOptionsMeta & {
|
|
12
|
+
components?: Partial<Components>;
|
|
13
|
+
};
|
|
14
|
+
declare function highlight(code: string, options: HighlightOptions): Promise<ReactNode>;
|
|
15
|
+
|
|
16
|
+
export { type HighlightOptions as H, createStyleTransformer as c, defaultThemes as d, highlight as h };
|
package/dist/sidebar.js
CHANGED
|
@@ -3,7 +3,6 @@ import "./chunk-MLKGABMK.js";
|
|
|
3
3
|
|
|
4
4
|
// src/sidebar.tsx
|
|
5
5
|
import {
|
|
6
|
-
useCallback,
|
|
7
6
|
createContext,
|
|
8
7
|
useContext,
|
|
9
8
|
useEffect,
|
|
@@ -38,9 +37,9 @@ function SidebarTrigger({
|
|
|
38
37
|
{
|
|
39
38
|
"aria-label": "Toggle Sidebar",
|
|
40
39
|
"data-open": open,
|
|
41
|
-
onClick:
|
|
40
|
+
onClick: () => {
|
|
42
41
|
setOpen(!open);
|
|
43
|
-
},
|
|
42
|
+
},
|
|
44
43
|
...props
|
|
45
44
|
}
|
|
46
45
|
);
|
package/dist/toc.js
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactNode, DependencyList } from 'react';
|
|
2
|
+
import { H as HighlightOptions } from '../shiki-FJwEmGMA.js';
|
|
3
|
+
import 'shiki';
|
|
4
|
+
import 'shiki/themes';
|
|
5
|
+
import 'hast-util-to-jsx-runtime';
|
|
6
|
+
|
|
7
|
+
declare function useShiki(code: string, options: HighlightOptions & {
|
|
8
|
+
defaultValue?: ReactNode;
|
|
9
|
+
}, deps?: DependencyList): ReactNode;
|
|
10
|
+
|
|
11
|
+
export { useShiki };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
highlight
|
|
4
|
+
} from "../chunk-7CSWJQ5H.js";
|
|
5
|
+
import "../chunk-MLKGABMK.js";
|
|
6
|
+
|
|
7
|
+
// src/utils/use-shiki.tsx
|
|
8
|
+
import {
|
|
9
|
+
useEffect,
|
|
10
|
+
useState
|
|
11
|
+
} from "react";
|
|
12
|
+
import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
|
|
13
|
+
import { jsx } from "react/jsx-runtime";
|
|
14
|
+
var jsEngine;
|
|
15
|
+
function useShiki(code, options, deps) {
|
|
16
|
+
const [out, setOut] = useState(() => {
|
|
17
|
+
if (options.defaultValue) return options.defaultValue;
|
|
18
|
+
const { pre: Pre = "pre", code: Code = "code" } = options.components ?? {};
|
|
19
|
+
return /* @__PURE__ */ jsx(Pre, { children: /* @__PURE__ */ jsx(Code, { children: code }) });
|
|
20
|
+
});
|
|
21
|
+
if (!options.engine && !jsEngine) {
|
|
22
|
+
jsEngine = createJavaScriptRegexEngine();
|
|
23
|
+
}
|
|
24
|
+
useEffect(
|
|
25
|
+
() => {
|
|
26
|
+
void highlight(code, {
|
|
27
|
+
...options,
|
|
28
|
+
engine: options.engine ?? jsEngine
|
|
29
|
+
}).then(setOut);
|
|
30
|
+
},
|
|
31
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- custom deps
|
|
32
|
+
deps ?? [code, options.lang]
|
|
33
|
+
);
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
useShiki
|
|
38
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-core",
|
|
3
|
-
"version": "14.0
|
|
3
|
+
"version": "14.1.0",
|
|
4
4
|
"description": "The library for building a documentation website in Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -48,6 +48,10 @@
|
|
|
48
48
|
"import": "./dist/utils/use-on-change.js",
|
|
49
49
|
"types": "./dist/utils/use-on-change.d.ts"
|
|
50
50
|
},
|
|
51
|
+
"./utils/use-shiki": {
|
|
52
|
+
"import": "./dist/utils/use-shiki.js",
|
|
53
|
+
"types": "./dist/utils/use-shiki.d.ts"
|
|
54
|
+
},
|
|
51
55
|
"./link": {
|
|
52
56
|
"import": "./dist/link.js",
|
|
53
57
|
"types": "./dist/link.d.ts"
|
|
@@ -65,19 +69,19 @@
|
|
|
65
69
|
"dist/*"
|
|
66
70
|
],
|
|
67
71
|
"dependencies": {
|
|
68
|
-
"@formatjs/intl-localematcher": "^0.5.
|
|
72
|
+
"@formatjs/intl-localematcher": "^0.5.6",
|
|
69
73
|
"@orama/orama": "^3.0.1",
|
|
70
|
-
"@shikijs/rehype": "^1.22.
|
|
71
|
-
"@shikijs/transformers": "^1.22.0",
|
|
74
|
+
"@shikijs/rehype": "^1.22.2",
|
|
72
75
|
"github-slugger": "^2.0.0",
|
|
73
76
|
"hast-util-to-estree": "^3.1.0",
|
|
77
|
+
"hast-util-to-jsx-runtime": "^2.3.2",
|
|
74
78
|
"image-size": "^1.1.1",
|
|
75
79
|
"negotiator": "^1.0.0",
|
|
76
80
|
"react-remove-scroll": "^2.6.0",
|
|
77
81
|
"remark": "^15.0.0",
|
|
78
82
|
"remark-gfm": "^4.0.0",
|
|
79
83
|
"scroll-into-view-if-needed": "^3.1.0",
|
|
80
|
-
"shiki": "^1.22.
|
|
84
|
+
"shiki": "^1.22.2",
|
|
81
85
|
"unist-util-visit": "^5.0.0"
|
|
82
86
|
},
|
|
83
87
|
"devDependencies": {
|
|
@@ -87,8 +91,8 @@
|
|
|
87
91
|
"@types/hast": "^3.0.4",
|
|
88
92
|
"@types/mdast": "^4.0.3",
|
|
89
93
|
"@types/negotiator": "^0.6.3",
|
|
90
|
-
"@types/node": "22.
|
|
91
|
-
"@types/react": "^18.3.
|
|
94
|
+
"@types/node": "22.8.1",
|
|
95
|
+
"@types/react": "^18.3.12",
|
|
92
96
|
"@types/react-dom": "^18.3.1",
|
|
93
97
|
"algoliasearch": "4.24.0",
|
|
94
98
|
"mdast-util-mdx-jsx": "^3.1.3",
|
|
@@ -96,16 +100,31 @@
|
|
|
96
100
|
"next": "^15.0.0",
|
|
97
101
|
"remark-mdx": "^3.1.0",
|
|
98
102
|
"remark-rehype": "^11.1.1",
|
|
103
|
+
"shiki-transformers": "^1.0.0",
|
|
99
104
|
"unified": "^11.0.5",
|
|
100
|
-
"
|
|
101
|
-
"
|
|
105
|
+
"tsconfig": "0.0.0",
|
|
106
|
+
"eslint-config-custom": "0.0.0"
|
|
102
107
|
},
|
|
103
|
-
"
|
|
108
|
+
"peerDependencies": {
|
|
104
109
|
"algoliasearch": "4.24.0",
|
|
105
|
-
"next": "15.
|
|
110
|
+
"next": "14.x.x || 15.x.x",
|
|
106
111
|
"react": ">= 18",
|
|
107
112
|
"react-dom": ">= 18"
|
|
108
113
|
},
|
|
114
|
+
"peerDependenciesMeta": {
|
|
115
|
+
"algoliasearch": {
|
|
116
|
+
"optional": true
|
|
117
|
+
},
|
|
118
|
+
"next": {
|
|
119
|
+
"optional": true
|
|
120
|
+
},
|
|
121
|
+
"react": {
|
|
122
|
+
"optional": true
|
|
123
|
+
},
|
|
124
|
+
"react-dom": {
|
|
125
|
+
"optional": true
|
|
126
|
+
}
|
|
127
|
+
},
|
|
109
128
|
"publishConfig": {
|
|
110
129
|
"access": "public"
|
|
111
130
|
},
|
package/dist/chunk-I5BWASD6.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// src/utils/use-on-change.ts
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
function useOnChange(value, onChange, isUpdated = (prev, current) => prev !== current) {
|
|
4
|
-
const [prev, setPrev] = useState(value);
|
|
5
|
-
if (isUpdated(prev, value)) {
|
|
6
|
-
onChange(value, prev);
|
|
7
|
-
setPrev(value);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
useOnChange
|
|
13
|
-
};
|