@mirror-physics/fractal-ui 0.2.0-next.52 → 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.js CHANGED
@@ -197,22 +197,23 @@ var codeTheme = EditorView.theme({
197
197
  ".cm-lineNumbers .cm-gutterElement": { padding: "0 10px 0 4px" },
198
198
  ".cm-foldGutter": { width: "14px" },
199
199
  ".cm-foldGutter .cm-gutterElement": {
200
- display: "flex",
200
+ position: "relative",
201
+ display: "block",
201
202
  width: "14px",
202
- alignItems: "center",
203
- justifyContent: "flex-end",
204
- padding: "0 1px 0 0"
203
+ padding: "0"
205
204
  },
206
205
  ".cm-foldGutter .cm-gutterElement > span": {
206
+ position: "absolute",
207
+ top: "2px",
208
+ left: "0",
207
209
  display: "inline-flex",
208
- width: "12px",
209
- height: "100%",
210
+ width: "14px",
211
+ height: "14px",
210
212
  alignItems: "center",
211
213
  justifyContent: "center",
212
214
  padding: "0",
213
215
  color: "var(--fg-tertiary)",
214
- lineHeight: "1",
215
- transform: "translateY(-1px)",
216
+ lineHeight: "14px",
216
217
  transition: "color 120ms ease"
217
218
  },
218
219
  ".cm-foldGutter .cm-gutterElement > span:hover": { color: "var(--fg-secondary)" },
@@ -250,24 +251,71 @@ var fractalHighlightStyle = HighlightStyle.define([
250
251
  var jsonSupport = json();
251
252
  var JSON_LANGUAGE_NAMES = /* @__PURE__ */ new Set(["json", "jsonl", "ndjson", "geojson"]);
252
253
  var JSON_LINES_LANGUAGE_NAMES = /* @__PURE__ */ new Set(["jsonl", "ndjson"]);
254
+ var JSON_LINES_PRETTY_PRINT_THRESHOLD = 160;
255
+ function formatJsonLinesForDisplay(value) {
256
+ return value.split(/\r?\n/).map((line) => {
257
+ const firstContentIndex = line.search(/\S/);
258
+ if (firstContentIndex < 0 || line.length - firstContentIndex <= JSON_LINES_PRETTY_PRINT_THRESHOLD) return line;
259
+ const indentation = line.slice(0, firstContentIndex);
260
+ try {
261
+ const parsed = JSON.parse(line.slice(firstContentIndex));
262
+ if (parsed === null || typeof parsed !== "object") return line;
263
+ return JSON.stringify(parsed, null, 2).split("\n").map((formattedLine) => `${indentation}${formattedLine}`).join("\n");
264
+ } catch {
265
+ return line;
266
+ }
267
+ }).join("\n");
268
+ }
269
+ function findJsonContainerEnd(document2, start) {
270
+ const openingCharacter = document2[start];
271
+ if (openingCharacter !== "{" && openingCharacter !== "[") return null;
272
+ const closingCharacters = [];
273
+ let isInsideString = false;
274
+ let isEscaped = false;
275
+ for (let index = start; index < document2.length; index += 1) {
276
+ const character = document2[index];
277
+ if (isInsideString) {
278
+ if (isEscaped) {
279
+ isEscaped = false;
280
+ } else if (character === "\\") {
281
+ isEscaped = true;
282
+ } else if (character === '"') {
283
+ isInsideString = false;
284
+ }
285
+ continue;
286
+ }
287
+ if (character === '"') {
288
+ isInsideString = true;
289
+ } else if (character === "{") {
290
+ closingCharacters.push("}");
291
+ } else if (character === "[") {
292
+ closingCharacters.push("]");
293
+ } else if (character === "}" || character === "]") {
294
+ if (closingCharacters.pop() !== character) return null;
295
+ if (closingCharacters.length === 0) return index;
296
+ }
297
+ }
298
+ return null;
299
+ }
253
300
  var jsonLinesFoldSupport = foldService.of((state, lineStart, lineEnd) => {
254
301
  const line = state.doc.sliceString(lineStart, lineEnd);
255
302
  const firstContentIndex = line.search(/\S/);
256
303
  if (firstContentIndex < 0) return null;
257
- const lastContentIndex = line.search(/\s*$/) - 1;
304
+ const containerStart = lineStart + firstContentIndex;
258
305
  const openingCharacter = line[firstContentIndex];
259
- const closingCharacter = line[lastContentIndex];
260
- const isContainer = openingCharacter === "{" && closingCharacter === "}" || openingCharacter === "[" && closingCharacter === "]";
261
- if (!isContainer || lastContentIndex - firstContentIndex < 2) return null;
306
+ if (openingCharacter !== "{" && openingCharacter !== "[") return null;
307
+ const document2 = state.doc.toString();
308
+ const containerEnd = findJsonContainerEnd(document2, containerStart);
309
+ if (containerEnd === null || containerEnd - containerStart < 2) return null;
262
310
  try {
263
- const parsed = JSON.parse(line.slice(firstContentIndex, lastContentIndex + 1));
311
+ const parsed = JSON.parse(document2.slice(containerStart, containerEnd + 1));
264
312
  if (parsed === null || typeof parsed !== "object") return null;
265
313
  } catch {
266
314
  return null;
267
315
  }
268
316
  return {
269
- from: lineStart + firstContentIndex + 1,
270
- to: lineStart + lastContentIndex
317
+ from: containerStart + 1,
318
+ to: containerEnd
271
319
  };
272
320
  });
273
321
  function resolveLanguage(language, fileName) {
@@ -304,6 +352,10 @@ function CodeBlock({
304
352
  ...props
305
353
  }) {
306
354
  const resolvedLanguage = useMemo(() => resolveLanguage(language, fileName), [fileName, language]);
355
+ const displayValue = useMemo(
356
+ () => !editable && resolvedLanguage.isJsonLines ? formatJsonLinesForDisplay(value) : value,
357
+ [editable, resolvedLanguage.isJsonLines, value]
358
+ );
307
359
  const [copyStatus, setCopyStatus] = useState2("idle");
308
360
  const copyResetTimer = useRef(null);
309
361
  useEffect(() => () => {
@@ -366,7 +418,7 @@ function CodeBlock({
366
418
  CodeMirror,
367
419
  {
368
420
  "aria-label": surfaceLabel,
369
- value,
421
+ value: displayValue,
370
422
  editable,
371
423
  readOnly: !editable,
372
424
  onChange,