@pipelex/mthds-form 0.34.0 → 0.35.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/{chunk-5RV3ASMO.js → chunk-TD62R3P6.js} +348 -190
- package/dist/chunk-TD62R3P6.js.map +1 -0
- package/dist/{chunk-XYS5KCXB.js → chunk-XLTYIIUY.js} +127 -10
- package/dist/chunk-XLTYIIUY.js.map +1 -0
- package/dist/{field-renderer-BYN6YrU-.d.ts → field-presentation-D5BkBSjX.d.ts} +49 -9
- package/dist/generative/headless/index.d.ts +36 -2
- package/dist/generative/headless/index.js +2 -1
- package/dist/generative/index.d.ts +27 -19
- package/dist/generative/index.js +31 -30
- package/dist/generative/index.js.map +1 -1
- package/dist/layout-sample.mthds +85 -0
- package/dist/react/index.d.ts +49 -61
- package/dist/react/index.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -2
- package/dist/chunk-5RV3ASMO.js.map +0 -1
- package/dist/chunk-XYS5KCXB.js.map +0 -1
|
@@ -10,13 +10,13 @@ import { conceptCategory } from './chunk-FABY3DEY.js';
|
|
|
10
10
|
import { acceptLabel, acceptMap, isAcceptedFile, normalizeMimeType, formatOfFilename, DOCUMENT_FORMATS, IMAGE_FORMATS } from './chunk-XCO6GTEC.js';
|
|
11
11
|
import { shownAsOptional, isFoldedOptional, anyOptionalStructureOpen, isOptionalStructure, computeReadiness, gateRefusal, optionalStructureOpen, mustBeFilled } from './chunk-TF4RTKLH.js';
|
|
12
12
|
import { ownProp } from './chunk-V3OV2XQT.js';
|
|
13
|
-
import { toStoredDateValue,
|
|
13
|
+
import { toDateInputValue, toStoredDateValue, asCalendarDate } from './chunk-GKV77RAS.js';
|
|
14
14
|
import { clsx } from 'clsx';
|
|
15
15
|
import { twMerge } from 'tailwind-merge';
|
|
16
|
-
import { ChevronDown, ChevronUp, Check, List, Braces, ListChecks, ToggleLeft, Hash, Image as Image$1, FileText, CalendarDays, Type, Folder, Search, X, ImageIcon, Loader2, ImageOff, Upload, Link2, EyeOff, Eye, Minus, Plus, Trash2,
|
|
16
|
+
import { ChevronDown, ChevronUp, Check, List, Braces, ListChecks, ToggleLeft, Hash, Image as Image$1, FileText, CalendarDays, Type, Folder, Search, X, ImageIcon, Loader2, ImageOff, Upload, Link2, EyeOff, Eye, Minus, Plus, Trash2, ClipboardPaste, MoreHorizontal, TriangleAlert, FileDown, Copy, Download, ChevronRight, ExternalLink, ChevronLeft } from 'lucide-react';
|
|
17
17
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
18
18
|
import * as React9 from 'react';
|
|
19
|
-
import { createContext, use,
|
|
19
|
+
import { createContext, use, useMemo, useContext, useId, useState, useEffect, useRef, useLayoutEffect, useCallback, Fragment as Fragment$1, useSyncExternalStore } from 'react';
|
|
20
20
|
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
|
21
21
|
import { useDropzone } from 'react-dropzone';
|
|
22
22
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
@@ -84,100 +84,94 @@ function fieldLabel(title, name, presentation) {
|
|
|
84
84
|
if (title !== void 0) return title;
|
|
85
85
|
return presentation === "app" ? humanizeFieldName(name) : name;
|
|
86
86
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
] }),
|
|
165
|
-
field.description && /* @__PURE__ */ jsx("p", { className: "text-[12px] leading-relaxed text-muted-foreground", children: field.description })
|
|
166
|
-
] }),
|
|
167
|
-
/* @__PURE__ */ jsx(
|
|
168
|
-
Switch,
|
|
169
|
-
{
|
|
170
|
-
id: domId,
|
|
171
|
-
checked: value ?? false,
|
|
172
|
-
onCheckedChange: onChange,
|
|
173
|
-
disabled,
|
|
174
|
-
className: "shrink-0"
|
|
175
|
-
}
|
|
176
|
-
)
|
|
177
|
-
]
|
|
87
|
+
function shownDescription(description, label, kinds, presentation) {
|
|
88
|
+
if (!description || presentation !== "app") return description || void 0;
|
|
89
|
+
if (label.trim() === "") return void 0;
|
|
90
|
+
return descriptionAddsToLabel(description, label, kinds) ? description : void 0;
|
|
91
|
+
}
|
|
92
|
+
function shownItemDescription(itemDescription, listLabel, listDescription, kinds, presentation) {
|
|
93
|
+
if (!itemDescription || presentation !== "app") return void 0;
|
|
94
|
+
if (itemDescription === listDescription) return void 0;
|
|
95
|
+
const said = listDescription ? `${listLabel} ${listDescription}` : listLabel;
|
|
96
|
+
return descriptionAddsToLabel(itemDescription, said, kinds) ? itemDescription : void 0;
|
|
97
|
+
}
|
|
98
|
+
function descriptionAddsToLabel(description, label, kinds) {
|
|
99
|
+
if (label.trim() === "") return true;
|
|
100
|
+
const words = contentStems(description);
|
|
101
|
+
if (words.length === 0) return true;
|
|
102
|
+
const said = new Set(contentStems(label));
|
|
103
|
+
for (const kind of kinds) for (const word of KIND_WORDS[kind]) said.add(stem(word));
|
|
104
|
+
return words.some((word) => !said.has(word));
|
|
105
|
+
}
|
|
106
|
+
var KIND_WORDS = {
|
|
107
|
+
text: ["text"],
|
|
108
|
+
date: ["date", "day"],
|
|
109
|
+
document: ["document", "file"],
|
|
110
|
+
image: ["image", "picture", "photo"],
|
|
111
|
+
number: ["number"],
|
|
112
|
+
boolean: [],
|
|
113
|
+
choice: [],
|
|
114
|
+
structured: [],
|
|
115
|
+
list: ["list"]
|
|
116
|
+
};
|
|
117
|
+
var FILLER = /* @__PURE__ */ new Set([
|
|
118
|
+
"a",
|
|
119
|
+
"an",
|
|
120
|
+
"the",
|
|
121
|
+
"of",
|
|
122
|
+
"for",
|
|
123
|
+
"to",
|
|
124
|
+
"in",
|
|
125
|
+
"on",
|
|
126
|
+
"at",
|
|
127
|
+
"by",
|
|
128
|
+
"with",
|
|
129
|
+
"and",
|
|
130
|
+
"or",
|
|
131
|
+
"is",
|
|
132
|
+
"are",
|
|
133
|
+
"be",
|
|
134
|
+
"it",
|
|
135
|
+
"its",
|
|
136
|
+
"this",
|
|
137
|
+
"that",
|
|
138
|
+
"these",
|
|
139
|
+
"those",
|
|
140
|
+
"their",
|
|
141
|
+
"they",
|
|
142
|
+
"them",
|
|
143
|
+
"his",
|
|
144
|
+
"her",
|
|
145
|
+
"your",
|
|
146
|
+
"you",
|
|
147
|
+
"our",
|
|
148
|
+
"we",
|
|
149
|
+
"if",
|
|
150
|
+
"any",
|
|
151
|
+
"as",
|
|
152
|
+
"from",
|
|
153
|
+
"some",
|
|
154
|
+
"one"
|
|
155
|
+
]);
|
|
156
|
+
function contentStems(text) {
|
|
157
|
+
return (text.normalize("NFC").toLowerCase().replace(/['’]s\b/gu, "").match(WORD) ?? []).filter((word) => !FILLER.has(word)).map(stem);
|
|
158
|
+
}
|
|
159
|
+
var WORD = /[\p{L}\p{M}\p{N}]+|[\p{S}%‰#@]/gu;
|
|
160
|
+
function stem(word) {
|
|
161
|
+
for (const [suffix, floor] of SUFFIXES) {
|
|
162
|
+
if (word.endsWith(suffix) && word.length - suffix.length >= floor) {
|
|
163
|
+
return word.slice(0, -suffix.length);
|
|
178
164
|
}
|
|
179
|
-
|
|
180
|
-
|
|
165
|
+
}
|
|
166
|
+
return word;
|
|
167
|
+
}
|
|
168
|
+
var SUFFIXES = [
|
|
169
|
+
["ing", 4],
|
|
170
|
+
["ed", 4],
|
|
171
|
+
["es", 4],
|
|
172
|
+
["s", 3],
|
|
173
|
+
["e", 4]
|
|
174
|
+
];
|
|
181
175
|
|
|
182
176
|
// src/react/locales/calendar.ts
|
|
183
177
|
function dayNumber(date) {
|
|
@@ -216,7 +210,7 @@ function someNames(names, more) {
|
|
|
216
210
|
return AND.format(more > 0 ? [...names, `${more} more`] : names);
|
|
217
211
|
}
|
|
218
212
|
var EN_FIELD_STRINGS = {
|
|
219
|
-
optionalBadge: "
|
|
213
|
+
optionalBadge: "Optional",
|
|
220
214
|
selectPlaceholder: "Select\u2026",
|
|
221
215
|
typeValuePlaceholder: "Type a value\u2026",
|
|
222
216
|
writeHerePlaceholder: "Write here\u2026",
|
|
@@ -231,8 +225,8 @@ var EN_FIELD_STRINGS = {
|
|
|
231
225
|
fieldsCount: (count) => count === 1 ? "1 field" : `${count} fields`,
|
|
232
226
|
uploading: "Uploading\u2026",
|
|
233
227
|
dropToUpload: "Drop to upload",
|
|
234
|
-
dropOrBrowse: "
|
|
235
|
-
pasteUrlInstead: "
|
|
228
|
+
dropOrBrowse: "Choose a file or drop it here",
|
|
229
|
+
pasteUrlInstead: "Paste a link instead",
|
|
236
230
|
uploadUnavailable: "Files cannot be uploaded here. Paste a link to the file instead.",
|
|
237
231
|
urlPlaceholder: "https://\u2026",
|
|
238
232
|
fileUrlAria: (label) => label ? `Link to the file for ${label}` : "Link to the file",
|
|
@@ -282,7 +276,7 @@ var EN_FIELD_STRINGS = {
|
|
|
282
276
|
nextImage: "Next picture",
|
|
283
277
|
openOriginal: "Open the original",
|
|
284
278
|
unsupportedFileType: (formats) => `That file type is not supported. Accepted formats: ${formats}.`,
|
|
285
|
-
dropFilesOrBrowse: "
|
|
279
|
+
dropFilesOrBrowse: "Choose files or drop them here",
|
|
286
280
|
dropFilesToAdd: "Drop to add the files",
|
|
287
281
|
addFilesAria: (label) => label ? `Add files to ${label}` : "Add files",
|
|
288
282
|
filesAdded: (count) => count === 1 ? "1 file added" : `${count} files added`,
|
|
@@ -402,7 +396,7 @@ function someNames2(names, more) {
|
|
|
402
396
|
return AND2.format(more > 0 ? [...names, `${more} ${plural(more, "autre", "autres")}`] : names);
|
|
403
397
|
}
|
|
404
398
|
var FR_FIELD_STRINGS = {
|
|
405
|
-
optionalBadge: "
|
|
399
|
+
optionalBadge: "Facultatif",
|
|
406
400
|
selectPlaceholder: "Choisir\u2026",
|
|
407
401
|
typeValuePlaceholder: "Saisissez une valeur\u2026",
|
|
408
402
|
writeHerePlaceholder: "\xC9crivez ici\u2026",
|
|
@@ -417,8 +411,8 @@ var FR_FIELD_STRINGS = {
|
|
|
417
411
|
fieldsCount: (count) => `${count} ${plural(count, "champ", "champs")}`,
|
|
418
412
|
uploading: "Envoi en cours\u2026",
|
|
419
413
|
dropToUpload: "D\xE9posez pour envoyer",
|
|
420
|
-
dropOrBrowse: "
|
|
421
|
-
pasteUrlInstead: "
|
|
414
|
+
dropOrBrowse: "Choisissez un fichier ou d\xE9posez-le ici",
|
|
415
|
+
pasteUrlInstead: "Collez plut\xF4t un lien",
|
|
422
416
|
uploadUnavailable: "Impossible d\u2019envoyer un fichier ici. Collez plut\xF4t un lien vers le fichier.",
|
|
423
417
|
urlPlaceholder: "https://\u2026",
|
|
424
418
|
fileUrlAria: (label) => label ? `Lien vers le fichier pour ${label}` : "Lien vers le fichier",
|
|
@@ -468,7 +462,7 @@ var FR_FIELD_STRINGS = {
|
|
|
468
462
|
nextImage: "Image suivante",
|
|
469
463
|
openOriginal: "Ouvrir l\u2019original",
|
|
470
464
|
unsupportedFileType: (formats) => `Ce type de fichier n\u2019est pas pris en charge. Formats accept\xE9s\xA0: ${formats}.`,
|
|
471
|
-
dropFilesOrBrowse: "
|
|
465
|
+
dropFilesOrBrowse: "Choisissez des fichiers ou d\xE9posez-les ici",
|
|
472
466
|
dropFilesToAdd: "D\xE9posez pour ajouter les fichiers",
|
|
473
467
|
addFilesAria: (label) => label ? `Ajouter des fichiers \xE0 ${label}` : "Ajouter des fichiers",
|
|
474
468
|
filesAdded: (count) => `${count} ${plural(count, "fichier ajout\xE9", "fichiers ajout\xE9s")}`,
|
|
@@ -568,6 +562,23 @@ function FieldStringsProvider({
|
|
|
568
562
|
function useFieldStrings() {
|
|
569
563
|
return useContext(FieldStringsContext);
|
|
570
564
|
}
|
|
565
|
+
|
|
566
|
+
// src/react/field-styles.ts
|
|
567
|
+
var fieldControlClass = cn(
|
|
568
|
+
"w-full rounded-md border border-border bg-input text-sm text-foreground",
|
|
569
|
+
"placeholder:text-muted-foreground/70 transition-colors",
|
|
570
|
+
"focus-visible:outline-hidden focus-visible:ring-1",
|
|
571
|
+
"focus-visible:border-ring focus-visible:ring-ring/40",
|
|
572
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
573
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/30"
|
|
574
|
+
);
|
|
575
|
+
var rowActionClass = cn(
|
|
576
|
+
"flex min-h-11 w-full items-center justify-center gap-2 rounded-md border border-border px-3 text-[14px] text-foreground transition-colors",
|
|
577
|
+
"enabled:hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50 sm:min-h-9"
|
|
578
|
+
);
|
|
579
|
+
function smallPrintClass(isApp) {
|
|
580
|
+
return isApp ? "text-[12px] text-muted-foreground tabular-nums" : "font-mono text-[10.5px] text-muted-foreground";
|
|
581
|
+
}
|
|
571
582
|
var ERROR_OUTLINE = "rounded-lg outline-solid outline-1 outline-offset-4 outline-destructive";
|
|
572
583
|
function FieldShell({
|
|
573
584
|
name,
|
|
@@ -575,18 +586,19 @@ function FieldShell({
|
|
|
575
586
|
conceptRef,
|
|
576
587
|
category,
|
|
577
588
|
description,
|
|
589
|
+
hint,
|
|
578
590
|
required,
|
|
579
591
|
error,
|
|
580
592
|
htmlFor,
|
|
581
593
|
children,
|
|
582
594
|
className
|
|
583
595
|
}) {
|
|
584
|
-
const s = useFieldStrings();
|
|
585
596
|
const presentation = useFieldPresentation();
|
|
586
597
|
const isApp = presentation === "app";
|
|
587
598
|
const Label3 = htmlFor ? "label" : "div";
|
|
588
599
|
const labelText = fieldLabel(title, name, presentation);
|
|
589
600
|
const showLabel = labelText.trim() !== "";
|
|
601
|
+
const shownText = shownDescription(description, labelText, [category], presentation) ?? hint;
|
|
590
602
|
const outlined = isApp && !!error;
|
|
591
603
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
|
|
592
604
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
|
|
@@ -602,20 +614,9 @@ function FieldShell({
|
|
|
602
614
|
}
|
|
603
615
|
),
|
|
604
616
|
!isApp && /* @__PURE__ */ jsx(ConceptPill, { conceptRef, category }),
|
|
605
|
-
!required &&
|
|
606
|
-
// a monospace tag was a third face on a host's page.
|
|
607
|
-
/* @__PURE__ */ jsx(
|
|
608
|
-
"span",
|
|
609
|
-
{
|
|
610
|
-
className: cn(
|
|
611
|
-
"ml-auto text-[10px] uppercase tracking-wider text-muted-foreground",
|
|
612
|
-
!isApp && "font-mono"
|
|
613
|
-
),
|
|
614
|
-
children: s.optionalBadge
|
|
615
|
-
}
|
|
616
|
-
)
|
|
617
|
+
!required && /* @__PURE__ */ jsx(OptionalMark, {})
|
|
617
618
|
] }),
|
|
618
|
-
|
|
619
|
+
shownText && /* @__PURE__ */ jsx(FieldDescription, { children: shownText }),
|
|
619
620
|
/* @__PURE__ */ jsx(
|
|
620
621
|
"div",
|
|
621
622
|
{
|
|
@@ -627,18 +628,123 @@ function FieldShell({
|
|
|
627
628
|
error && /* @__PURE__ */ jsx("p", { className: "flex items-center gap-1 text-[11px] text-destructive", role: "alert", children: error })
|
|
628
629
|
] });
|
|
629
630
|
}
|
|
631
|
+
function OptionalMark() {
|
|
632
|
+
const s = useFieldStrings();
|
|
633
|
+
const isApp = useFieldPresentation() === "app";
|
|
634
|
+
return /* @__PURE__ */ jsx(
|
|
635
|
+
"span",
|
|
636
|
+
{
|
|
637
|
+
className: cn(
|
|
638
|
+
"ml-auto",
|
|
639
|
+
isApp ? smallPrintClass(true) : "font-mono text-[10px] uppercase tracking-wider text-muted-foreground"
|
|
640
|
+
),
|
|
641
|
+
children: s.optionalBadge
|
|
642
|
+
}
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
function FieldDescription({ id, children }) {
|
|
646
|
+
return /* @__PURE__ */ jsx("p", { id, className: "text-[12px] leading-relaxed text-muted-foreground", children });
|
|
647
|
+
}
|
|
630
648
|
|
|
631
|
-
// src/react/
|
|
632
|
-
var
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
);
|
|
649
|
+
// src/react/role-tokens.ts
|
|
650
|
+
var linkTextClass = "text-[color:var(--link,var(--primary,hsl(240_5.9%_10%)))]";
|
|
651
|
+
var selectedFillClass = "bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
|
|
652
|
+
var selectedStateFillClass = "data-[state=on]:bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
|
|
653
|
+
var selectedCheckedFillClass = "aria-checked:bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
|
|
654
|
+
var selectedFillStrongClass = "bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_15%,transparent))]";
|
|
655
|
+
var selectedBorderClass = "border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
|
|
656
|
+
var selectedStateBorderClass = "data-[state=on]:border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
|
|
657
|
+
var selectedHoverBorderClass = "hover:border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
|
|
658
|
+
var checkedAccentClass = "accent-[color:var(--link,var(--primary,hsl(240_5.9%_10%)))]";
|
|
659
|
+
var focusOutlineClass = "focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring";
|
|
660
|
+
var focusWithinOutlineClass = "focus-within:outline-solid focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-ring";
|
|
661
|
+
var focusOutlineInsetClass = "focus-visible:outline-solid focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring";
|
|
662
|
+
var frameFocusOutlineClass = "data-focus-visible:outline-solid data-focus-visible:outline-2 data-focus-visible:-outline-offset-2 data-focus-visible:outline-ring";
|
|
663
|
+
var Switch = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
664
|
+
SwitchPrimitives.Root,
|
|
665
|
+
{
|
|
666
|
+
className: cn(
|
|
667
|
+
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-muted-foreground",
|
|
668
|
+
focusOutlineClass,
|
|
669
|
+
"max-sm:relative max-sm:after:absolute max-sm:after:-inset-x-0.5 max-sm:after:-inset-y-3 max-sm:after:content-['']",
|
|
670
|
+
className
|
|
671
|
+
),
|
|
672
|
+
...props,
|
|
673
|
+
ref,
|
|
674
|
+
children: /* @__PURE__ */ jsx(
|
|
675
|
+
SwitchPrimitives.Thumb,
|
|
676
|
+
{
|
|
677
|
+
className: cn(
|
|
678
|
+
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
|
679
|
+
)
|
|
680
|
+
}
|
|
681
|
+
)
|
|
682
|
+
}
|
|
683
|
+
));
|
|
684
|
+
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
685
|
+
var FieldDomIdContext = createContext(null);
|
|
686
|
+
function FieldDomIdProvider({
|
|
687
|
+
prefix,
|
|
688
|
+
children
|
|
689
|
+
}) {
|
|
690
|
+
const generated = useId();
|
|
691
|
+
return /* @__PURE__ */ jsx(FieldDomIdContext, { value: prefix ?? generated, children });
|
|
692
|
+
}
|
|
693
|
+
function useFieldDomId(path) {
|
|
694
|
+
const scoped = use(FieldDomIdContext);
|
|
695
|
+
const local = useId();
|
|
696
|
+
const prefix = scoped ?? local;
|
|
697
|
+
return prefix === "" ? path : `${prefix}-${path}`;
|
|
698
|
+
}
|
|
699
|
+
function BooleanField({ field, value, onChange, id, disabled }) {
|
|
700
|
+
const presentation = useFieldPresentation();
|
|
701
|
+
const isApp = presentation === "app";
|
|
702
|
+
const domId = useFieldDomId(id);
|
|
703
|
+
const label = fieldLabel(field.title, field.name, presentation);
|
|
704
|
+
const description = shownDescription(field.description, label, ["boolean"], presentation);
|
|
705
|
+
return /* @__PURE__ */ jsxs(
|
|
706
|
+
"div",
|
|
707
|
+
{
|
|
708
|
+
className: cn(
|
|
709
|
+
"flex items-center justify-between gap-4 rounded-md border border-border bg-input px-3.5 py-3",
|
|
710
|
+
disabled && "opacity-50"
|
|
711
|
+
),
|
|
712
|
+
children: [
|
|
713
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
|
|
714
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
|
|
715
|
+
/* @__PURE__ */ jsx(
|
|
716
|
+
"label",
|
|
717
|
+
{
|
|
718
|
+
htmlFor: domId,
|
|
719
|
+
className: cn(
|
|
720
|
+
"text-[13px] font-medium leading-none text-foreground",
|
|
721
|
+
isApp ? "text-[13.5px]" : "font-mono"
|
|
722
|
+
),
|
|
723
|
+
children: label
|
|
724
|
+
}
|
|
725
|
+
),
|
|
726
|
+
!isApp && /* @__PURE__ */ jsx(ConceptPill, { conceptRef: field.conceptRef, category: "boolean" })
|
|
727
|
+
] }),
|
|
728
|
+
description && /* @__PURE__ */ jsx(FieldDescription, { children: description })
|
|
729
|
+
] }),
|
|
730
|
+
/* @__PURE__ */ jsx(
|
|
731
|
+
Switch,
|
|
732
|
+
{
|
|
733
|
+
id: domId,
|
|
734
|
+
checked: value ?? false,
|
|
735
|
+
onCheckedChange: onChange,
|
|
736
|
+
disabled,
|
|
737
|
+
className: "shrink-0"
|
|
738
|
+
}
|
|
739
|
+
)
|
|
740
|
+
]
|
|
741
|
+
}
|
|
742
|
+
);
|
|
743
|
+
}
|
|
640
744
|
function DateField({ field, value, onChange, id, error, disabled }) {
|
|
641
745
|
const domId = useFieldDomId(id);
|
|
746
|
+
const isApp = useFieldPresentation() === "app";
|
|
747
|
+
const shown = toDateInputValue(value);
|
|
642
748
|
return /* @__PURE__ */ jsx(
|
|
643
749
|
FieldShell,
|
|
644
750
|
{
|
|
@@ -655,11 +761,17 @@ function DateField({ field, value, onChange, id, error, disabled }) {
|
|
|
655
761
|
{
|
|
656
762
|
id: domId,
|
|
657
763
|
type: "date",
|
|
658
|
-
value:
|
|
764
|
+
value: shown,
|
|
659
765
|
disabled,
|
|
660
766
|
"aria-invalid": !!error,
|
|
767
|
+
"data-empty": asCalendarDate(shown) === null ? "" : void 0,
|
|
661
768
|
onChange: (e) => onChange(toStoredDateValue(e.target.value, field.datetime)),
|
|
662
|
-
className: cn(
|
|
769
|
+
className: cn(
|
|
770
|
+
fieldControlClass,
|
|
771
|
+
"h-11 px-3 tabular-nums data-empty:text-muted-foreground dark:scheme-dark",
|
|
772
|
+
"[&::-webkit-calendar-picker-indicator]:cursor-pointer",
|
|
773
|
+
!isApp && "font-mono"
|
|
774
|
+
)
|
|
663
775
|
}
|
|
664
776
|
)
|
|
665
777
|
}
|
|
@@ -1001,10 +1113,7 @@ function FilePickerEntry({ onOpen, label, disabled, ref, id }) {
|
|
|
1001
1113
|
disabled,
|
|
1002
1114
|
"aria-haspopup": "dialog",
|
|
1003
1115
|
"aria-label": s.chooseFromSourceAria(label),
|
|
1004
|
-
className: cn(
|
|
1005
|
-
"flex min-h-11 w-full items-center justify-center gap-2 rounded-md border border-border px-3 text-[14px] text-foreground transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50 sm:min-h-9",
|
|
1006
|
-
focusOutlineClass
|
|
1007
|
-
),
|
|
1116
|
+
className: cn(rowActionClass, focusOutlineClass),
|
|
1008
1117
|
children: [
|
|
1009
1118
|
/* @__PURE__ */ jsx(Folder, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
|
|
1010
1119
|
s.chooseFromSource
|
|
@@ -1390,6 +1499,7 @@ function FileField({
|
|
|
1390
1499
|
}) {
|
|
1391
1500
|
const s = useFieldStrings();
|
|
1392
1501
|
const presentation = useFieldPresentation();
|
|
1502
|
+
const isApp = presentation === "app";
|
|
1393
1503
|
const domId = useFieldDomId(id);
|
|
1394
1504
|
const [showUrl, setShowUrl] = useState(false);
|
|
1395
1505
|
const [typedUrl, setTypedUrl] = useState(null);
|
|
@@ -1651,7 +1761,7 @@ function FileField({
|
|
|
1651
1761
|
s.uploading
|
|
1652
1762
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1653
1763
|
noUploadLineShown && /* @__PURE__ */ jsx("p", { id: noUploadLineId, className: "text-[12px] text-muted-foreground", children: s.uploadUnavailable }),
|
|
1654
|
-
hint && /* @__PURE__ */ jsx("p", { className:
|
|
1764
|
+
hint && /* @__PURE__ */ jsx("p", { className: smallPrintClass(isApp), children: hint })
|
|
1655
1765
|
] }) })
|
|
1656
1766
|
) : (
|
|
1657
1767
|
// `role="presentation"` and no tab stop: this div is the drop TARGET and
|
|
@@ -1689,7 +1799,7 @@ function FileField({
|
|
|
1689
1799
|
/* @__PURE__ */ jsx(Upload, { className: "h-5 w-5 text-muted-foreground", strokeWidth: 1.75 }),
|
|
1690
1800
|
/* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
1691
1801
|
/* @__PURE__ */ jsx("p", { className: "text-[13px] text-foreground", children: isDragActive ? s.dropToUpload : s.dropOrBrowse }),
|
|
1692
|
-
hint && /* @__PURE__ */ jsx("p", { className:
|
|
1802
|
+
hint && /* @__PURE__ */ jsx("p", { className: smallPrintClass(isApp), children: hint })
|
|
1693
1803
|
] })
|
|
1694
1804
|
] })
|
|
1695
1805
|
]
|
|
@@ -1697,8 +1807,9 @@ function FileField({
|
|
|
1697
1807
|
)
|
|
1698
1808
|
),
|
|
1699
1809
|
!busy && (refusal ? /* @__PURE__ */ jsx("p", { role: "alert", className: "text-[12px] text-destructive", children: refusal.kind === "type" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1700
|
-
/* @__PURE__ */ jsx("span", { className: "font-mono", children: refusal.name }),
|
|
1701
|
-
" \u2014
|
|
1810
|
+
/* @__PURE__ */ jsx("span", { className: isApp ? "font-medium" : "font-mono", children: refusal.name }),
|
|
1811
|
+
" \u2014",
|
|
1812
|
+
" ",
|
|
1702
1813
|
s.unsupportedFileType(hint)
|
|
1703
1814
|
] }) : dropArea?.open ? (
|
|
1704
1815
|
// Pointed to only while it takes files: a full list's area is
|
|
@@ -1723,7 +1834,12 @@ function FileField({
|
|
|
1723
1834
|
setTypedUrl(e.target.value);
|
|
1724
1835
|
onChange(e.target.value ? { url: e.target.value } : void 0);
|
|
1725
1836
|
},
|
|
1726
|
-
className: cn(
|
|
1837
|
+
className: cn(
|
|
1838
|
+
fieldControlClass,
|
|
1839
|
+
// In an app, a control of the field family like any other; in a
|
|
1840
|
+
// studio, a reference set as code, under the field's mono name.
|
|
1841
|
+
isApp ? "h-11 px-3" : "h-9 px-3 font-mono text-[12px]"
|
|
1842
|
+
)
|
|
1727
1843
|
}
|
|
1728
1844
|
) : allowUrl && /* @__PURE__ */ jsxs(
|
|
1729
1845
|
"button",
|
|
@@ -1732,13 +1848,21 @@ function FileField({
|
|
|
1732
1848
|
disabled: busy,
|
|
1733
1849
|
onClick: () => setShowUrl(true),
|
|
1734
1850
|
className: cn(
|
|
1735
|
-
"flex w-fit items-center
|
|
1736
|
-
|
|
1851
|
+
"flex w-fit items-center rounded-sm text-muted-foreground transition-colors hover:text-foreground disabled:opacity-50 max-sm:min-h-11",
|
|
1852
|
+
// A studio's aside is a mono footnote; an app's is a quiet text
|
|
1853
|
+
// action in the page's face, underlined under the pointer.
|
|
1854
|
+
isApp ? "gap-1.5 text-[13px] underline-offset-4 hover:underline" : "gap-1 font-mono text-[11px]",
|
|
1737
1855
|
focusOutlineClass,
|
|
1738
1856
|
"focus-visible:outline-offset-2"
|
|
1739
1857
|
),
|
|
1740
1858
|
children: [
|
|
1741
|
-
/* @__PURE__ */ jsx(
|
|
1859
|
+
/* @__PURE__ */ jsx(
|
|
1860
|
+
Link2,
|
|
1861
|
+
{
|
|
1862
|
+
className: cn("shrink-0", isApp ? "h-3.5 w-3.5" : "h-3 w-3"),
|
|
1863
|
+
"aria-hidden": "true"
|
|
1864
|
+
}
|
|
1865
|
+
),
|
|
1742
1866
|
s.pasteUrlInstead
|
|
1743
1867
|
]
|
|
1744
1868
|
}
|
|
@@ -1838,7 +1962,16 @@ function FileChip({
|
|
|
1838
1962
|
/* @__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" }) }),
|
|
1839
1963
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 basis-32 [contain:inline-size]", children: [
|
|
1840
1964
|
/* @__PURE__ */ jsx("p", { className: "truncate text-[13px] font-medium text-foreground", children: value?.filename ?? s.uploadedFile }),
|
|
1841
|
-
subtitle && /* @__PURE__ */ jsx(
|
|
1965
|
+
subtitle && /* @__PURE__ */ jsx(
|
|
1966
|
+
"p",
|
|
1967
|
+
{
|
|
1968
|
+
className: cn(
|
|
1969
|
+
"truncate text-muted-foreground",
|
|
1970
|
+
presentation === "app" ? "text-[12px]" : "font-mono text-[10.5px]"
|
|
1971
|
+
),
|
|
1972
|
+
children: subtitle
|
|
1973
|
+
}
|
|
1974
|
+
)
|
|
1842
1975
|
] }),
|
|
1843
1976
|
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex shrink-0 items-center gap-3", children: [
|
|
1844
1977
|
canPreview && /* @__PURE__ */ jsxs(
|
|
@@ -1847,12 +1980,12 @@ function FileChip({
|
|
|
1847
1980
|
type: "button",
|
|
1848
1981
|
onClick: onTogglePreview,
|
|
1849
1982
|
className: cn(
|
|
1850
|
-
"inline-flex h-7 shrink-0 items-center gap-1 rounded-md border border-border px-2 text-[11px] text-muted-foreground transition-colors hover:bg-muted hover:text-foreground max-sm:
|
|
1983
|
+
"inline-flex h-7 shrink-0 items-center gap-1 rounded-md border border-border px-2 text-[11px] text-muted-foreground transition-colors hover:bg-muted hover:text-foreground max-sm:size-11 max-sm:justify-center max-sm:px-0",
|
|
1851
1984
|
focusOutlineClass
|
|
1852
1985
|
),
|
|
1853
1986
|
children: [
|
|
1854
1987
|
previewOpen ? /* @__PURE__ */ jsx(EyeOff, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(Eye, { className: "h-3.5 w-3.5" }),
|
|
1855
|
-
s.preview
|
|
1988
|
+
/* @__PURE__ */ jsx("span", { className: "max-sm:sr-only", children: s.preview })
|
|
1856
1989
|
]
|
|
1857
1990
|
}
|
|
1858
1991
|
),
|
|
@@ -2057,6 +2190,7 @@ function EnumField({ field, value, onChange, id, error, disabled }) {
|
|
|
2057
2190
|
function NumberField({ field, value, onChange, id, error, disabled }) {
|
|
2058
2191
|
const s = useFieldStrings();
|
|
2059
2192
|
const domId = useFieldDomId(id);
|
|
2193
|
+
const isApp = useFieldPresentation() === "app";
|
|
2060
2194
|
const step = field.integer ? 1 : 0.1;
|
|
2061
2195
|
const clamp = (n) => {
|
|
2062
2196
|
let next = n;
|
|
@@ -2073,7 +2207,8 @@ function NumberField({ field, value, onChange, id, error, disabled }) {
|
|
|
2073
2207
|
title: field.title,
|
|
2074
2208
|
conceptRef: field.conceptRef,
|
|
2075
2209
|
category: "number",
|
|
2076
|
-
description: field.description
|
|
2210
|
+
description: field.description,
|
|
2211
|
+
hint: rangeHint,
|
|
2077
2212
|
required: !shownAsOptional(field),
|
|
2078
2213
|
error,
|
|
2079
2214
|
htmlFor: domId,
|
|
@@ -2094,7 +2229,10 @@ function NumberField({ field, value, onChange, id, error, disabled }) {
|
|
|
2094
2229
|
onChange: (e) => onChange(e.target.value === "" ? void 0 : Number(e.target.value)),
|
|
2095
2230
|
className: cn(
|
|
2096
2231
|
fieldControlClass,
|
|
2097
|
-
"h-11 px-3
|
|
2232
|
+
"h-11 px-3 tabular-nums [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none",
|
|
2233
|
+
// A number is a value, not an identifier: mono in a studio, beside
|
|
2234
|
+
// the field's mono name, and the page's own face in an app.
|
|
2235
|
+
!isApp && "font-mono"
|
|
2098
2236
|
)
|
|
2099
2237
|
}
|
|
2100
2238
|
),
|
|
@@ -2232,6 +2370,7 @@ function ObjectField({ field, value, onChange, id, error, env }) {
|
|
|
2232
2370
|
const depth = use(StructureDepthContext);
|
|
2233
2371
|
const data = value ?? {};
|
|
2234
2372
|
const label = fieldLabel(field.title, field.name, presentation);
|
|
2373
|
+
const description = shownDescription(field.description, label, ["structured"], presentation);
|
|
2235
2374
|
const grouping = structureGrouping(depth, label.trim() !== "", use(FramedFormContext));
|
|
2236
2375
|
const domId = useFieldDomId(id);
|
|
2237
2376
|
const refused = use(RefusedStructureContext) === id;
|
|
@@ -2261,7 +2400,7 @@ function ObjectField({ field, value, onChange, id, error, env }) {
|
|
|
2261
2400
|
const group = grouping === "none" ? {} : {
|
|
2262
2401
|
role: "group",
|
|
2263
2402
|
"aria-labelledby": nameId,
|
|
2264
|
-
"aria-describedby":
|
|
2403
|
+
"aria-describedby": description ? descriptionId : void 0
|
|
2265
2404
|
};
|
|
2266
2405
|
const section = grouping === "section";
|
|
2267
2406
|
const caption = error && /* @__PURE__ */ jsx("p", { className: "text-[11px] text-destructive", role: "alert", children: error });
|
|
@@ -2271,7 +2410,7 @@ function ObjectField({ field, value, onChange, id, error, env }) {
|
|
|
2271
2410
|
!isApp && /* @__PURE__ */ jsx(ConceptPill, { conceptRef: field.conceptRef, category: "structured" }),
|
|
2272
2411
|
section && caption
|
|
2273
2412
|
] }),
|
|
2274
|
-
|
|
2413
|
+
description && /* @__PURE__ */ jsx(FieldDescription, { id: descriptionId, children: description }),
|
|
2275
2414
|
/* @__PURE__ */ jsxs(
|
|
2276
2415
|
"div",
|
|
2277
2416
|
{
|
|
@@ -2361,6 +2500,7 @@ function firstFocusable(within2) {
|
|
|
2361
2500
|
var NAMED = 3;
|
|
2362
2501
|
function ListFileDrop({ label, formats, shut, onPlace }) {
|
|
2363
2502
|
const s = useFieldStrings();
|
|
2503
|
+
const isApp = useFieldPresentation() === "app";
|
|
2364
2504
|
const hint = acceptLabel(formats);
|
|
2365
2505
|
const accept = useMemo(() => acceptMap(formats), [formats]);
|
|
2366
2506
|
const [notice, setNotice] = useState(null);
|
|
@@ -2409,7 +2549,7 @@ function ListFileDrop({ label, formats, shut, onPlace }) {
|
|
|
2409
2549
|
),
|
|
2410
2550
|
/* @__PURE__ */ jsx(Upload, { className: "h-4 w-4 text-muted-foreground", strokeWidth: 1.75 }),
|
|
2411
2551
|
/* @__PURE__ */ jsx("p", { className: "text-[13px] text-foreground", children: isDragActive ? s.dropFilesToAdd : s.dropFilesOrBrowse }),
|
|
2412
|
-
hint && /* @__PURE__ */ jsx("p", { className:
|
|
2552
|
+
hint && /* @__PURE__ */ jsx("p", { className: smallPrintClass(isApp), children: hint })
|
|
2413
2553
|
]
|
|
2414
2554
|
}
|
|
2415
2555
|
),
|
|
@@ -2569,6 +2709,18 @@ function ListField({ field, value, onChange, id, error, env }) {
|
|
|
2569
2709
|
}
|
|
2570
2710
|
return count;
|
|
2571
2711
|
};
|
|
2712
|
+
const label = fieldLabel(field.title, field.name, presentation);
|
|
2713
|
+
const exactCount = field.itemCount !== void 0 && field.maxItemCount === field.itemCount ? field.itemCount : void 0;
|
|
2714
|
+
const countShown = !isApp || items.length > 0 || exactCount !== void 0;
|
|
2715
|
+
const kinds = ["list", conceptCategory(field.item)];
|
|
2716
|
+
const description = shownDescription(field.description, label, kinds, presentation);
|
|
2717
|
+
const itemDescription = shownItemDescription(
|
|
2718
|
+
field.item.description,
|
|
2719
|
+
label,
|
|
2720
|
+
field.description,
|
|
2721
|
+
kinds,
|
|
2722
|
+
presentation
|
|
2723
|
+
);
|
|
2572
2724
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2573
2725
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
|
|
2574
2726
|
/* @__PURE__ */ jsx(
|
|
@@ -2578,25 +2730,17 @@ function ListField({ field, value, onChange, id, error, env }) {
|
|
|
2578
2730
|
"text-[13px] font-medium leading-none text-foreground",
|
|
2579
2731
|
isApp ? "text-[13.5px]" : "font-mono"
|
|
2580
2732
|
),
|
|
2581
|
-
children:
|
|
2733
|
+
children: label
|
|
2582
2734
|
}
|
|
2583
2735
|
),
|
|
2584
2736
|
!isApp && /* @__PURE__ */ jsx(ConceptPill, { conceptRef: field.conceptRef, category: "list" }),
|
|
2585
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
2586
|
-
shownAsOptional(field) && /* @__PURE__ */ jsx(
|
|
2587
|
-
"span",
|
|
2588
|
-
{
|
|
2589
|
-
className: cn(
|
|
2590
|
-
"ml-auto text-[10px] uppercase tracking-wider text-muted-foreground",
|
|
2591
|
-
!isApp && "font-mono"
|
|
2592
|
-
),
|
|
2593
|
-
children: s.optionalBadge
|
|
2594
|
-
}
|
|
2595
|
-
)
|
|
2737
|
+
countShown && /* @__PURE__ */ jsx("span", { className: smallPrintClass(isApp), children: exactCount !== void 0 ? s.itemsCountOf(items.length, exactCount) : s.itemsCount(items.length) }),
|
|
2738
|
+
shownAsOptional(field) && /* @__PURE__ */ jsx(OptionalMark, {})
|
|
2596
2739
|
] }),
|
|
2597
|
-
|
|
2740
|
+
description && /* @__PURE__ */ jsx(FieldDescription, { children: description }),
|
|
2741
|
+
itemDescription && /* @__PURE__ */ jsx(FieldDescription, { children: itemDescription }),
|
|
2598
2742
|
/* @__PURE__ */ jsxs("div", { ref: rowsRef, className: "space-y-2", children: [
|
|
2599
|
-
items.length === 0 && !dropOffered && /* @__PURE__ */ jsx("p", { className: "rounded-md border border-dashed border-border bg-input/50 px-3 py-4 text-center text-[12px] text-muted-foreground", children: s.noItemsYet }),
|
|
2743
|
+
items.length === 0 && !dropOffered && !isApp && /* @__PURE__ */ jsx("p", { className: "rounded-md border border-dashed border-border bg-input/50 px-3 py-4 text-center text-[12px] text-muted-foreground", children: s.noItemsYet }),
|
|
2600
2744
|
/* @__PURE__ */ jsx(ListDropAreaContext.Provider, { value: dropArea, children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
2601
2745
|
"div",
|
|
2602
2746
|
{
|
|
@@ -2614,7 +2758,8 @@ function ListField({ field, value, onChange, id, error, env }) {
|
|
|
2614
2758
|
"span",
|
|
2615
2759
|
{
|
|
2616
2760
|
className: cn(
|
|
2617
|
-
"shrink-0
|
|
2761
|
+
"shrink-0 text-muted-foreground",
|
|
2762
|
+
isApp ? "text-[12px] tabular-nums" : "font-mono text-[11px]",
|
|
2618
2763
|
structuredRows ? "col-start-1 row-start-1" : "mt-1 w-5 text-center"
|
|
2619
2764
|
),
|
|
2620
2765
|
children: index + 1
|
|
@@ -2657,7 +2802,7 @@ function ListField({ field, value, onChange, id, error, env }) {
|
|
|
2657
2802
|
dropOffered && fileItem && /* @__PURE__ */ jsx("div", { ref: dropRef, children: /* @__PURE__ */ jsx(
|
|
2658
2803
|
ListFileDrop,
|
|
2659
2804
|
{
|
|
2660
|
-
label
|
|
2805
|
+
label,
|
|
2661
2806
|
formats: fileItem.formats,
|
|
2662
2807
|
shut: !dropOpen,
|
|
2663
2808
|
onPlace: placeFiles
|
|
@@ -2670,15 +2815,27 @@ function ListField({ field, value, onChange, id, error, env }) {
|
|
|
2670
2815
|
onClick: addItem,
|
|
2671
2816
|
disabled: env?.disabled || isFull,
|
|
2672
2817
|
className: cn(
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2818
|
+
isApp ? (
|
|
2819
|
+
// A secondary action of the same family as the team's files
|
|
2820
|
+
// row under it, and the field above it.
|
|
2821
|
+
rowActionClass
|
|
2822
|
+
) : [
|
|
2823
|
+
"inline-flex h-9 w-full items-center justify-center gap-1.5 rounded-md border border-dashed border-border text-[13px] text-muted-foreground transition-colors max-sm:h-11",
|
|
2824
|
+
// The edge under the pointer is the accent's, as a selected
|
|
2825
|
+
// pill's is; the fill under it stays neutral.
|
|
2826
|
+
"hover:bg-muted hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
2827
|
+
selectedHoverBorderClass
|
|
2828
|
+
],
|
|
2678
2829
|
focusOutlineClass
|
|
2679
2830
|
),
|
|
2680
2831
|
children: [
|
|
2681
|
-
/* @__PURE__ */ jsx(
|
|
2832
|
+
/* @__PURE__ */ jsx(
|
|
2833
|
+
Plus,
|
|
2834
|
+
{
|
|
2835
|
+
className: cn("h-4 w-4", isApp && "shrink-0 text-muted-foreground"),
|
|
2836
|
+
"aria-hidden": "true"
|
|
2837
|
+
}
|
|
2838
|
+
),
|
|
2682
2839
|
s.addItem
|
|
2683
2840
|
]
|
|
2684
2841
|
}
|
|
@@ -2688,7 +2845,7 @@ function ListField({ field, value, onChange, id, error, env }) {
|
|
|
2688
2845
|
FilePickerEntry,
|
|
2689
2846
|
{
|
|
2690
2847
|
ref: pickerEntryRef,
|
|
2691
|
-
label
|
|
2848
|
+
label,
|
|
2692
2849
|
disabled: env?.disabled || busy || room === 0,
|
|
2693
2850
|
onOpen: () => setPickerOpen(true)
|
|
2694
2851
|
}
|
|
@@ -2854,7 +3011,8 @@ function UnknownField({ field, value, onChange, id, error, disabled }) {
|
|
|
2854
3011
|
title: field.title,
|
|
2855
3012
|
conceptRef: field.conceptRef,
|
|
2856
3013
|
category: "structured",
|
|
2857
|
-
description: field.description
|
|
3014
|
+
description: field.description,
|
|
3015
|
+
hint: s.jsonHint,
|
|
2858
3016
|
required: !shownAsOptional(field),
|
|
2859
3017
|
error,
|
|
2860
3018
|
htmlFor: domId,
|
|
@@ -3208,7 +3366,7 @@ function FillWithExample({
|
|
|
3208
3366
|
},
|
|
3209
3367
|
className: cn(secondaryClass, className),
|
|
3210
3368
|
children: [
|
|
3211
|
-
/* @__PURE__ */ jsx(
|
|
3369
|
+
/* @__PURE__ */ jsx(ClipboardPaste, { className: "size-4 text-muted-foreground", "aria-hidden": "true" }),
|
|
3212
3370
|
s.fillWithExample
|
|
3213
3371
|
]
|
|
3214
3372
|
}
|
|
@@ -4583,11 +4741,11 @@ function useFileNamePrompt() {
|
|
|
4583
4741
|
const asking = useAskFileName();
|
|
4584
4742
|
const [pending, setPending] = useState(null);
|
|
4585
4743
|
const ask = useCallback(
|
|
4586
|
-
(
|
|
4587
|
-
if (!asking) return Promise.resolve(`${
|
|
4744
|
+
(stem3, extension) => {
|
|
4745
|
+
if (!asking) return Promise.resolve(`${stem3}${extension}`);
|
|
4588
4746
|
return new Promise((resolve) => {
|
|
4589
4747
|
setPending({
|
|
4590
|
-
stem:
|
|
4748
|
+
stem: stem3,
|
|
4591
4749
|
extension,
|
|
4592
4750
|
settle: (name) => {
|
|
4593
4751
|
setPending(null);
|
|
@@ -4611,11 +4769,11 @@ function useFileNamePrompt() {
|
|
|
4611
4769
|
) : null;
|
|
4612
4770
|
return { ask, dialog };
|
|
4613
4771
|
}
|
|
4614
|
-
function FileNameDialog({ stem:
|
|
4772
|
+
function FileNameDialog({ stem: stem3, extension, onConfirm, onCancel }) {
|
|
4615
4773
|
const s = useFieldStrings();
|
|
4616
4774
|
const titleId = useId();
|
|
4617
4775
|
const extensionId = useId();
|
|
4618
|
-
const [value, setValue] = useState(
|
|
4776
|
+
const [value, setValue] = useState(stem3);
|
|
4619
4777
|
const panel = useRef(null);
|
|
4620
4778
|
const field = useRef(null);
|
|
4621
4779
|
const pressedBackdrop = useRef(false);
|
|
@@ -7016,8 +7174,8 @@ ${planned.url ?? planned.text}`;
|
|
|
7016
7174
|
{
|
|
7017
7175
|
type: "button",
|
|
7018
7176
|
onClick: async () => {
|
|
7019
|
-
const { stem:
|
|
7020
|
-
const name = await ask(
|
|
7177
|
+
const { stem: stem3, extension } = splitFileName(planned.name);
|
|
7178
|
+
const name = await ask(stem3, extension);
|
|
7021
7179
|
if (name === null) return;
|
|
7022
7180
|
const started = { identity, state: "saving" };
|
|
7023
7181
|
setAttempt(started);
|
|
@@ -8288,7 +8446,7 @@ function ResultNode({
|
|
|
8288
8446
|
const pagePath = location?.path.join(".");
|
|
8289
8447
|
const pageFile = pagePath === void 0 ? void 0 : readStuffFile("markup", unwrapped, pagePath);
|
|
8290
8448
|
const page = pageDownloadShown ? pageFile : void 0;
|
|
8291
|
-
const pdfName = pdfShown && content && pageFile && location ?
|
|
8449
|
+
const pdfName = pdfShown && content && pageFile && location ? stem2(planFileSave(pageFile, { baseName: location.baseName })?.name) : void 0;
|
|
8292
8450
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8293
8451
|
page || pdfName !== void 0 ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
8294
8452
|
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: header }),
|
|
@@ -8506,7 +8664,7 @@ function ResultNode({
|
|
|
8506
8664
|
}
|
|
8507
8665
|
return null;
|
|
8508
8666
|
}
|
|
8509
|
-
function
|
|
8667
|
+
function stem2(name) {
|
|
8510
8668
|
return name === void 0 ? "" : name.replace(/\.[^.]+$/, "");
|
|
8511
8669
|
}
|
|
8512
8670
|
var ALL_VIEWS = ["rendered", "json"];
|
|
@@ -8667,15 +8825,15 @@ function StuffPanel({
|
|
|
8667
8825
|
const only = plan.files.length === 1 ? plan.files[0] : void 0;
|
|
8668
8826
|
const json = plan.files.length > 1 ? plan.files[plan.files.length - 1] : void 0;
|
|
8669
8827
|
if (only) {
|
|
8670
|
-
const { stem:
|
|
8671
|
-
const name2 = await ask(
|
|
8828
|
+
const { stem: stem3, extension } = splitFileName(only.name);
|
|
8829
|
+
const name2 = await ask(stem3, extension);
|
|
8672
8830
|
if (name2 === null) return;
|
|
8673
8831
|
if (name2 !== only.name) plan = { ...plan, files: [{ ...only, name: name2 }] };
|
|
8674
8832
|
} else if (json) {
|
|
8675
|
-
const { stem:
|
|
8676
|
-
const name2 = await ask(
|
|
8833
|
+
const { stem: stem3 } = splitFileName(json.name);
|
|
8834
|
+
const name2 = await ask(stem3, "");
|
|
8677
8835
|
if (name2 === null) return;
|
|
8678
|
-
if (name2 !==
|
|
8836
|
+
if (name2 !== stem3) plan = planStuffSave(field, value, { baseName: name2, ...options });
|
|
8679
8837
|
}
|
|
8680
8838
|
const attempt = {
|
|
8681
8839
|
field,
|
|
@@ -8812,5 +8970,5 @@ function pdfFileName(field, value, baseName) {
|
|
|
8812
8970
|
}
|
|
8813
8971
|
|
|
8814
8972
|
export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EN_FIELD_STRINGS, EnumField, FIELD_STRINGS_BY_LOCALE, FR_FIELD_STRINGS, FieldDomIdProvider, FieldPresentationProvider, FieldRenderer, FieldShell, FieldStringsProvider, FilePicker, FilePickerEntry, FillWithExample, HtmlPreview, ImageField, JsonView, ListField, Markdown, MethodForm, NumberField, ObjectField, OptionalToggle, PdfDownloadButton, ProseField, ResultEnvProvider, ResultField, ResultRoot, SUPPORTED_LOCALES, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StuffViewer, Switch, TextField, ToggleGroup, ToggleGroupItem, UnknownField, actionShadowClass, checkedAccentClass, cn, enumLabeler, fieldControlClass, fieldLabel, fieldStringsFor, focusOutlineClass, headingClass, isThenable, linkTextClass, panelFlatShadowClass, panelRaisedShadowClass, panelSurfaceClass, renderHtmlPdf, resolveHtmlStorageUrls, saveInBrowser, selectedBorderClass, selectedFillClass, selectedFillStrongClass, useFieldDomId, useFieldPresentation, useFieldStrings, useMethodForm, useProseImages, useResolveRendition, useResolveShareUrl, useResolveUrl, useResolvedUrl };
|
|
8815
|
-
//# sourceMappingURL=chunk-
|
|
8816
|
-
//# sourceMappingURL=chunk-
|
|
8973
|
+
//# sourceMappingURL=chunk-TD62R3P6.js.map
|
|
8974
|
+
//# sourceMappingURL=chunk-TD62R3P6.js.map
|