@unfold-mdx/react 0.0.1

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/index.cjs ADDED
@@ -0,0 +1,626 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Depth: () => Depth,
34
+ DepthCode: () => DepthCode,
35
+ DepthLevel: () => DepthLevel,
36
+ DepthPane: () => DepthPane,
37
+ codeDiff: () => codeDiff,
38
+ sentenceDiff: () => sentenceDiff,
39
+ tokenize: () => tokenize,
40
+ tokenizeCodeLine: () => tokenizeCodeLine,
41
+ tokenizeLines: () => tokenizeLines
42
+ });
43
+ module.exports = __toCommonJS(index_exports);
44
+
45
+ // src/diff/tokenize.ts
46
+ function tokenize(text) {
47
+ if (!text) {
48
+ return [];
49
+ }
50
+ const splitRegex = /(?<=(?:(?<!\.)\.(?!\.)|[!?]))(?=\s|$)/;
51
+ return text.split(splitRegex).map((token) => token.trim()).filter((token) => token.length > 0);
52
+ }
53
+
54
+ // src/diff/sentenceDiff.ts
55
+ var import_diff_match_patch = require("diff-match-patch");
56
+ function sentenceDiff(prev, next) {
57
+ const prevSentences = tokenize(prev);
58
+ const nextSentences = tokenize(next);
59
+ const sentenceToChar = /* @__PURE__ */ new Map();
60
+ const charToSentence = [];
61
+ function getCharForSentence(sentence) {
62
+ let char = sentenceToChar.get(sentence);
63
+ if (char === void 0) {
64
+ const code = charToSentence.length;
65
+ char = String.fromCharCode(code);
66
+ sentenceToChar.set(sentence, char);
67
+ charToSentence.push(sentence);
68
+ }
69
+ return char;
70
+ }
71
+ const prevChars = prevSentences.map(getCharForSentence).join("");
72
+ const nextChars = nextSentences.map(getCharForSentence).join("");
73
+ const dmp = new import_diff_match_patch.diff_match_patch();
74
+ const diffs = dmp.diff_main(prevChars, nextChars);
75
+ dmp.diff_cleanupSemantic(diffs);
76
+ const result = [];
77
+ let i = 0;
78
+ while (i < diffs.length) {
79
+ const [op, text] = diffs[i];
80
+ if (op === 0) {
81
+ for (let j = 0; j < text.length; j++) {
82
+ result.push({
83
+ kind: "equal",
84
+ sentence: charToSentence[text.charCodeAt(j)]
85
+ });
86
+ }
87
+ i++;
88
+ } else if (op === -1 && i + 1 < diffs.length && diffs[i + 1][0] === 1) {
89
+ const deleteText = text;
90
+ const insertText = diffs[i + 1][1];
91
+ const deleteLen = deleteText.length;
92
+ const insertLen = insertText.length;
93
+ const minLen = Math.min(deleteLen, insertLen);
94
+ for (let j = 0; j < minLen; j++) {
95
+ result.push({
96
+ kind: "modified",
97
+ before: charToSentence[deleteText.charCodeAt(j)],
98
+ after: charToSentence[insertText.charCodeAt(j)]
99
+ });
100
+ }
101
+ for (let j = minLen; j < deleteLen; j++) {
102
+ result.push({
103
+ kind: "removed",
104
+ sentence: charToSentence[deleteText.charCodeAt(j)]
105
+ });
106
+ }
107
+ for (let j = minLen; j < insertLen; j++) {
108
+ result.push({
109
+ kind: "added",
110
+ sentence: charToSentence[insertText.charCodeAt(j)]
111
+ });
112
+ }
113
+ i += 2;
114
+ } else if (op === -1) {
115
+ for (let j = 0; j < text.length; j++) {
116
+ result.push({
117
+ kind: "removed",
118
+ sentence: charToSentence[text.charCodeAt(j)]
119
+ });
120
+ }
121
+ i++;
122
+ } else if (op === 1) {
123
+ for (let j = 0; j < text.length; j++) {
124
+ result.push({
125
+ kind: "added",
126
+ sentence: charToSentence[text.charCodeAt(j)]
127
+ });
128
+ }
129
+ i++;
130
+ }
131
+ }
132
+ return result;
133
+ }
134
+
135
+ // src/diff/codeTokenize.ts
136
+ function tokenizeLines(code) {
137
+ if (code === "") return [];
138
+ return code.split(/\r?\n/);
139
+ }
140
+ function tokenizeCodeLine(line) {
141
+ if (line === "") return [];
142
+ const regex = /([a-zA-Z0-9_]+|\s+|[^a-zA-Z0-9_\s])/g;
143
+ const tokens = [];
144
+ let match;
145
+ while ((match = regex.exec(line)) !== null) {
146
+ if (match[0].length > 0) {
147
+ tokens.push(match[0]);
148
+ }
149
+ }
150
+ return tokens;
151
+ }
152
+
153
+ // src/diff/codeDiff.ts
154
+ var import_diff_match_patch2 = require("diff-match-patch");
155
+ function codeDiff(prev, next) {
156
+ if (prev === "" && next !== "") {
157
+ return tokenizeLines(next).map((line) => ({
158
+ kind: "added",
159
+ tokens: tokenizeCodeLine(line).map((t) => ({ kind: "added", text: t }))
160
+ }));
161
+ }
162
+ const prevLines = tokenizeLines(prev);
163
+ const nextLines = tokenizeLines(next);
164
+ const lineToChar = /* @__PURE__ */ new Map();
165
+ const charToLine = [];
166
+ function getCharForLine(line) {
167
+ let char = lineToChar.get(line);
168
+ if (char === void 0) {
169
+ const code = charToLine.length;
170
+ char = String.fromCharCode(code);
171
+ lineToChar.set(line, char);
172
+ charToLine.push(line);
173
+ }
174
+ return char;
175
+ }
176
+ const prevChars = prevLines.map(getCharForLine).join("");
177
+ const nextChars = nextLines.map(getCharForLine).join("");
178
+ const dmp = new import_diff_match_patch2.diff_match_patch();
179
+ const diffs = dmp.diff_main(prevChars, nextChars);
180
+ dmp.diff_cleanupSemantic(diffs);
181
+ const result = [];
182
+ let i = 0;
183
+ while (i < diffs.length) {
184
+ const [op, text] = diffs[i];
185
+ if (op === 0) {
186
+ for (let j = 0; j < text.length; j++) {
187
+ result.push({
188
+ kind: "equal",
189
+ line: charToLine[text.charCodeAt(j)]
190
+ });
191
+ }
192
+ i++;
193
+ } else if (op === -1 && i + 1 < diffs.length && diffs[i + 1][0] === 1) {
194
+ const deleteText = text;
195
+ const insertText = diffs[i + 1][1];
196
+ const deleteLen = deleteText.length;
197
+ const insertLen = insertText.length;
198
+ const minLen = Math.min(deleteLen, insertLen);
199
+ for (let j = 0; j < minLen; j++) {
200
+ let getCharForToken2 = function(tok) {
201
+ let char = tokenToChar.get(tok);
202
+ if (char === void 0) {
203
+ const code = charToToken.length;
204
+ char = String.fromCharCode(code);
205
+ tokenToChar.set(tok, char);
206
+ charToToken.push(tok);
207
+ }
208
+ return char;
209
+ };
210
+ var getCharForToken = getCharForToken2;
211
+ const prevLine = charToLine[deleteText.charCodeAt(j)];
212
+ const nextLine = charToLine[insertText.charCodeAt(j)];
213
+ const prevTokens = tokenizeCodeLine(prevLine);
214
+ const nextTokens = tokenizeCodeLine(nextLine);
215
+ const tokenToChar = /* @__PURE__ */ new Map();
216
+ const charToToken = [];
217
+ const prevTokChars = prevTokens.map(getCharForToken2).join("");
218
+ const nextTokChars = nextTokens.map(getCharForToken2).join("");
219
+ const tokDiffs = dmp.diff_main(prevTokChars, nextTokChars);
220
+ dmp.diff_cleanupSemantic(tokDiffs);
221
+ const tokens = [];
222
+ for (let k = 0; k < tokDiffs.length; k++) {
223
+ const [tokOp, tokText] = tokDiffs[k];
224
+ if (tokOp === 0) {
225
+ for (let c = 0; c < tokText.length; c++) {
226
+ tokens.push({ kind: "equal", text: charToToken[tokText.charCodeAt(c)] });
227
+ }
228
+ } else if (tokOp === 1) {
229
+ for (let c = 0; c < tokText.length; c++) {
230
+ tokens.push({ kind: "added", text: charToToken[tokText.charCodeAt(c)] });
231
+ }
232
+ }
233
+ }
234
+ result.push({ kind: "changed", tokens });
235
+ }
236
+ for (let j = minLen; j < insertLen; j++) {
237
+ const line = charToLine[insertText.charCodeAt(j)];
238
+ const tokens = tokenizeCodeLine(line).map((t) => ({ kind: "added", text: t }));
239
+ result.push({ kind: "added", tokens });
240
+ }
241
+ i += 2;
242
+ } else if (op === -1) {
243
+ i++;
244
+ } else if (op === 1) {
245
+ for (let j = 0; j < text.length; j++) {
246
+ const line = charToLine[text.charCodeAt(j)];
247
+ const tokens = tokenizeCodeLine(line).map((t) => ({ kind: "added", text: t }));
248
+ result.push({ kind: "added", tokens });
249
+ }
250
+ i++;
251
+ }
252
+ }
253
+ return result;
254
+ }
255
+
256
+ // src/components/Depth.tsx
257
+ var import_react4 = __toESM(require("react"), 1);
258
+
259
+ // src/context/DepthContext.tsx
260
+ var import_react = require("react");
261
+ var DepthContext = (0, import_react.createContext)(null);
262
+
263
+ // src/components/DepthLevel.tsx
264
+ var import_jsx_runtime = require("react/jsx-runtime");
265
+ function DepthLevel({ label, children, ...props }) {
266
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "data-depth-level": true, ...props, children });
267
+ }
268
+ DepthLevel.unfoldType = "level";
269
+
270
+ // src/components/DepthCode.tsx
271
+ var import_jsx_runtime2 = require("react/jsx-runtime");
272
+ function DepthCode({ lang, label, children, ...rest }) {
273
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { "data-lang": lang, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children }) });
274
+ }
275
+ DepthCode.unfoldType = "code";
276
+
277
+ // src/components/DepthPane.tsx
278
+ var import_react2 = require("react");
279
+ var import_jsx_runtime3 = require("react/jsx-runtime");
280
+ var noopSubscribe = () => () => {
281
+ };
282
+ function DepthPane({
283
+ show,
284
+ proseDiff,
285
+ codeDiff: codeDiff2,
286
+ justEntered,
287
+ animate,
288
+ codeLang,
289
+ codeText,
290
+ highlighter,
291
+ highlight = true
292
+ }) {
293
+ const showProse = show === "both" || show === "prose";
294
+ const showCode = show === "both" || show === "code";
295
+ const enterState = animate && justEntered ? "true" : void 0;
296
+ const getStatus = (itemKind) => {
297
+ if (!highlight || itemKind === "equal") return "equal";
298
+ return "added";
299
+ };
300
+ (0, import_react2.useSyncExternalStore)(
301
+ highlighter?.subscribe ?? noopSubscribe,
302
+ () => highlighter?.getSnapshot() ?? 0,
303
+ () => highlighter?.getSnapshot() ?? 0
304
+ );
305
+ let finalCodeDiff = codeDiff2;
306
+ if (highlighter && codeText !== void 0 && codeLang !== void 0) {
307
+ const highlighted = highlighter.highlight(codeText, codeLang, codeDiff2);
308
+ if (highlighted) {
309
+ finalCodeDiff = highlighted;
310
+ }
311
+ }
312
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { "data-unfold-panes": true, children: [
313
+ showProse && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "data-unfold-pane": "prose", "aria-live": "polite", children: proseDiff.filter((item) => item.kind !== "removed").map((item, index) => {
314
+ const status = getStatus(item.kind);
315
+ const sentenceText = item.kind === "modified" ? item.after : item.sentence;
316
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
317
+ "span",
318
+ {
319
+ "data-sentence": status,
320
+ "data-enter": status === "added" ? enterState : void 0,
321
+ children: [
322
+ sentenceText,
323
+ " "
324
+ ]
325
+ },
326
+ `prose-${index}`
327
+ );
328
+ }) }),
329
+ showCode && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "data-unfold-pane": "code", "aria-live": "polite", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("pre", { "data-lang": codeLang, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { children: finalCodeDiff.map((lineDiff, lineIndex) => {
330
+ const lineText = lineDiff.tokens ? lineDiff.tokens.map((t) => t.text).join("") : lineDiff.line || "";
331
+ const isWhitespaceOnly = lineText.trim() === "";
332
+ const lineStatus = isWhitespaceOnly ? "equal" : getStatus(lineDiff.kind);
333
+ if (lineDiff.kind === "equal" && !lineDiff.tokens) {
334
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { "data-code-line": "equal", children: [
335
+ lineDiff.line,
336
+ "\n"
337
+ ] }, `line-${lineIndex}`);
338
+ }
339
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
340
+ "span",
341
+ {
342
+ "data-code-line": lineStatus,
343
+ "data-enter": lineStatus === "added" ? enterState : void 0,
344
+ children: [
345
+ lineDiff.tokens?.map((token, tokenIndex) => {
346
+ const tokenStatus = getStatus(token.kind);
347
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
348
+ "span",
349
+ {
350
+ "data-code-token": isWhitespaceOnly ? "equal" : tokenStatus,
351
+ style: token.color ? { color: token.color } : void 0,
352
+ children: token.text
353
+ },
354
+ `token-${tokenIndex}`
355
+ );
356
+ }),
357
+ "\n"
358
+ ]
359
+ },
360
+ `line-${lineIndex}`
361
+ );
362
+ }) }) }) })
363
+ ] });
364
+ }
365
+
366
+ // src/components/controls/Controls.tsx
367
+ var import_react3 = require("react");
368
+ var import_jsx_runtime4 = require("react/jsx-runtime");
369
+ var BUTTON_LABELS = {
370
+ text: { prev: "Prev", next: "Next" },
371
+ arrow: { prev: "\u2190 Prev", next: "Next \u2192" },
372
+ chevron: { prev: "\u2039 Prev", next: "Next \u203A" },
373
+ minimal: { prev: "\u2039", next: "\u203A" }
374
+ };
375
+ function Controls({ buttonVariant, indicators }) {
376
+ const context = (0, import_react3.useContext)(DepthContext);
377
+ if (!context) return null;
378
+ const { selectedIndex, totalSteps, advance, back, goTo, labels } = context;
379
+ const isFirst = selectedIndex === 0;
380
+ const isLast = selectedIndex === totalSteps - 1;
381
+ const btnText = BUTTON_LABELS[buttonVariant] || BUTTON_LABELS.text;
382
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { "data-unfold-controls": true, "data-button-variant": buttonVariant, children: [
383
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
384
+ "button",
385
+ {
386
+ "data-unfold-prev": true,
387
+ "aria-disabled": isFirst ? "true" : "false",
388
+ "aria-label": !isFirst ? `Go back to step: ${labels[selectedIndex - 1]}` : void 0,
389
+ onClick: back,
390
+ children: btnText.prev
391
+ }
392
+ ),
393
+ indicators && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { "data-unfold-indicators": true, role: "tablist", children: Array.from({ length: totalSteps }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
394
+ "button",
395
+ {
396
+ role: "tab",
397
+ "aria-selected": i === selectedIndex,
398
+ "data-unfold-dot": true,
399
+ "data-active": i === selectedIndex ? "true" : void 0,
400
+ "aria-label": `Go to step: ${labels[i] || i + 1}`,
401
+ onClick: () => goTo(i)
402
+ },
403
+ i
404
+ )) }),
405
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
406
+ "button",
407
+ {
408
+ "data-unfold-next": true,
409
+ "aria-disabled": isLast ? "true" : "false",
410
+ "aria-label": !isLast ? `Advance to step: ${labels[selectedIndex + 1]}` : void 0,
411
+ onClick: advance,
412
+ children: btnText.next
413
+ }
414
+ )
415
+ ] });
416
+ }
417
+
418
+ // src/components/Depth.tsx
419
+ var import_jsx_runtime5 = require("react/jsx-runtime");
420
+ function getTextContent(node) {
421
+ if (node === null || node === void 0) {
422
+ return "";
423
+ }
424
+ if (typeof node === "string" || typeof node === "number") {
425
+ return String(node);
426
+ }
427
+ if (Array.isArray(node)) {
428
+ return node.map(getTextContent).join("");
429
+ }
430
+ if (import_react4.default.isValidElement(node)) {
431
+ return getTextContent(node.props.children);
432
+ }
433
+ return "";
434
+ }
435
+ function Depth({
436
+ selectedIndex,
437
+ defaultIndex,
438
+ onChange,
439
+ orientation = "horizontal",
440
+ ratio = 0.5,
441
+ show = "both",
442
+ indicators = false,
443
+ buttonVariant = "text",
444
+ animate = true,
445
+ highlight = true,
446
+ highlighter,
447
+ children
448
+ }) {
449
+ const isControlled = selectedIndex !== void 0 && onChange !== void 0;
450
+ const [internalIndex, setInternalIndex] = (0, import_react4.useState)(defaultIndex ?? 0);
451
+ const currentIndex = isControlled ? selectedIndex : internalIndex;
452
+ const [isMounted, setIsMounted] = (0, import_react4.useState)(false);
453
+ (0, import_react4.useEffect)(() => {
454
+ setIsMounted(true);
455
+ }, []);
456
+ const parsedChildren = (0, import_react4.useMemo)(() => {
457
+ const proseLevels = [];
458
+ const codeLevels = [];
459
+ import_react4.default.Children.forEach(children, (child) => {
460
+ if (import_react4.default.isValidElement(child)) {
461
+ const type = child.type?.unfoldType || child.type;
462
+ if (type === "level" || type === DepthLevel) {
463
+ proseLevels.push({
464
+ label: child.props.label || "",
465
+ text: getTextContent(child.props.children)
466
+ });
467
+ } else if (type === "code" || type === DepthCode) {
468
+ codeLevels.push({
469
+ lang: child.props.lang || "",
470
+ label: child.props.label || "",
471
+ text: getTextContent(child.props.children)
472
+ });
473
+ }
474
+ }
475
+ });
476
+ return { proseLevels, codeLevels };
477
+ }, [children]);
478
+ const proseDiffTable = (0, import_react4.useMemo)(() => {
479
+ const table = [];
480
+ if (parsedChildren.proseLevels.length > 0) {
481
+ table.push(sentenceDiff("", parsedChildren.proseLevels[0].text));
482
+ for (let i = 1; i < parsedChildren.proseLevels.length; i++) {
483
+ table.push(sentenceDiff(parsedChildren.proseLevels[i - 1].text, parsedChildren.proseLevels[i].text));
484
+ }
485
+ }
486
+ return table;
487
+ }, [parsedChildren.proseLevels]);
488
+ const codeDiffTable = (0, import_react4.useMemo)(() => {
489
+ const table = [];
490
+ if (parsedChildren.codeLevels.length > 0) {
491
+ table.push(codeDiff("", parsedChildren.codeLevels[0].text));
492
+ for (let i = 1; i < parsedChildren.codeLevels.length; i++) {
493
+ table.push(codeDiff(parsedChildren.codeLevels[i - 1].text, parsedChildren.codeLevels[i].text));
494
+ }
495
+ }
496
+ return table;
497
+ }, [parsedChildren.codeLevels]);
498
+ const [justEntered, setJustEntered] = (0, import_react4.useState)(false);
499
+ const prevIndexRef = (0, import_react4.useRef)(null);
500
+ (0, import_react4.useEffect)(() => {
501
+ if (prevIndexRef.current !== null && currentIndex !== prevIndexRef.current) {
502
+ setJustEntered(true);
503
+ }
504
+ prevIndexRef.current = currentIndex;
505
+ }, [currentIndex]);
506
+ (0, import_react4.useEffect)(() => {
507
+ if (justEntered) {
508
+ const animFrameId = requestAnimationFrame(() => {
509
+ setJustEntered(false);
510
+ });
511
+ return () => cancelAnimationFrame(animFrameId);
512
+ }
513
+ }, [justEntered]);
514
+ const totalSteps = Math.max(parsedChildren.proseLevels.length, parsedChildren.codeLevels.length, 1);
515
+ const goTo = (index) => {
516
+ if (index >= 0 && index < totalSteps) {
517
+ if (!isControlled) {
518
+ setInternalIndex(index);
519
+ }
520
+ onChange?.(index);
521
+ }
522
+ };
523
+ const handleBack = () => goTo(currentIndex - 1);
524
+ const handleNext = () => goTo(currentIndex + 1);
525
+ const maxLabels = Math.max(parsedChildren.proseLevels.length, parsedChildren.codeLevels.length);
526
+ const labels = Array.from({ length: maxLabels }).map((_, i) => {
527
+ return parsedChildren.proseLevels[i]?.label || parsedChildren.codeLevels[i]?.label || `Step ${i + 1}`;
528
+ });
529
+ const contextValue = {
530
+ selectedIndex: currentIndex,
531
+ totalSteps,
532
+ labels,
533
+ show,
534
+ orientation,
535
+ goTo,
536
+ advance: handleNext,
537
+ back: handleBack
538
+ };
539
+ if (!isMounted) {
540
+ const defaultLastIndex = totalSteps - 1;
541
+ let proseCount = 0;
542
+ let codeCount = 0;
543
+ const maxProse = parsedChildren.proseLevels.length;
544
+ const maxCode = parsedChildren.codeLevels.length;
545
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DepthContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
546
+ "div",
547
+ {
548
+ "data-unfold-root": true,
549
+ "data-orientation": orientation,
550
+ "data-show": show,
551
+ style: { "--unfold-ratio": ratio },
552
+ "data-level": defaultLastIndex,
553
+ "data-total-levels": totalSteps,
554
+ role: "region",
555
+ "aria-label": labels[defaultLastIndex],
556
+ children: import_react4.default.Children.map(children, (child) => {
557
+ if (import_react4.default.isValidElement(child)) {
558
+ const type = child.type?.unfoldType || child.type;
559
+ if (type === "level" || type === DepthLevel) {
560
+ const isDeepest = proseCount === Math.max(0, maxProse - 1);
561
+ proseCount++;
562
+ return import_react4.default.cloneElement(child, {
563
+ "data-unfold-active": isDeepest ? "true" : void 0
564
+ });
565
+ } else if (type === "code" || type === DepthCode) {
566
+ const isDeepest = codeCount === Math.max(0, maxCode - 1);
567
+ codeCount++;
568
+ return import_react4.default.cloneElement(child, {
569
+ "data-unfold-active": isDeepest ? "true" : void 0
570
+ });
571
+ }
572
+ }
573
+ return child;
574
+ })
575
+ }
576
+ ) });
577
+ }
578
+ const clampedProseIndex = Math.min(currentIndex, proseDiffTable.length - 1);
579
+ const clampedCodeIndex = Math.min(currentIndex, codeDiffTable.length - 1);
580
+ const currentProseDiff = clampedProseIndex >= 0 ? proseDiffTable[clampedProseIndex] : [];
581
+ const currentCodeDiff = clampedCodeIndex >= 0 ? codeDiffTable[clampedCodeIndex] : [];
582
+ const currentCodeLang = clampedCodeIndex >= 0 ? parsedChildren.codeLevels[clampedCodeIndex]?.lang : void 0;
583
+ const currentCodeText = clampedCodeIndex >= 0 ? parsedChildren.codeLevels[clampedCodeIndex]?.text : void 0;
584
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DepthContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
585
+ "div",
586
+ {
587
+ "data-unfold-root": true,
588
+ "data-orientation": orientation,
589
+ "data-show": show,
590
+ style: { "--unfold-ratio": ratio },
591
+ "data-level": currentIndex,
592
+ "data-total-levels": totalSteps,
593
+ role: "region",
594
+ "aria-label": labels[currentIndex],
595
+ children: [
596
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
597
+ DepthPane,
598
+ {
599
+ show,
600
+ proseDiff: currentProseDiff,
601
+ codeDiff: currentCodeDiff,
602
+ justEntered,
603
+ animate,
604
+ codeLang: currentCodeLang,
605
+ codeText: currentCodeText,
606
+ highlighter,
607
+ highlight
608
+ }
609
+ ),
610
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Controls, { buttonVariant, indicators })
611
+ ]
612
+ }
613
+ ) });
614
+ }
615
+ // Annotate the CommonJS export names for ESM import in node:
616
+ 0 && (module.exports = {
617
+ Depth,
618
+ DepthCode,
619
+ DepthLevel,
620
+ DepthPane,
621
+ codeDiff,
622
+ sentenceDiff,
623
+ tokenize,
624
+ tokenizeCodeLine,
625
+ tokenizeLines
626
+ });
@@ -0,0 +1,65 @@
1
+ import { SentenceDiff } from './diff/index.cjs';
2
+ export { sentenceDiff, tokenize, tokenizeCodeLine, tokenizeLines } from './diff/index.cjs';
3
+ import { C as CodeLineDiff } from './codeDiff-BVwZfdt9.cjs';
4
+ export { a as CodeToken, c as codeDiff } from './codeDiff-BVwZfdt9.cjs';
5
+ import * as React from 'react';
6
+ import React__default from 'react';
7
+ import { ShikiHighlighter } from './shiki/index.cjs';
8
+
9
+ interface DepthProps {
10
+ selectedIndex?: number;
11
+ defaultIndex?: number;
12
+ onChange?: (i: number) => void;
13
+ orientation?: "horizontal" | "vertical";
14
+ ratio?: number;
15
+ show?: "both" | "prose" | "code";
16
+ indicators?: boolean;
17
+ buttonVariant?: "text" | "arrow" | "chevron" | "minimal";
18
+ animate?: boolean;
19
+ highlight?: boolean;
20
+ highlighter?: ShikiHighlighter;
21
+ children: React__default.ReactNode;
22
+ }
23
+ declare function Depth({ selectedIndex, defaultIndex, onChange, orientation, ratio, show, indicators, buttonVariant, animate, highlight, highlighter, children, }: DepthProps): React__default.JSX.Element;
24
+
25
+ interface DepthLevelProps {
26
+ label: string;
27
+ children: React__default.ReactNode;
28
+ [key: string]: any;
29
+ }
30
+ /**
31
+ * DepthLevel acts as a slot component to hold a level's label and prose snapshot.
32
+ *
33
+ * - Inside <Depth> (after mounting/hydration), it is parsed and not rendered directly.
34
+ * - Outside <Depth> (or during SSR / before hydration), it falls back to rendering
35
+ * its children wrapped in a container with a data-depth-level attribute.
36
+ */
37
+ declare function DepthLevel({ label, children, ...props }: DepthLevelProps): React__default.JSX.Element;
38
+ declare namespace DepthLevel {
39
+ var unfoldType: string;
40
+ }
41
+
42
+ interface DepthCodeProps extends React__default.HTMLAttributes<HTMLPreElement> {
43
+ lang?: string;
44
+ label?: string;
45
+ children: string;
46
+ }
47
+ declare function DepthCode({ lang, label, children, ...rest }: DepthCodeProps): React__default.JSX.Element;
48
+ declare namespace DepthCode {
49
+ var unfoldType: string;
50
+ }
51
+
52
+ interface DepthPaneProps {
53
+ show: "both" | "prose" | "code";
54
+ proseDiff: SentenceDiff[];
55
+ codeDiff: CodeLineDiff[];
56
+ justEntered: boolean;
57
+ animate: boolean;
58
+ codeLang?: string;
59
+ codeText?: string;
60
+ highlighter?: ShikiHighlighter;
61
+ highlight?: boolean;
62
+ }
63
+ declare function DepthPane({ show, proseDiff, codeDiff, justEntered, animate, codeLang, codeText, highlighter, highlight, }: DepthPaneProps): React.JSX.Element;
64
+
65
+ export { CodeLineDiff, Depth, DepthCode, type DepthCodeProps, DepthLevel, type DepthLevelProps, DepthPane, type DepthProps, SentenceDiff };