@mirror-physics/fractal-ui 0.2.0-next.51 → 0.2.0-next.53
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 +90 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +91 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -306,22 +306,23 @@ var codeTheme = import_view.EditorView.theme({
|
|
|
306
306
|
".cm-lineNumbers .cm-gutterElement": { padding: "0 10px 0 4px" },
|
|
307
307
|
".cm-foldGutter": { width: "14px" },
|
|
308
308
|
".cm-foldGutter .cm-gutterElement": {
|
|
309
|
-
|
|
309
|
+
position: "relative",
|
|
310
|
+
display: "block",
|
|
310
311
|
width: "14px",
|
|
311
|
-
|
|
312
|
-
justifyContent: "flex-end",
|
|
313
|
-
padding: "0 1px 0 0"
|
|
312
|
+
padding: "0"
|
|
314
313
|
},
|
|
315
314
|
".cm-foldGutter .cm-gutterElement > span": {
|
|
315
|
+
position: "absolute",
|
|
316
|
+
top: "2px",
|
|
317
|
+
left: "0",
|
|
316
318
|
display: "inline-flex",
|
|
317
|
-
width: "
|
|
318
|
-
height: "
|
|
319
|
+
width: "14px",
|
|
320
|
+
height: "14px",
|
|
319
321
|
alignItems: "center",
|
|
320
322
|
justifyContent: "center",
|
|
321
323
|
padding: "0",
|
|
322
324
|
color: "var(--fg-tertiary)",
|
|
323
|
-
lineHeight: "
|
|
324
|
-
transform: "translateY(-1px)",
|
|
325
|
+
lineHeight: "14px",
|
|
325
326
|
transition: "color 120ms ease"
|
|
326
327
|
},
|
|
327
328
|
".cm-foldGutter .cm-gutterElement > span:hover": { color: "var(--fg-secondary)" },
|
|
@@ -358,16 +359,87 @@ var fractalHighlightStyle = import_language.HighlightStyle.define([
|
|
|
358
359
|
]);
|
|
359
360
|
var jsonSupport = (0, import_lang_json.json)();
|
|
360
361
|
var JSON_LANGUAGE_NAMES = /* @__PURE__ */ new Set(["json", "jsonl", "ndjson", "geojson"]);
|
|
362
|
+
var JSON_LINES_LANGUAGE_NAMES = /* @__PURE__ */ new Set(["jsonl", "ndjson"]);
|
|
363
|
+
var JSON_LINES_PRETTY_PRINT_THRESHOLD = 160;
|
|
364
|
+
function formatJsonLinesForDisplay(value) {
|
|
365
|
+
return value.split(/\r?\n/).map((line) => {
|
|
366
|
+
const firstContentIndex = line.search(/\S/);
|
|
367
|
+
if (firstContentIndex < 0 || line.length - firstContentIndex <= JSON_LINES_PRETTY_PRINT_THRESHOLD) return line;
|
|
368
|
+
const indentation = line.slice(0, firstContentIndex);
|
|
369
|
+
try {
|
|
370
|
+
const parsed = JSON.parse(line.slice(firstContentIndex));
|
|
371
|
+
if (parsed === null || typeof parsed !== "object") return line;
|
|
372
|
+
return JSON.stringify(parsed, null, 2).split("\n").map((formattedLine) => `${indentation}${formattedLine}`).join("\n");
|
|
373
|
+
} catch {
|
|
374
|
+
return line;
|
|
375
|
+
}
|
|
376
|
+
}).join("\n");
|
|
377
|
+
}
|
|
378
|
+
function findJsonContainerEnd(document2, start) {
|
|
379
|
+
const openingCharacter = document2[start];
|
|
380
|
+
if (openingCharacter !== "{" && openingCharacter !== "[") return null;
|
|
381
|
+
const closingCharacters = [];
|
|
382
|
+
let isInsideString = false;
|
|
383
|
+
let isEscaped = false;
|
|
384
|
+
for (let index = start; index < document2.length; index += 1) {
|
|
385
|
+
const character = document2[index];
|
|
386
|
+
if (isInsideString) {
|
|
387
|
+
if (isEscaped) {
|
|
388
|
+
isEscaped = false;
|
|
389
|
+
} else if (character === "\\") {
|
|
390
|
+
isEscaped = true;
|
|
391
|
+
} else if (character === '"') {
|
|
392
|
+
isInsideString = false;
|
|
393
|
+
}
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
if (character === '"') {
|
|
397
|
+
isInsideString = true;
|
|
398
|
+
} else if (character === "{") {
|
|
399
|
+
closingCharacters.push("}");
|
|
400
|
+
} else if (character === "[") {
|
|
401
|
+
closingCharacters.push("]");
|
|
402
|
+
} else if (character === "}" || character === "]") {
|
|
403
|
+
if (closingCharacters.pop() !== character) return null;
|
|
404
|
+
if (closingCharacters.length === 0) return index;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
var jsonLinesFoldSupport = import_language.foldService.of((state, lineStart, lineEnd) => {
|
|
410
|
+
const line = state.doc.sliceString(lineStart, lineEnd);
|
|
411
|
+
const firstContentIndex = line.search(/\S/);
|
|
412
|
+
if (firstContentIndex < 0) return null;
|
|
413
|
+
const containerStart = lineStart + firstContentIndex;
|
|
414
|
+
const openingCharacter = line[firstContentIndex];
|
|
415
|
+
if (openingCharacter !== "{" && openingCharacter !== "[") return null;
|
|
416
|
+
const document2 = state.doc.toString();
|
|
417
|
+
const containerEnd = findJsonContainerEnd(document2, containerStart);
|
|
418
|
+
if (containerEnd === null || containerEnd - containerStart < 2) return null;
|
|
419
|
+
try {
|
|
420
|
+
const parsed = JSON.parse(document2.slice(containerStart, containerEnd + 1));
|
|
421
|
+
if (parsed === null || typeof parsed !== "object") return null;
|
|
422
|
+
} catch {
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
return {
|
|
426
|
+
from: containerStart + 1,
|
|
427
|
+
to: containerEnd
|
|
428
|
+
};
|
|
429
|
+
});
|
|
361
430
|
function resolveLanguage(language, fileName) {
|
|
362
431
|
const normalized = language?.trim().toLowerCase();
|
|
363
432
|
const extension = fileName?.split(/[?#]/, 1)[0].split(".").pop()?.toLowerCase();
|
|
364
433
|
if (normalized && JSON_LANGUAGE_NAMES.has(normalized) || extension && JSON_LANGUAGE_NAMES.has(extension)) {
|
|
365
|
-
|
|
434
|
+
const isJsonLines = Boolean(
|
|
435
|
+
normalized && JSON_LINES_LANGUAGE_NAMES.has(normalized) || extension && JSON_LINES_LANGUAGE_NAMES.has(extension)
|
|
436
|
+
);
|
|
437
|
+
return { label: isJsonLines ? "JSONL" : "JSON", support: jsonSupport, isJsonLines };
|
|
366
438
|
}
|
|
367
439
|
if (normalized && !["text", "txt", "plaintext", "plain"].includes(normalized)) {
|
|
368
|
-
return { label: language?.trim(), support: null };
|
|
440
|
+
return { label: language?.trim(), support: null, isJsonLines: false };
|
|
369
441
|
}
|
|
370
|
-
return { support: null };
|
|
442
|
+
return { support: null, isJsonLines: false };
|
|
371
443
|
}
|
|
372
444
|
function CodeBlock({
|
|
373
445
|
value,
|
|
@@ -389,6 +461,10 @@ function CodeBlock({
|
|
|
389
461
|
...props
|
|
390
462
|
}) {
|
|
391
463
|
const resolvedLanguage = (0, import_react.useMemo)(() => resolveLanguage(language, fileName), [fileName, language]);
|
|
464
|
+
const displayValue = (0, import_react.useMemo)(
|
|
465
|
+
() => !editable && resolvedLanguage.isJsonLines ? formatJsonLinesForDisplay(value) : value,
|
|
466
|
+
[editable, resolvedLanguage.isJsonLines, value]
|
|
467
|
+
);
|
|
392
468
|
const [copyStatus, setCopyStatus] = (0, import_react.useState)("idle");
|
|
393
469
|
const copyResetTimer = (0, import_react.useRef)(null);
|
|
394
470
|
(0, import_react.useEffect)(() => () => {
|
|
@@ -398,9 +474,10 @@ function CodeBlock({
|
|
|
398
474
|
codeTheme,
|
|
399
475
|
(0, import_language.syntaxHighlighting)(fractalHighlightStyle),
|
|
400
476
|
...resolvedLanguage.support ? [resolvedLanguage.support] : [],
|
|
477
|
+
...resolvedLanguage.isJsonLines ? [jsonLinesFoldSupport] : [],
|
|
401
478
|
...lineNumbers ? [(0, import_language.foldGutter)(), (0, import_view.lineNumbers)()] : [],
|
|
402
479
|
...wrap ? [import_view.EditorView.lineWrapping] : []
|
|
403
|
-
], [lineNumbers, resolvedLanguage.support, wrap]);
|
|
480
|
+
], [lineNumbers, resolvedLanguage.isJsonLines, resolvedLanguage.support, wrap]);
|
|
404
481
|
const languageLabel = resolvedLanguage.label;
|
|
405
482
|
const toolbarLabel = label ?? fileName ?? languageLabel;
|
|
406
483
|
const surfaceLabel = ariaLabel ?? (fileName ? `${fileName} ${editable ? "editor" : "viewer"}` : `Code ${editable ? "editor" : "viewer"}`);
|
|
@@ -450,7 +527,7 @@ function CodeBlock({
|
|
|
450
527
|
import_react_codemirror.default,
|
|
451
528
|
{
|
|
452
529
|
"aria-label": surfaceLabel,
|
|
453
|
-
value,
|
|
530
|
+
value: displayValue,
|
|
454
531
|
editable,
|
|
455
532
|
readOnly: !editable,
|
|
456
533
|
onChange,
|