@pipelex/mthds-form 0.9.0 → 0.10.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/README.md +3 -0
- package/dist/{chunk-S4CB423P.js → chunk-4JQAJT7C.js} +3 -3
- package/dist/{chunk-S4CB423P.js.map → chunk-4JQAJT7C.js.map} +1 -1
- package/dist/{chunk-YABRYTQ4.js → chunk-4KGQ65TQ.js} +3 -3
- package/dist/{chunk-YABRYTQ4.js.map → chunk-4KGQ65TQ.js.map} +1 -1
- package/dist/chunk-CAKQ5VFT.js +35 -0
- package/dist/chunk-CAKQ5VFT.js.map +1 -0
- package/dist/{chunk-25I6JDIK.js → chunk-FABY3DEY.js} +2 -2
- package/dist/chunk-FABY3DEY.js.map +1 -0
- package/dist/{chunk-AZZAAGNX.js → chunk-TID7ZN63.js} +7 -3
- package/dist/chunk-TID7ZN63.js.map +1 -0
- package/dist/{chunk-KG4IYFWI.js → chunk-W56WIIVC.js} +174 -51
- package/dist/chunk-W56WIIVC.js.map +1 -0
- package/dist/chunk-XCO6GTEC.js +38 -0
- package/dist/chunk-XCO6GTEC.js.map +1 -0
- package/dist/{chunk-KIEOLP2L.js → chunk-ZB4RYUKV.js} +4 -4
- package/dist/chunk-ZB4RYUKV.js.map +1 -0
- package/dist/core/derive.d.ts +1 -0
- package/dist/core/derive.js +2 -2
- package/dist/core/descriptor.d.ts +13 -2
- package/dist/core/descriptor.js +1 -1
- package/dist/core/file-formats.d.ts +34 -7
- package/dist/core/file-formats.js +1 -1
- package/dist/core/gating-fields.d.ts +1 -0
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.js +7 -6
- package/dist/core/narrow-file-formats.d.ts +50 -0
- package/dist/core/narrow-file-formats.js +4 -0
- package/dist/core/narrow-file-formats.js.map +1 -0
- package/dist/core/native-content.d.ts +20 -11
- package/dist/core/native-content.js +1 -1
- package/dist/core/readiness.d.ts +1 -0
- package/dist/core/stuff-files.d.ts +1 -0
- package/dist/core/stuff-files.js +2 -2
- package/dist/core/values.d.ts +1 -0
- package/dist/core/values.js +3 -3
- package/dist/generative/index.d.ts +105 -12
- package/dist/generative/index.js +79 -157
- package/dist/generative/index.js.map +1 -1
- package/dist/{ui-designer.mthds → layout-design.mthds} +177 -29
- package/dist/react/index.d.ts +66 -10
- package/dist/react/index.js +5 -5
- package/dist/styles.css +1 -1
- package/package.json +3 -3
- package/dist/chunk-25I6JDIK.js.map +0 -1
- package/dist/chunk-2JWRG53S.js +0 -33
- package/dist/chunk-2JWRG53S.js.map +0 -1
- package/dist/chunk-AZZAAGNX.js.map +0 -1
- package/dist/chunk-KG4IYFWI.js.map +0 -1
- package/dist/chunk-KIEOLP2L.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { collectStuffFiles } from './chunk-
|
|
2
|
-
import { viewableUrl, isNativeDateNode, isNativeHtmlNode, readHtmlContent, isNativeCompositeNode, readCompositeContent,
|
|
3
|
-
import { conceptCategory } from './chunk-
|
|
4
|
-
import { isAcceptedFile,
|
|
1
|
+
import { collectStuffFiles } from './chunk-4JQAJT7C.js';
|
|
2
|
+
import { viewableUrl, isNativeDateNode, isNativeHtmlNode, readHtmlContent, isNativeCompositeNode, readCompositeContent, isNativeValueNode, readDateContent, formatDateContent, readImageContent, readDataUrl, readDocumentContent } from './chunk-TID7ZN63.js';
|
|
3
|
+
import { conceptCategory } from './chunk-FABY3DEY.js';
|
|
4
|
+
import { acceptLabel, acceptMap, isAcceptedFile, formatOfFilename, DOCUMENT_FORMATS, IMAGE_FORMATS } from './chunk-XCO6GTEC.js';
|
|
5
5
|
import { isFilled } from './chunk-PM55AHRO.js';
|
|
6
6
|
import { toStoredDateValue, toDateInputValue } from './chunk-GKV77RAS.js';
|
|
7
7
|
import { ownProp } from './chunk-V3OV2XQT.js';
|
|
@@ -66,6 +66,39 @@ function humanizeFieldName(name) {
|
|
|
66
66
|
if (words === "") return name;
|
|
67
67
|
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
68
68
|
}
|
|
69
|
+
function humanizeEnumValue(code) {
|
|
70
|
+
if (!ENUM_CODE.test(code)) return code;
|
|
71
|
+
const allCaps = code === code.toUpperCase() && code !== code.toLowerCase();
|
|
72
|
+
if (!allCaps) return humanizeFieldName(code);
|
|
73
|
+
return CODE_SEPARATOR.test(code) ? humanizeFieldName(code.toLowerCase()) : code;
|
|
74
|
+
}
|
|
75
|
+
var ENUM_CODE = /^\p{L}[\p{L}\p{N}_-]*$/u;
|
|
76
|
+
var CODE_SEPARATOR = /[_-]/;
|
|
77
|
+
function enumLabeler(options, presentation) {
|
|
78
|
+
if (presentation !== "app") return asWritten;
|
|
79
|
+
let labeler = APP_LABELERS.get(options);
|
|
80
|
+
if (labeler === void 0) {
|
|
81
|
+
labeler = wordsOrCodes(options);
|
|
82
|
+
APP_LABELERS.set(options, labeler);
|
|
83
|
+
}
|
|
84
|
+
return labeler;
|
|
85
|
+
}
|
|
86
|
+
function asWritten(value) {
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
function wordsOrCodes(options) {
|
|
90
|
+
const labels = /* @__PURE__ */ new Map();
|
|
91
|
+
const owners = /* @__PURE__ */ new Map();
|
|
92
|
+
for (const option of options) {
|
|
93
|
+
const label = humanizeEnumValue(option);
|
|
94
|
+
const owner = owners.get(label);
|
|
95
|
+
if (owner !== void 0 && owner !== option) return asWritten;
|
|
96
|
+
owners.set(label, option);
|
|
97
|
+
labels.set(option, label);
|
|
98
|
+
}
|
|
99
|
+
return (value) => labels.get(value) ?? value;
|
|
100
|
+
}
|
|
101
|
+
var APP_LABELERS = /* @__PURE__ */ new WeakMap();
|
|
69
102
|
function fieldLabel(title, name, presentation) {
|
|
70
103
|
if (title !== void 0) return title;
|
|
71
104
|
return presentation === "app" ? humanizeFieldName(name) : name;
|
|
@@ -170,8 +203,9 @@ var DEFAULT_FIELD_STRINGS = {
|
|
|
170
203
|
dropToUpload: "Drop to upload",
|
|
171
204
|
dropOrBrowse: "Drop a file or click to browse",
|
|
172
205
|
pasteUrlInstead: "paste a URL instead",
|
|
173
|
-
urlPlaceholder: "https://\u2026
|
|
174
|
-
|
|
206
|
+
urlPlaceholder: "https://\u2026",
|
|
207
|
+
fileUrlAria: (label) => label ? `Link to the file for ${label}` : "Link to the file",
|
|
208
|
+
uploadedFile: "Attached file",
|
|
175
209
|
encodedFileSummary: (format, bytes) => `${format} \xB7 ${formatBytes(bytes)}`,
|
|
176
210
|
preview: "Preview",
|
|
177
211
|
removeFileAria: "Remove file",
|
|
@@ -192,7 +226,7 @@ var DEFAULT_FIELD_STRINGS = {
|
|
|
192
226
|
resultViewGroup: "Result view",
|
|
193
227
|
yes: "Yes",
|
|
194
228
|
no: "No",
|
|
195
|
-
unsupportedFileType: (
|
|
229
|
+
unsupportedFileType: (formats) => `That file type is not supported. Accepted formats: ${formats}.`,
|
|
196
230
|
hideOptionalFields: "Hide optional fields",
|
|
197
231
|
hideOptionalInputs: "Hide optional inputs",
|
|
198
232
|
optionalFieldsCount: (count) => count === 1 ? "1 optional field" : `${count} optional fields`,
|
|
@@ -296,6 +330,11 @@ function encodedFileSummary(url, strings) {
|
|
|
296
330
|
var IMAGE_EXT_RE = /\.(jpg|jpeg|png|gif|webp|bmp|svg|avif)(\?|$)/i;
|
|
297
331
|
var PDF_EXT_RE = /\.pdf(\?|$)/i;
|
|
298
332
|
var DATA_URL_MIME_RE = /^data:([^;,]+)/i;
|
|
333
|
+
var WEB_URL_RE = /^\s*https?:\/\//i;
|
|
334
|
+
var URL_SCHEME_RE = /^\s*[a-z][a-z0-9+.-]*:/i;
|
|
335
|
+
function isReadableLink(url) {
|
|
336
|
+
return WEB_URL_RE.test(url) || !URL_SCHEME_RE.test(url);
|
|
337
|
+
}
|
|
299
338
|
function dataUrlMime(url) {
|
|
300
339
|
return DATA_URL_MIME_RE.exec(url)?.[1]?.toLowerCase();
|
|
301
340
|
}
|
|
@@ -318,8 +357,10 @@ function FileField({
|
|
|
318
357
|
category
|
|
319
358
|
}) {
|
|
320
359
|
const s = useFieldStrings();
|
|
360
|
+
const presentation = useFieldPresentation();
|
|
321
361
|
const domId = useFieldDomId(id);
|
|
322
362
|
const [showUrl, setShowUrl] = useState(false);
|
|
363
|
+
const [typedUrl, setTypedUrl] = useState(null);
|
|
323
364
|
const [previewOpen, setPreviewOpen] = useState(false);
|
|
324
365
|
const [localPreview, setLocalPreview] = useState(null);
|
|
325
366
|
const [resolved, setResolved] = useState(null);
|
|
@@ -331,9 +372,12 @@ function FileField({
|
|
|
331
372
|
}, []);
|
|
332
373
|
useEffect(() => () => setLocal(null), [setLocal]);
|
|
333
374
|
const [rejected, setRejected] = useState(null);
|
|
375
|
+
const formats = field.formats;
|
|
376
|
+
const hint = acceptLabel(formats);
|
|
377
|
+
const accept = useMemo(() => acceptMap(formats), [formats]);
|
|
334
378
|
const handleFile = useCallback(
|
|
335
379
|
(file) => {
|
|
336
|
-
if (!isAcceptedFile(
|
|
380
|
+
if (!isAcceptedFile(formats, file)) {
|
|
337
381
|
setRejected(file.name);
|
|
338
382
|
return;
|
|
339
383
|
}
|
|
@@ -341,7 +385,7 @@ function FileField({
|
|
|
341
385
|
setLocal({ objectUrl: URL.createObjectURL(file), type: file.type });
|
|
342
386
|
onDropFile(file);
|
|
343
387
|
},
|
|
344
|
-
[
|
|
388
|
+
[formats, setLocal, onDropFile]
|
|
345
389
|
);
|
|
346
390
|
const busy = disabled || uploading;
|
|
347
391
|
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
|
@@ -353,7 +397,7 @@ function FileField({
|
|
|
353
397
|
// entirely, and a browser reporting an empty `File.type` slips through
|
|
354
398
|
// react-dropzone's own matcher. `handleFile` is where the answer is
|
|
355
399
|
// decided; this is the affordance in front of it.
|
|
356
|
-
accept
|
|
400
|
+
accept,
|
|
357
401
|
// The tab stop belongs on the INPUT, not on this div - see the root element
|
|
358
402
|
// below. Without this, react-dropzone puts `tabIndex: 0` and its own key
|
|
359
403
|
// handlers on a `role="presentation"` div, and the element a keyboard or
|
|
@@ -403,17 +447,23 @@ function FileField({
|
|
|
403
447
|
if (!previewOpen || !storageUri || localIsCurrent || !resolveUrl) return;
|
|
404
448
|
let cancelled = false;
|
|
405
449
|
void resolveUrl(storageUri).then((src) => {
|
|
406
|
-
if (!cancelled) setResolved(
|
|
450
|
+
if (!cancelled) setResolved({ uri: storageUri, src: src || null });
|
|
407
451
|
}).catch(() => {
|
|
408
|
-
if (!cancelled) setResolved(null);
|
|
452
|
+
if (!cancelled) setResolved({ uri: storageUri, src: null });
|
|
409
453
|
});
|
|
410
454
|
return () => {
|
|
411
455
|
cancelled = true;
|
|
412
456
|
};
|
|
413
457
|
}, [previewOpen, storageUri, localIsCurrent, resolveUrl]);
|
|
414
|
-
const resolvedSrc = resolved && resolved.uri === storageUri ? viewableUrl(resolved.src) : void 0;
|
|
458
|
+
const resolvedSrc = resolved && resolved.uri === storageUri ? viewableUrl(resolved.src ?? void 0) : void 0;
|
|
415
459
|
const previewSrc = (localIsCurrent ? localPreview?.objectUrl : void 0) ?? directSrc ?? resolvedSrc;
|
|
416
|
-
const previewPending = !previewSrc && !!storageUri && resolved?.uri !== storageUri;
|
|
460
|
+
const previewPending = !previewSrc && !!storageUri && !!resolveUrl && resolved?.uri !== storageUri;
|
|
461
|
+
const togglePreview = () => {
|
|
462
|
+
if (!previewOpen) setResolved((r) => r?.src === null ? null : r);
|
|
463
|
+
setPreviewOpen((v) => !v);
|
|
464
|
+
};
|
|
465
|
+
const urlValue = value?.url ?? "";
|
|
466
|
+
const urlText = presentation === "studio" || isReadableLink(urlValue) || urlValue === typedUrl ? urlValue : "";
|
|
417
467
|
return /* @__PURE__ */ jsxs(
|
|
418
468
|
FieldShell,
|
|
419
469
|
{
|
|
@@ -431,11 +481,13 @@ function FileField({
|
|
|
431
481
|
FileChip,
|
|
432
482
|
{
|
|
433
483
|
value,
|
|
484
|
+
formats,
|
|
485
|
+
presentation,
|
|
434
486
|
disabled,
|
|
435
487
|
onClear: clear,
|
|
436
488
|
canPreview,
|
|
437
489
|
previewOpen,
|
|
438
|
-
onTogglePreview:
|
|
490
|
+
onTogglePreview: togglePreview
|
|
439
491
|
}
|
|
440
492
|
),
|
|
441
493
|
previewOpen && (previewSrc && isImage ? /* @__PURE__ */ jsx(ImagePreview, { src: previewSrc, filename: value?.filename }) : previewSrc && isPdf ? /* @__PURE__ */ jsx(PdfPreview, { src: previewSrc }) : previewPending ? /* @__PURE__ */ jsx("div", { className: "flex h-24 items-center justify-center rounded-md border border-border bg-muted", children: /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) }) : (
|
|
@@ -480,7 +532,7 @@ function FileField({
|
|
|
480
532
|
/* @__PURE__ */ jsx(Upload, { className: "h-5 w-5 text-muted-foreground", strokeWidth: 1.75 }),
|
|
481
533
|
/* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
482
534
|
/* @__PURE__ */ jsx("p", { className: "text-[13px] text-foreground", children: isDragActive ? s.dropToUpload : s.dropOrBrowse }),
|
|
483
|
-
|
|
535
|
+
hint && /* @__PURE__ */ jsx("p", { className: "font-mono text-[10.5px] text-muted-foreground", children: hint })
|
|
484
536
|
] })
|
|
485
537
|
] })
|
|
486
538
|
]
|
|
@@ -489,9 +541,8 @@ function FileField({
|
|
|
489
541
|
),
|
|
490
542
|
rejected && !busy && /* @__PURE__ */ jsxs("p", { role: "alert", className: "text-[12px] text-destructive", children: [
|
|
491
543
|
/* @__PURE__ */ jsx("span", { className: "font-mono", children: rejected }),
|
|
492
|
-
" \u2014",
|
|
493
|
-
|
|
494
|
-
s.unsupportedFileType(field.accept ?? "")
|
|
544
|
+
" \u2014 ",
|
|
545
|
+
s.unsupportedFileType(hint)
|
|
495
546
|
] }),
|
|
496
547
|
!showUrl ? /* @__PURE__ */ jsxs(
|
|
497
548
|
"button",
|
|
@@ -510,11 +561,13 @@ function FileField({
|
|
|
510
561
|
{
|
|
511
562
|
type: "text",
|
|
512
563
|
autoFocus: true,
|
|
513
|
-
value:
|
|
564
|
+
value: urlText,
|
|
514
565
|
disabled: busy,
|
|
566
|
+
"aria-label": s.fileUrlAria(fieldLabel(field.title, field.name, presentation)),
|
|
515
567
|
placeholder: s.urlPlaceholder,
|
|
516
568
|
onChange: (e) => {
|
|
517
569
|
setLocal(null);
|
|
570
|
+
setTypedUrl(e.target.value);
|
|
518
571
|
onChange(e.target.value ? { url: e.target.value } : void 0);
|
|
519
572
|
},
|
|
520
573
|
className: cn(fieldControlClass, "h-9 px-3 font-mono text-[12px]")
|
|
@@ -556,8 +609,17 @@ function PdfPreview({ src }) {
|
|
|
556
609
|
}
|
|
557
610
|
);
|
|
558
611
|
}
|
|
612
|
+
function fileChipSubtitle(url, filename, formats, presentation, strings) {
|
|
613
|
+
if (url === void 0) return void 0;
|
|
614
|
+
const summary = encodedFileSummary(url, strings);
|
|
615
|
+
if (summary !== void 0) return summary;
|
|
616
|
+
if (presentation === "studio" || isReadableLink(url)) return url;
|
|
617
|
+
return filename ? formatOfFilename(formats, filename)?.label : void 0;
|
|
618
|
+
}
|
|
559
619
|
function FileChip({
|
|
560
620
|
value,
|
|
621
|
+
formats,
|
|
622
|
+
presentation,
|
|
561
623
|
disabled,
|
|
562
624
|
onClear,
|
|
563
625
|
canPreview,
|
|
@@ -566,15 +628,16 @@ function FileChip({
|
|
|
566
628
|
}) {
|
|
567
629
|
const s = useFieldStrings();
|
|
568
630
|
const url = value?.url;
|
|
631
|
+
const filename = value?.filename;
|
|
569
632
|
const subtitle = useMemo(
|
|
570
|
-
() => url
|
|
571
|
-
[url, s]
|
|
633
|
+
() => fileChipSubtitle(url, filename, formats, presentation, s),
|
|
634
|
+
[url, filename, formats, presentation, s]
|
|
572
635
|
);
|
|
573
636
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 rounded-md border border-border bg-input px-3 py-2.5", children: [
|
|
574
637
|
/* @__PURE__ */ jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-muted", children: /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4 text-muted-foreground" }) }),
|
|
575
638
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
576
639
|
/* @__PURE__ */ jsx("p", { className: "truncate text-[13px] font-medium text-foreground", children: value?.filename ?? s.uploadedFile }),
|
|
577
|
-
/* @__PURE__ */ jsx("p", { className: "truncate font-mono text-[10.5px] text-muted-foreground", children: subtitle })
|
|
640
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "truncate font-mono text-[10.5px] text-muted-foreground", children: subtitle })
|
|
578
641
|
] }),
|
|
579
642
|
canPreview && /* @__PURE__ */ jsxs(
|
|
580
643
|
"button",
|
|
@@ -773,7 +836,9 @@ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
|
|
|
773
836
|
var CLEAR_VALUE = "__none__";
|
|
774
837
|
function EnumField({ field, value, onChange, id, error, disabled }) {
|
|
775
838
|
const s = useFieldStrings();
|
|
776
|
-
const
|
|
839
|
+
const presentation = useFieldPresentation();
|
|
840
|
+
const labelOf = enumLabeler(field.options, presentation);
|
|
841
|
+
const isSegmented = field.options.length <= 4 && field.options.every((o) => labelOf(o).length <= 16);
|
|
777
842
|
const domId = useFieldDomId(id);
|
|
778
843
|
return /* @__PURE__ */ jsx(
|
|
779
844
|
FieldShell,
|
|
@@ -797,7 +862,7 @@ function EnumField({ field, value, onChange, id, error, disabled }) {
|
|
|
797
862
|
value: value ?? "",
|
|
798
863
|
onValueChange: (next) => onChange(next === "" ? void 0 : next),
|
|
799
864
|
disabled,
|
|
800
|
-
"aria-label": field.title
|
|
865
|
+
"aria-label": fieldLabel(field.title, field.name, presentation),
|
|
801
866
|
className: "flex flex-wrap justify-start gap-1.5",
|
|
802
867
|
children: field.options.map((option) => /* @__PURE__ */ jsxs(
|
|
803
868
|
ToggleGroupItem,
|
|
@@ -807,7 +872,7 @@ function EnumField({ field, value, onChange, id, error, disabled }) {
|
|
|
807
872
|
className: "h-9 min-w-0 gap-1.5 border-border bg-input px-3 text-[13px] text-muted-foreground hover:bg-muted hover:text-foreground data-[state=on]:border-primary/40 data-[state=on]:bg-primary/10 data-[state=on]:font-medium data-[state=on]:text-foreground",
|
|
808
873
|
children: [
|
|
809
874
|
value === option && /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-primary", strokeWidth: 2.5, "aria-hidden": "true" }),
|
|
810
|
-
option
|
|
875
|
+
labelOf(option)
|
|
811
876
|
]
|
|
812
877
|
},
|
|
813
878
|
option
|
|
@@ -824,7 +889,7 @@ function EnumField({ field, value, onChange, id, error, disabled }) {
|
|
|
824
889
|
/* @__PURE__ */ jsx(SelectTrigger, { id: domId, "aria-invalid": !!error, className: "h-11", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: s.selectPlaceholder }) }),
|
|
825
890
|
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
826
891
|
/* @__PURE__ */ jsx(SelectItem, { value: CLEAR_VALUE, children: s.selectPlaceholder }),
|
|
827
|
-
field.options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option, children: option }, option))
|
|
892
|
+
field.options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option, children: labelOf(option) }, option))
|
|
828
893
|
] })
|
|
829
894
|
]
|
|
830
895
|
}
|
|
@@ -1345,11 +1410,12 @@ function ResultEnvProvider({
|
|
|
1345
1410
|
resolveUrl,
|
|
1346
1411
|
resolveShareUrl,
|
|
1347
1412
|
proseImages,
|
|
1413
|
+
tableColumns,
|
|
1348
1414
|
children
|
|
1349
1415
|
}) {
|
|
1350
1416
|
const env = useMemo(
|
|
1351
|
-
() => ({ resolveUrl, resolveShareUrl, proseImages }),
|
|
1352
|
-
[resolveUrl, resolveShareUrl, proseImages]
|
|
1417
|
+
() => ({ resolveUrl, resolveShareUrl, proseImages, tableColumns }),
|
|
1418
|
+
[resolveUrl, resolveShareUrl, proseImages, tableColumns]
|
|
1353
1419
|
);
|
|
1354
1420
|
return /* @__PURE__ */ jsx(ResultEnvContext, { value: env, children });
|
|
1355
1421
|
}
|
|
@@ -1365,6 +1431,12 @@ function useResolveShareUrl() {
|
|
|
1365
1431
|
function useProseImages() {
|
|
1366
1432
|
return use(ResultEnvContext).proseImages ?? "link";
|
|
1367
1433
|
}
|
|
1434
|
+
var DEFAULT_TABLE_COLUMNS = 5;
|
|
1435
|
+
function useTableColumns() {
|
|
1436
|
+
const budget = use(ResultEnvContext).tableColumns;
|
|
1437
|
+
if (budget === void 0 || Number.isNaN(budget)) return DEFAULT_TABLE_COLUMNS;
|
|
1438
|
+
return Math.max(1, Math.floor(budget));
|
|
1439
|
+
}
|
|
1368
1440
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
1369
1441
|
var TooltipRoot = TooltipPrimitive.Root;
|
|
1370
1442
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
@@ -1811,6 +1883,18 @@ function DateValue({ value }) {
|
|
|
1811
1883
|
if (!content) return /* @__PURE__ */ jsx(Absent, {});
|
|
1812
1884
|
return /* @__PURE__ */ jsx("span", { className: "text-[13px] text-foreground", children: formatDateContent(content) });
|
|
1813
1885
|
}
|
|
1886
|
+
function EnumValue({
|
|
1887
|
+
field,
|
|
1888
|
+
value,
|
|
1889
|
+
compact
|
|
1890
|
+
}) {
|
|
1891
|
+
const presentation = useFieldPresentation();
|
|
1892
|
+
const shown = typeof value === "string" ? enumLabeler(field.options, presentation)(value) : value;
|
|
1893
|
+
return /* @__PURE__ */ jsx(Scalar, { value: shown, compact });
|
|
1894
|
+
}
|
|
1895
|
+
function cellTitle(column, cell, presentation) {
|
|
1896
|
+
return column.kind === "enum" && typeof cell === "string" ? enumLabeler(column.options, presentation)(cell) : String(cell);
|
|
1897
|
+
}
|
|
1814
1898
|
function fileLabel(url, filename, strings) {
|
|
1815
1899
|
if (filename) return filename;
|
|
1816
1900
|
const encoded = encodedFileSummary(url, strings);
|
|
@@ -1829,16 +1913,18 @@ function CopyButton({
|
|
|
1829
1913
|
title
|
|
1830
1914
|
}) {
|
|
1831
1915
|
const [copied, setCopied] = useState(false);
|
|
1916
|
+
useEffect(() => {
|
|
1917
|
+
if (!copied) return;
|
|
1918
|
+
const timer = window.setTimeout(() => setCopied(false), 1500);
|
|
1919
|
+
return () => window.clearTimeout(timer);
|
|
1920
|
+
}, [copied]);
|
|
1832
1921
|
if (typeof navigator === "undefined" || !navigator.clipboard) return null;
|
|
1833
1922
|
return /* @__PURE__ */ jsx(
|
|
1834
1923
|
"button",
|
|
1835
1924
|
{
|
|
1836
1925
|
type: "button",
|
|
1837
1926
|
onClick: () => {
|
|
1838
|
-
const done = () =>
|
|
1839
|
-
setCopied(true);
|
|
1840
|
-
window.setTimeout(() => setCopied(false), 1500);
|
|
1841
|
-
};
|
|
1927
|
+
const done = () => setCopied(true);
|
|
1842
1928
|
if (!provide) {
|
|
1843
1929
|
void navigator.clipboard.writeText(value ?? "").then(done);
|
|
1844
1930
|
return;
|
|
@@ -2118,6 +2204,8 @@ function LeafValue({
|
|
|
2118
2204
|
return /* @__PURE__ */ jsx(ImageValue, { value, compact });
|
|
2119
2205
|
case "object":
|
|
2120
2206
|
return compact ? /* @__PURE__ */ jsx(RecordSummary, { field, value }) : /* @__PURE__ */ jsx(Scalar, { value });
|
|
2207
|
+
case "enum":
|
|
2208
|
+
return /* @__PURE__ */ jsx(EnumValue, { field, value, compact });
|
|
2121
2209
|
default:
|
|
2122
2210
|
return /* @__PURE__ */ jsx(Scalar, { value, compact });
|
|
2123
2211
|
}
|
|
@@ -2126,7 +2214,7 @@ function RecordSummary({ field, value }) {
|
|
|
2126
2214
|
const s = useFieldStrings();
|
|
2127
2215
|
if (isNativeDateNode(field)) return /* @__PURE__ */ jsx(DateValue, { value });
|
|
2128
2216
|
if (!isRecord(value) || Object.keys(value).length === 0) return /* @__PURE__ */ jsx(Absent, {});
|
|
2129
|
-
const naming = isNativeHtmlNode(field) ? void 0 : field.fields
|
|
2217
|
+
const naming = isNativeHtmlNode(field) ? void 0 : recordNameField(field.fields) ?? field.fields.find((member) => member.kind === "prose");
|
|
2130
2218
|
if (naming === void 0) {
|
|
2131
2219
|
return /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap text-[12.5px] text-muted-foreground", children: s.fieldsCount(field.fields.length) });
|
|
2132
2220
|
}
|
|
@@ -2199,8 +2287,10 @@ function fitsACellWhole(field) {
|
|
|
2199
2287
|
return true;
|
|
2200
2288
|
case "text":
|
|
2201
2289
|
return field.maxLength !== void 0 && field.maxLength <= CELL_LENGTH_LIMIT;
|
|
2290
|
+
case "object":
|
|
2291
|
+
return isNativeDateNode(field);
|
|
2202
2292
|
case "list":
|
|
2203
|
-
return fitsACellWhole(field.item);
|
|
2293
|
+
return isInlineColumn(field) && fitsACellWhole(field.item);
|
|
2204
2294
|
default:
|
|
2205
2295
|
return false;
|
|
2206
2296
|
}
|
|
@@ -2213,10 +2303,12 @@ function ObjectTable({
|
|
|
2213
2303
|
}) {
|
|
2214
2304
|
const s = useFieldStrings();
|
|
2215
2305
|
const presentation = useFieldPresentation();
|
|
2306
|
+
const budget = useTableColumns();
|
|
2216
2307
|
const scrollerRef = useRef(null);
|
|
2217
2308
|
const [expanded, setExpanded] = useState(() => /* @__PURE__ */ new Set());
|
|
2218
2309
|
const [viewportWidth, setViewportWidth] = useState();
|
|
2219
|
-
const
|
|
2310
|
+
const { shown, hidden, name } = chooseColumns(columns, budget);
|
|
2311
|
+
const canExpand = hidden > 0 || shown.some((column) => column !== name && !fitsACellWhole(column));
|
|
2220
2312
|
useEffect(() => {
|
|
2221
2313
|
const scroller = scrollerRef.current;
|
|
2222
2314
|
if (!scroller) return;
|
|
@@ -2261,7 +2353,7 @@ function ObjectTable({
|
|
|
2261
2353
|
children: /* @__PURE__ */ jsxs("table", { className: "w-full min-w-full border-collapse text-[13px]", children: [
|
|
2262
2354
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-border bg-muted text-left", children: [
|
|
2263
2355
|
canExpand && /* @__PURE__ */ jsx("th", { scope: "col", style: { width: EXPAND_COLUMN }, className: "px-1", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: s.rowDetailsColumn }) }),
|
|
2264
|
-
|
|
2356
|
+
shown.map((column) => /* @__PURE__ */ jsx(
|
|
2265
2357
|
"th",
|
|
2266
2358
|
{
|
|
2267
2359
|
scope: "col",
|
|
@@ -2275,7 +2367,7 @@ function ObjectTable({
|
|
|
2275
2367
|
))
|
|
2276
2368
|
] }) }),
|
|
2277
2369
|
/* @__PURE__ */ jsx("tbody", { children: items.map((item, index) => {
|
|
2278
|
-
const isOpen = expanded.has(index);
|
|
2370
|
+
const isOpen = canExpand && expanded.has(index);
|
|
2279
2371
|
return /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-border/60 last:border-b-0", children: [
|
|
2280
2372
|
canExpand && /* @__PURE__ */ jsx("td", { className: "px-1 pt-px align-top", children: /* @__PURE__ */ jsx(
|
|
2281
2373
|
"button",
|
|
@@ -2288,7 +2380,7 @@ function ObjectTable({
|
|
|
2288
2380
|
children: isOpen ? /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-3.5" }) : /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-3.5" })
|
|
2289
2381
|
}
|
|
2290
2382
|
) }),
|
|
2291
|
-
isOpen ? /* @__PURE__ */ jsx("td", { colSpan:
|
|
2383
|
+
isOpen ? /* @__PURE__ */ jsx("td", { colSpan: shown.length, className: "bg-card/40 p-0", children: /* @__PURE__ */ jsx(
|
|
2292
2384
|
"div",
|
|
2293
2385
|
{
|
|
2294
2386
|
className: "sticky left-0 px-3.5 py-3",
|
|
@@ -2303,16 +2395,16 @@ function ObjectTable({
|
|
|
2303
2395
|
} : {},
|
|
2304
2396
|
children: /* @__PURE__ */ jsx(ResultField, { field: element, value: item, hideLabel: true })
|
|
2305
2397
|
}
|
|
2306
|
-
) }) :
|
|
2398
|
+
) }) : shown.map((column) => {
|
|
2307
2399
|
const cell = typeof item === "object" && item !== null ? ownProp(item, column.name) : void 0;
|
|
2308
2400
|
return /* @__PURE__ */ jsx("td", { className: "px-3 py-1.5 align-top", children: /* @__PURE__ */ jsx(
|
|
2309
2401
|
"div",
|
|
2310
2402
|
{
|
|
2311
2403
|
className: cn(
|
|
2312
2404
|
"max-w-[44ch]",
|
|
2313
|
-
column.kind === "list" && isInlineColumn(column) ? "min-w-[16ch]" : "truncate"
|
|
2405
|
+
column === name ? "max-w-none min-w-[16ch] wrap-anywhere [&>span]:whitespace-normal" : column.kind === "list" && isInlineColumn(column) ? "min-w-[16ch]" : "truncate"
|
|
2314
2406
|
),
|
|
2315
|
-
...typeof cell === "string" || typeof cell === "number" ? { title:
|
|
2407
|
+
...typeof cell === "string" || typeof cell === "number" ? { title: cellTitle(column, cell, presentation) } : {},
|
|
2316
2408
|
children: /* @__PURE__ */ jsx(LeafValue, { field: column, value: cell, compact: true })
|
|
2317
2409
|
}
|
|
2318
2410
|
) }, column.name);
|
|
@@ -2379,10 +2471,31 @@ function ImageGallery({ items }) {
|
|
|
2379
2471
|
function FileRows({ items, kind }) {
|
|
2380
2472
|
return /* @__PURE__ */ jsx("div", { className: "divide-y divide-border overflow-hidden rounded-lg border border-border", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "bg-card/40 px-3.5 py-2", children: kind === "document" ? /* @__PURE__ */ jsx(DocumentValue, { value: item }) : /* @__PURE__ */ jsx(ImageValue, { value: item, inRow: true }) }, index)) });
|
|
2381
2473
|
}
|
|
2382
|
-
function
|
|
2474
|
+
function recordColumns(item) {
|
|
2383
2475
|
if (item.kind !== "object" || item.fields.length === 0) return void 0;
|
|
2384
2476
|
return item.fields;
|
|
2385
2477
|
}
|
|
2478
|
+
function recordNameField(fields) {
|
|
2479
|
+
return fields.find((member) => member.kind === "text");
|
|
2480
|
+
}
|
|
2481
|
+
function columnTier(field, name) {
|
|
2482
|
+
if (field === name) return 1;
|
|
2483
|
+
if (field.kind !== "list" && fitsACellWhole(field)) return 2;
|
|
2484
|
+
if (field.kind === "text" || field.kind === "list" && isInlineColumn(field)) return 3;
|
|
2485
|
+
return 4;
|
|
2486
|
+
}
|
|
2487
|
+
function chooseColumns(fields, budget) {
|
|
2488
|
+
const name = recordNameField(fields);
|
|
2489
|
+
if (fields.length <= budget) return { shown: fields, hidden: 0, ...name ? { name } : {} };
|
|
2490
|
+
const kept = new Set(
|
|
2491
|
+
fields.map((field, index) => ({ field, index, tier: columnTier(field, name) })).sort((a, b) => a.tier - b.tier || a.index - b.index).slice(0, budget).map(({ field }) => field)
|
|
2492
|
+
);
|
|
2493
|
+
return {
|
|
2494
|
+
shown: fields.filter((field) => kept.has(field)),
|
|
2495
|
+
hidden: fields.length - kept.size,
|
|
2496
|
+
...name ? { name } : {}
|
|
2497
|
+
};
|
|
2498
|
+
}
|
|
2386
2499
|
function ResultField({ field, value, depth = 0, hideLabel = false }) {
|
|
2387
2500
|
const s = useFieldStrings();
|
|
2388
2501
|
const unwrapped = unwrap(field, value);
|
|
@@ -2454,13 +2567,21 @@ function ResultField({ field, value, depth = 0, hideLabel = false }) {
|
|
|
2454
2567
|
}
|
|
2455
2568
|
case "list": {
|
|
2456
2569
|
const items = Array.isArray(unwrapped) ? unwrapped : [];
|
|
2457
|
-
const columns =
|
|
2570
|
+
const columns = recordColumns(field.item);
|
|
2458
2571
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2459
2572
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2", children: [
|
|
2460
2573
|
header,
|
|
2461
2574
|
/* @__PURE__ */ jsx("span", { className: "font-mono text-[10.5px] text-muted-foreground", children: s.itemsCount(items.length) })
|
|
2462
2575
|
] }),
|
|
2463
|
-
items.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-[13px] italic text-muted-foreground", children: s.noItemsYet }) :
|
|
2576
|
+
items.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-[13px] italic text-muted-foreground", children: s.noItemsYet }) : isNativeValueNode(field.item) ? (
|
|
2577
|
+
// A list of dates, pages or composites is a list of VALUES, each read
|
|
2578
|
+
// by its own arm - one per line. Their nodes are `object` (or, for a
|
|
2579
|
+
// composite, `unknown`), so the branches below would tabulate a
|
|
2580
|
+
// date's `date` and `time`, print a page's markup source down a
|
|
2581
|
+
// column named by it, and show a composite as JSON. The arm keyed by
|
|
2582
|
+
// concept is the one that knows what each entry is.
|
|
2583
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border/60 overflow-hidden rounded-lg border border-border", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "bg-card/40 px-3 py-1.5", children: /* @__PURE__ */ jsx(ResultField, { field: field.item, value: item, depth: depth + 1, hideLabel: true }) }, index)) })
|
|
2584
|
+
) : columns ? (
|
|
2464
2585
|
// Same shape every row: the labels are column headers, not per-row
|
|
2465
2586
|
// labels. See `ObjectTable`.
|
|
2466
2587
|
/* @__PURE__ */ jsx(
|
|
@@ -2616,6 +2737,11 @@ function highlight(json) {
|
|
|
2616
2737
|
function JsonView({ value }) {
|
|
2617
2738
|
const s = useFieldStrings();
|
|
2618
2739
|
const [copied, setCopied] = useState(false);
|
|
2740
|
+
useEffect(() => {
|
|
2741
|
+
if (!copied) return;
|
|
2742
|
+
const timer = window.setTimeout(() => setCopied(false), 1500);
|
|
2743
|
+
return () => window.clearTimeout(timer);
|
|
2744
|
+
}, [copied]);
|
|
2619
2745
|
const text = value === null || value === void 0 ? void 0 : typeof value === "object" ? stringifyValue(value) : JSON.stringify(value);
|
|
2620
2746
|
if (text === void 0) {
|
|
2621
2747
|
return /* @__PURE__ */ jsx(Absent, {});
|
|
@@ -2626,10 +2752,7 @@ function JsonView({ value }) {
|
|
|
2626
2752
|
{
|
|
2627
2753
|
type: "button",
|
|
2628
2754
|
onClick: () => {
|
|
2629
|
-
void navigator.clipboard.writeText(text).then(() =>
|
|
2630
|
-
setCopied(true);
|
|
2631
|
-
window.setTimeout(() => setCopied(false), 1500);
|
|
2632
|
-
});
|
|
2755
|
+
void navigator.clipboard.writeText(text).then(() => setCopied(true));
|
|
2633
2756
|
},
|
|
2634
2757
|
"aria-label": s.copyJson,
|
|
2635
2758
|
className: "absolute right-2 top-2 rounded border border-border bg-card p-1 text-muted-foreground hover:text-foreground focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1",
|
|
@@ -2717,5 +2840,5 @@ function StuffViewer({
|
|
|
2717
2840
|
}
|
|
2718
2841
|
|
|
2719
2842
|
export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EnumField, FieldDomIdProvider, FieldPresentationProvider, FieldRenderer, FieldShell, FieldStringsProvider, HtmlPreview, ImageField, JsonView, ListField, Markdown, NumberField, ObjectField, OptionalToggle, ProseField, ResultEnvProvider, ResultField, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StuffViewer, Switch, TextField, ToggleGroup, ToggleGroupItem, UnknownField, cn, downloadStuff, fieldControlClass, humanizeFieldName, useFieldDomId, useFieldPresentation, useFieldStrings, useProseImages, useResolveShareUrl, useResolveUrl, useResolvedUrl };
|
|
2720
|
-
//# sourceMappingURL=chunk-
|
|
2721
|
-
//# sourceMappingURL=chunk-
|
|
2843
|
+
//# sourceMappingURL=chunk-W56WIIVC.js.map
|
|
2844
|
+
//# sourceMappingURL=chunk-W56WIIVC.js.map
|