@pipelex/mthds-form 0.20.0 → 0.22.0
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 +1 -1
- package/dist/brand/index.d.ts +109 -1
- package/dist/brand/index.js +113 -1
- package/dist/brand/index.js.map +1 -1
- package/dist/{chunk-CSLDIWB6.js → chunk-5IZWP2X4.js} +339 -69
- package/dist/chunk-5IZWP2X4.js.map +1 -0
- package/dist/field-renderer-lNhtw-Cz.d.ts +215 -0
- package/dist/generative/index.d.ts +1 -1
- package/dist/generative/index.js +21 -5
- package/dist/generative/index.js.map +1 -1
- package/dist/react/index.d.ts +86 -71
- package/dist/react/index.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
- package/dist/chunk-CSLDIWB6.js.map +0 -1
- package/dist/field-renderer-B3g16qZT.d.ts +0 -74
|
@@ -2,7 +2,7 @@ import { planFileSave, planStuffSave, splitFileName, typedFileStem } from './chu
|
|
|
2
2
|
import { seedInputs, closeOptionalStructures, openOptionalStructures } from './chunk-VH5CDQDR.js';
|
|
3
3
|
import { sourceFileValue, roomForChosenFiles, addChosenFiles, chosenFilesAdded } from './chunk-EQJBM3NS.js';
|
|
4
4
|
import { readStuffFile } from './chunk-RRTI7AIR.js';
|
|
5
|
-
import {
|
|
5
|
+
import { apiInputsFromRunValues, sameRunValues, runValuesFromInputs, setValueAtPath } from './chunk-ZX52CQJ4.js';
|
|
6
6
|
import { viewableUrl, isNativeDateNode, isNativeHtmlNode, readHtmlContent, isNativeCompositeNode, readCompositeContent, isNativeValueNode, readDateContent, formatDateContent, readImageContent, readDataUrl, readDocumentContent } from './chunk-CM4KVG53.js';
|
|
7
7
|
import { buildRunFields } from './chunk-ZB4RYUKV.js';
|
|
8
8
|
import { conceptCategory } from './chunk-FABY3DEY.js';
|
|
@@ -566,11 +566,20 @@ function FieldShell({
|
|
|
566
566
|
] });
|
|
567
567
|
}
|
|
568
568
|
|
|
569
|
+
// src/react/brand-ink.ts
|
|
570
|
+
var brandInkClass = "text-[color:var(--brand,var(--primary,hsl(240_5.9%_10%)))]";
|
|
571
|
+
var brandFillInkClass = "text-[color:var(--brand-muted-foreground,var(--brand,var(--primary,hsl(240_5.9%_10%))))]";
|
|
572
|
+
var brandFillClass = "bg-[color:var(--brand-muted,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
|
|
573
|
+
var brandFillSelectedClass = "data-[state=on]:bg-[color:var(--brand-muted,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
|
|
574
|
+
var brandFillStrongClass = "bg-[color:var(--brand-muted,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_15%,transparent))]";
|
|
575
|
+
var brandFocusClass = "focus-visible:border-[color:var(--brand,var(--primary,hsl(240_5.9%_10%)))] focus-visible:ring-[color:color-mix(in_oklab,var(--brand,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
|
|
576
|
+
|
|
569
577
|
// src/react/field-styles.ts
|
|
570
578
|
var fieldControlClass = cn(
|
|
571
579
|
"w-full rounded-md border border-border bg-input text-sm text-foreground",
|
|
572
580
|
"placeholder:text-muted-foreground/70 transition-colors",
|
|
573
|
-
"focus-visible:outline-hidden focus-visible:
|
|
581
|
+
"focus-visible:outline-hidden focus-visible:ring-1",
|
|
582
|
+
brandFocusClass,
|
|
574
583
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
575
584
|
"aria-invalid:border-destructive aria-invalid:ring-destructive/30"
|
|
576
585
|
);
|
|
@@ -1237,6 +1246,20 @@ function isReadableLink(url) {
|
|
|
1237
1246
|
function dataUrlMime(url) {
|
|
1238
1247
|
return DATA_URL_MIME_RE.exec(url)?.[1]?.toLowerCase();
|
|
1239
1248
|
}
|
|
1249
|
+
function isThenable(answer) {
|
|
1250
|
+
return (typeof answer === "object" || typeof answer === "function") && answer !== null && typeof answer.then === "function";
|
|
1251
|
+
}
|
|
1252
|
+
function storedUrlOf(stored) {
|
|
1253
|
+
if (typeof stored === "string") return stored === "" ? void 0 : stored;
|
|
1254
|
+
if (stored === null || typeof stored !== "object") return void 0;
|
|
1255
|
+
const url = stored.url;
|
|
1256
|
+
return typeof url === "string" && url !== "" ? url : void 0;
|
|
1257
|
+
}
|
|
1258
|
+
function describesValue(local, url) {
|
|
1259
|
+
if (local.boundUrl !== void 0) return local.boundUrl === url;
|
|
1260
|
+
if (local.storedUrl !== void 0) return local.storedUrl === url;
|
|
1261
|
+
return !local.awaitingUpload;
|
|
1262
|
+
}
|
|
1240
1263
|
function DocumentField(props) {
|
|
1241
1264
|
return /* @__PURE__ */ jsx(FileField, { ...props, category: "document" });
|
|
1242
1265
|
}
|
|
@@ -1265,6 +1288,9 @@ function FileField({
|
|
|
1265
1288
|
const [typedUrl, setTypedUrl] = useState(null);
|
|
1266
1289
|
const [previewOpen, setPreviewOpen] = useState(false);
|
|
1267
1290
|
const [localPreview, setLocalPreview] = useState(null);
|
|
1291
|
+
const urlInFlight = useRef(void 0);
|
|
1292
|
+
const flightSeen = useRef(false);
|
|
1293
|
+
const localGeneration = useRef(0);
|
|
1268
1294
|
const [resolved, setResolved] = useState(null);
|
|
1269
1295
|
const localUrlRef = useRef(null);
|
|
1270
1296
|
const [pickerOpen, setPickerOpen] = useState(false);
|
|
@@ -1273,6 +1299,7 @@ function FileField({
|
|
|
1273
1299
|
const setLocal = useCallback((next) => {
|
|
1274
1300
|
if (localUrlRef.current) URL.revokeObjectURL(localUrlRef.current);
|
|
1275
1301
|
localUrlRef.current = next?.objectUrl ?? null;
|
|
1302
|
+
localGeneration.current += 1;
|
|
1276
1303
|
setLocalPreview(next);
|
|
1277
1304
|
}, []);
|
|
1278
1305
|
useEffect(() => () => setLocal(null), [setLocal]);
|
|
@@ -1299,10 +1326,27 @@ function FileField({
|
|
|
1299
1326
|
}
|
|
1300
1327
|
setRejected(null);
|
|
1301
1328
|
setDismissedUploadError(null);
|
|
1302
|
-
|
|
1303
|
-
|
|
1329
|
+
const upload = onDropFile(file);
|
|
1330
|
+
const awaitingUpload = isThenable(upload);
|
|
1331
|
+
setLocal({ objectUrl: URL.createObjectURL(file), type: file.type, awaitingUpload });
|
|
1332
|
+
urlInFlight.current = value?.url;
|
|
1333
|
+
flightSeen.current = false;
|
|
1334
|
+
if (!awaitingUpload) return;
|
|
1335
|
+
const generation = localGeneration.current;
|
|
1336
|
+
Promise.resolve(upload).then(
|
|
1337
|
+
(stored) => {
|
|
1338
|
+
if (localGeneration.current !== generation) return;
|
|
1339
|
+
const storedUrl = storedUrlOf(stored);
|
|
1340
|
+
setLocalPreview(
|
|
1341
|
+
(current) => current ? { ...current, awaitingUpload: false, storedUrl } : current
|
|
1342
|
+
);
|
|
1343
|
+
},
|
|
1344
|
+
() => {
|
|
1345
|
+
if (localGeneration.current === generation) setLocal(null);
|
|
1346
|
+
}
|
|
1347
|
+
);
|
|
1304
1348
|
},
|
|
1305
|
-
[formats, setLocal, onDropFile]
|
|
1349
|
+
[formats, setLocal, onDropFile, value?.url]
|
|
1306
1350
|
);
|
|
1307
1351
|
const busy = disabled || uploading;
|
|
1308
1352
|
const {
|
|
@@ -1358,14 +1402,11 @@ function FileField({
|
|
|
1358
1402
|
},
|
|
1359
1403
|
[setLocal, onChange, dismissUploadError]
|
|
1360
1404
|
);
|
|
1361
|
-
const localIsCurrent = !!localPreview && (localPreview
|
|
1362
|
-
const wasUploading = useRef(!!uploading);
|
|
1405
|
+
const localIsCurrent = !!localPreview && describesValue(localPreview, value?.url);
|
|
1363
1406
|
useEffect(() => {
|
|
1364
|
-
const ended = wasUploading.current && !uploading;
|
|
1365
|
-
wasUploading.current = !!uploading;
|
|
1366
1407
|
if (!localPreview || localPreview.boundUrl !== void 0) return;
|
|
1367
|
-
if (failure !== null
|
|
1368
|
-
}, [
|
|
1408
|
+
if (failure !== null) setLocal(null);
|
|
1409
|
+
}, [failure, localPreview, setLocal]);
|
|
1369
1410
|
const lastUrl = useRef(value?.url);
|
|
1370
1411
|
useEffect(() => {
|
|
1371
1412
|
if (lastUrl.current === value?.url) return;
|
|
@@ -1374,12 +1415,30 @@ function FileField({
|
|
|
1374
1415
|
}, [value?.url, uploadError]);
|
|
1375
1416
|
useEffect(() => {
|
|
1376
1417
|
if (!localPreview) return;
|
|
1377
|
-
if (localPreview.boundUrl
|
|
1378
|
-
if (
|
|
1379
|
-
setLocalPreview({ ...localPreview, boundUrl: value.url });
|
|
1418
|
+
if (localPreview.boundUrl !== void 0) {
|
|
1419
|
+
if (value?.url !== localPreview.boundUrl) setLocal(null);
|
|
1380
1420
|
return;
|
|
1381
1421
|
}
|
|
1382
|
-
if (
|
|
1422
|
+
if (uploading) {
|
|
1423
|
+
urlInFlight.current = value?.url;
|
|
1424
|
+
flightSeen.current = true;
|
|
1425
|
+
}
|
|
1426
|
+
if (localPreview.storedUrl !== void 0) {
|
|
1427
|
+
if (value?.url === localPreview.storedUrl) {
|
|
1428
|
+
setLocalPreview({ ...localPreview, boundUrl: localPreview.storedUrl });
|
|
1429
|
+
}
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
if (uploading || localPreview.awaitingUpload) return;
|
|
1433
|
+
if (!value?.url) {
|
|
1434
|
+
if (flightSeen.current) setLocal(null);
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
if (value.url === urlInFlight.current) {
|
|
1438
|
+
setLocal(null);
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
setLocalPreview({ ...localPreview, boundUrl: value.url });
|
|
1383
1442
|
}, [localPreview, value?.url, uploading, setLocal]);
|
|
1384
1443
|
const hasFile = !!value?.url;
|
|
1385
1444
|
const localType = localIsCurrent ? localPreview?.type : void 0;
|
|
@@ -1814,9 +1873,19 @@ function EnumField({ field, value, onChange, id, error, disabled }) {
|
|
|
1814
1873
|
{
|
|
1815
1874
|
value: option,
|
|
1816
1875
|
variant: "outline",
|
|
1817
|
-
className:
|
|
1876
|
+
className: cn(
|
|
1877
|
+
"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]:font-medium data-[state=on]:text-foreground",
|
|
1878
|
+
brandFillSelectedClass
|
|
1879
|
+
),
|
|
1818
1880
|
children: [
|
|
1819
|
-
value === option && /* @__PURE__ */ jsx(
|
|
1881
|
+
value === option && /* @__PURE__ */ jsx(
|
|
1882
|
+
Check,
|
|
1883
|
+
{
|
|
1884
|
+
className: cn("size-3.5", brandFillInkClass),
|
|
1885
|
+
strokeWidth: 2.5,
|
|
1886
|
+
"aria-hidden": "true"
|
|
1887
|
+
}
|
|
1888
|
+
),
|
|
1820
1889
|
labelOf(option)
|
|
1821
1890
|
]
|
|
1822
1891
|
},
|
|
@@ -2083,12 +2152,28 @@ function firstFocusable(within) {
|
|
|
2083
2152
|
}
|
|
2084
2153
|
return null;
|
|
2085
2154
|
}
|
|
2155
|
+
|
|
2156
|
+
// src/react/row-moves.ts
|
|
2157
|
+
function destinationOf(order) {
|
|
2158
|
+
return new Map(order.map((source, index) => [source, index]));
|
|
2159
|
+
}
|
|
2160
|
+
function movedId(id, listId, destination) {
|
|
2161
|
+
const prefix = `${listId}.`;
|
|
2162
|
+
if (!id.startsWith(prefix)) return id;
|
|
2163
|
+
const rest = id.slice(prefix.length);
|
|
2164
|
+
const dot = rest.indexOf(".");
|
|
2165
|
+
const row = dot === -1 ? rest : rest.slice(0, dot);
|
|
2166
|
+
if (!/^\d+$/.test(row)) return id;
|
|
2167
|
+
const index = destination.get(Number(row));
|
|
2168
|
+
if (index === void 0) return void 0;
|
|
2169
|
+
return `${prefix}${index}${dot === -1 ? "" : rest.slice(dot)}`;
|
|
2170
|
+
}
|
|
2086
2171
|
function ListField({ field, value, onChange, id, error, env }) {
|
|
2087
2172
|
const s = useFieldStrings();
|
|
2088
2173
|
const presentation = useFieldPresentation();
|
|
2089
2174
|
const isApp = presentation === "app";
|
|
2090
2175
|
const items = value ?? [];
|
|
2091
|
-
const [rowKeys, setRowKeys] = useRowKeys(items.length);
|
|
2176
|
+
const [rowKeys, setRowKeys] = useRowKeys(items.length, id, env?.rowMoves);
|
|
2092
2177
|
const [pickerOpen, setPickerOpen] = useState(false);
|
|
2093
2178
|
const pickerEntryRef = useRef(null);
|
|
2094
2179
|
const rowsRef = useRef(null);
|
|
@@ -2100,7 +2185,12 @@ function ListField({ field, value, onChange, id, error, env }) {
|
|
|
2100
2185
|
onChange(next);
|
|
2101
2186
|
};
|
|
2102
2187
|
const removeItem = (index) => {
|
|
2103
|
-
setRowKeys((prev) => prev.filter((_, i) => i !== index));
|
|
2188
|
+
if (!env?.rowMoves) setRowKeys((prev) => prev.filter((_, i) => i !== index));
|
|
2189
|
+
const hostRemoves = env?.onRemoveItem;
|
|
2190
|
+
if (hostRemoves) {
|
|
2191
|
+
hostRemoves(id, index);
|
|
2192
|
+
return;
|
|
2193
|
+
}
|
|
2104
2194
|
setStaleErrors((prev) => withRenumberedErrors(prev, id, index, env?.uploadErrors));
|
|
2105
2195
|
onChange(items.filter((_, i) => i !== index));
|
|
2106
2196
|
};
|
|
@@ -2131,7 +2221,7 @@ function ListField({ field, value, onChange, id, error, env }) {
|
|
|
2131
2221
|
next.delete(dropId);
|
|
2132
2222
|
return next;
|
|
2133
2223
|
});
|
|
2134
|
-
drop(dropId, file);
|
|
2224
|
+
return drop(dropId, file);
|
|
2135
2225
|
} : void 0
|
|
2136
2226
|
};
|
|
2137
2227
|
}, [env, staleErrors]);
|
|
@@ -2278,24 +2368,49 @@ function withRenumberedErrors(stale, listId, removed, hostErrors) {
|
|
|
2278
2368
|
}
|
|
2279
2369
|
return next.size === stale.size && [...next].every(([k, m]) => stale.get(k) === m) ? stale : next;
|
|
2280
2370
|
}
|
|
2281
|
-
function useRowKeys(length) {
|
|
2371
|
+
function useRowKeys(length, id, moves) {
|
|
2372
|
+
const latest = moves?.[moves.length - 1]?.seq ?? 0;
|
|
2282
2373
|
const [state, setState] = useState(() => ({
|
|
2283
2374
|
keys: Array.from({ length }, (_, i) => i),
|
|
2284
|
-
next: length
|
|
2375
|
+
next: length,
|
|
2376
|
+
seq: latest,
|
|
2377
|
+
id
|
|
2285
2378
|
}));
|
|
2286
|
-
if (state.keys.length !== length) {
|
|
2287
|
-
setState((prev) =>
|
|
2288
|
-
if (length <= prev.keys.length) return { keys: prev.keys.slice(0, length), next: prev.next };
|
|
2289
|
-
const added = length - prev.keys.length;
|
|
2290
|
-
return {
|
|
2291
|
-
keys: [...prev.keys, ...Array.from({ length: added }, (_, i) => prev.next + i)],
|
|
2292
|
-
next: prev.next + added
|
|
2293
|
-
};
|
|
2294
|
-
});
|
|
2379
|
+
if (state.seq !== latest || state.id !== id || state.keys.length !== length) {
|
|
2380
|
+
setState((prev) => withLength(replayed(prev, moves, latest, id), length));
|
|
2295
2381
|
}
|
|
2296
|
-
const update = (fn) => setState((prev) => ({ keys: fn(prev.keys)
|
|
2382
|
+
const update = (fn) => setState((prev) => ({ ...prev, keys: fn(prev.keys) }));
|
|
2297
2383
|
return [state.keys, update];
|
|
2298
2384
|
}
|
|
2385
|
+
function replayed(state, moves, latest, id) {
|
|
2386
|
+
let { keys, next } = state;
|
|
2387
|
+
let tracked = state.id;
|
|
2388
|
+
for (const move of moves ?? []) {
|
|
2389
|
+
if (move.seq <= state.seq || tracked === void 0) continue;
|
|
2390
|
+
if (move.listId === tracked) {
|
|
2391
|
+
const before = keys;
|
|
2392
|
+
keys = [];
|
|
2393
|
+
for (const source of move.order) {
|
|
2394
|
+
const key = before[source];
|
|
2395
|
+
if (key === void 0) keys.push(next++);
|
|
2396
|
+
else keys.push(key);
|
|
2397
|
+
}
|
|
2398
|
+
} else {
|
|
2399
|
+
tracked = movedId(tracked, move.listId, destinationOf(move.order));
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
return { keys, next, seq: latest, id };
|
|
2403
|
+
}
|
|
2404
|
+
function withLength(state, length) {
|
|
2405
|
+
if (state.keys.length === length) return state;
|
|
2406
|
+
if (length < state.keys.length) return { ...state, keys: state.keys.slice(0, length) };
|
|
2407
|
+
const added = length - state.keys.length;
|
|
2408
|
+
return {
|
|
2409
|
+
...state,
|
|
2410
|
+
keys: [...state.keys, ...Array.from({ length: added }, (_, i) => state.next + i)],
|
|
2411
|
+
next: state.next + added
|
|
2412
|
+
};
|
|
2413
|
+
}
|
|
2299
2414
|
function emptyValue(field) {
|
|
2300
2415
|
switch (field.kind) {
|
|
2301
2416
|
case "boolean":
|
|
@@ -2948,6 +3063,110 @@ function withoutId(ids, id) {
|
|
|
2948
3063
|
next.delete(id);
|
|
2949
3064
|
return next;
|
|
2950
3065
|
}
|
|
3066
|
+
var NO_UPLOADS = /* @__PURE__ */ new Map();
|
|
3067
|
+
var NO_MOVES = [];
|
|
3068
|
+
var NOTHING_HELD = {
|
|
3069
|
+
edited: null,
|
|
3070
|
+
failed: EMPTY_IDS,
|
|
3071
|
+
uploads: NO_UPLOADS,
|
|
3072
|
+
moves: NO_MOVES
|
|
3073
|
+
};
|
|
3074
|
+
function withoutEntry(entries, id) {
|
|
3075
|
+
if (!entries.has(id)) return entries;
|
|
3076
|
+
const next = new Map(entries);
|
|
3077
|
+
next.delete(id);
|
|
3078
|
+
return next;
|
|
3079
|
+
}
|
|
3080
|
+
function fileUrlAt(values, id) {
|
|
3081
|
+
const node = valueAt(values, id);
|
|
3082
|
+
if (node === null || typeof node !== "object") return void 0;
|
|
3083
|
+
const url = ownProp(node, "url");
|
|
3084
|
+
return typeof url === "string" && url !== "" ? url : void 0;
|
|
3085
|
+
}
|
|
3086
|
+
function valueAt(values, id) {
|
|
3087
|
+
let node = values;
|
|
3088
|
+
for (const key of id.split(".")) {
|
|
3089
|
+
if (node === null || typeof node !== "object") return void 0;
|
|
3090
|
+
node = ownProp(node, key);
|
|
3091
|
+
}
|
|
3092
|
+
return node;
|
|
3093
|
+
}
|
|
3094
|
+
function written(held, initial, update) {
|
|
3095
|
+
const before = held.edited ?? initial;
|
|
3096
|
+
const after = update(before);
|
|
3097
|
+
if (after === held.edited) return held;
|
|
3098
|
+
const replaced = [...held.failed].filter((id) => fileUrlAt(before, id) !== fileUrlAt(after, id));
|
|
3099
|
+
if (replaced.length === 0) return { ...held, edited: after };
|
|
3100
|
+
const failed = new Set(held.failed);
|
|
3101
|
+
for (const id of replaced) failed.delete(id);
|
|
3102
|
+
return { ...held, edited: after, failed };
|
|
3103
|
+
}
|
|
3104
|
+
function uploadDropped(held, initial, id, token) {
|
|
3105
|
+
const uploads = new Map(held.uploads);
|
|
3106
|
+
uploads.set(id, { token, over: fileUrlAt(held.edited ?? initial, id) });
|
|
3107
|
+
return { ...held, failed: withoutId(held.failed, id), uploads };
|
|
3108
|
+
}
|
|
3109
|
+
function placeOf(held, token) {
|
|
3110
|
+
for (const entry of held.uploads) if (entry[1].token === token) return entry;
|
|
3111
|
+
return void 0;
|
|
3112
|
+
}
|
|
3113
|
+
function uploadFailed(held, initial, token) {
|
|
3114
|
+
const place = placeOf(held, token);
|
|
3115
|
+
if (!place) return held;
|
|
3116
|
+
const [id, upload] = place;
|
|
3117
|
+
const stillThere = fileUrlAt(held.edited ?? initial, id) === upload.over;
|
|
3118
|
+
return {
|
|
3119
|
+
...held,
|
|
3120
|
+
failed: stillThere ? withId(held.failed, id) : held.failed,
|
|
3121
|
+
uploads: withoutEntry(held.uploads, id)
|
|
3122
|
+
};
|
|
3123
|
+
}
|
|
3124
|
+
function uploadLanded(held, initial, token, value) {
|
|
3125
|
+
const place = placeOf(held, token);
|
|
3126
|
+
if (!place) return held;
|
|
3127
|
+
const [id] = place;
|
|
3128
|
+
const next = written(held, initial, (before) => setValueAtPath(before, id.split("."), value));
|
|
3129
|
+
return { ...next, uploads: withoutEntry(next.uploads, id) };
|
|
3130
|
+
}
|
|
3131
|
+
function rowsMoved(held, initial, listId, order, seq) {
|
|
3132
|
+
const before = held.edited ?? initial;
|
|
3133
|
+
const rows = valueAt(before, listId);
|
|
3134
|
+
if (!Array.isArray(rows)) return held;
|
|
3135
|
+
const sources = order(rows);
|
|
3136
|
+
if (!sources) return held;
|
|
3137
|
+
const after = setValueAtPath(
|
|
3138
|
+
before,
|
|
3139
|
+
listId.split("."),
|
|
3140
|
+
sources.map((source) => rows[source])
|
|
3141
|
+
);
|
|
3142
|
+
const destination = destinationOf(sources);
|
|
3143
|
+
const failed = /* @__PURE__ */ new Set();
|
|
3144
|
+
for (const id of held.failed) {
|
|
3145
|
+
const moved = movedId(id, listId, destination);
|
|
3146
|
+
if (moved !== void 0) failed.add(moved);
|
|
3147
|
+
}
|
|
3148
|
+
const uploads = /* @__PURE__ */ new Map();
|
|
3149
|
+
for (const [id, upload] of held.uploads) {
|
|
3150
|
+
const moved = movedId(id, listId, destination);
|
|
3151
|
+
if (moved !== void 0) uploads.set(moved, upload);
|
|
3152
|
+
}
|
|
3153
|
+
const moves = [...held.moves, { seq, listId, order: sources }];
|
|
3154
|
+
return { edited: after, failed, uploads, moves };
|
|
3155
|
+
}
|
|
3156
|
+
function isRow(rows, index) {
|
|
3157
|
+
return Number.isInteger(index) && index >= 0 && index < rows.length;
|
|
3158
|
+
}
|
|
3159
|
+
function withoutRow(index) {
|
|
3160
|
+
return (rows) => isRow(rows, index) ? rows.map((_, i) => i).filter((i) => i !== index) : null;
|
|
3161
|
+
}
|
|
3162
|
+
function rowMovedTo(from, to) {
|
|
3163
|
+
return (rows) => {
|
|
3164
|
+
if (!isRow(rows, from) || !isRow(rows, to) || from === to) return null;
|
|
3165
|
+
const order = rows.map((_, i) => i).filter((i) => i !== from);
|
|
3166
|
+
order.splice(to, 0, from);
|
|
3167
|
+
return order;
|
|
3168
|
+
};
|
|
3169
|
+
}
|
|
2951
3170
|
function orderFields(fields, order) {
|
|
2952
3171
|
if (!order || order.length === 0) return fields;
|
|
2953
3172
|
const rank = (field) => {
|
|
@@ -2976,39 +3195,71 @@ function useMethodForm({
|
|
|
2976
3195
|
if (typeof initialValues === "function") return initialValues(seedInputs(fields));
|
|
2977
3196
|
return initialValues ?? seedInputs(fields);
|
|
2978
3197
|
}, [initialValues, fields]);
|
|
2979
|
-
const
|
|
3198
|
+
const store = useRef(NOTHING_HELD);
|
|
3199
|
+
const [held, setHeld] = useState(NOTHING_HELD);
|
|
3200
|
+
const commit = useCallback((next) => {
|
|
3201
|
+
if (next === store.current) return;
|
|
3202
|
+
store.current = next;
|
|
3203
|
+
setHeld(next);
|
|
3204
|
+
}, []);
|
|
3205
|
+
const edited = held.edited;
|
|
3206
|
+
const failedUploadIds = held.failed;
|
|
3207
|
+
const uploadingIds = useMemo(
|
|
3208
|
+
() => held.uploads.size === 0 ? EMPTY_IDS : new Set(held.uploads.keys()),
|
|
3209
|
+
[held.uploads]
|
|
3210
|
+
);
|
|
2980
3211
|
const [given, setGiven] = useState(null);
|
|
2981
|
-
const [uploadingIds, setUploadingIds] = useState(EMPTY_IDS);
|
|
2982
|
-
const [failedUploadIds, setFailedUploadIds] = useState(EMPTY_IDS);
|
|
2983
3212
|
const [attempted, setAttempted] = useState(false);
|
|
2984
3213
|
const [resets, setResets] = useState(0);
|
|
2985
|
-
const pendingUploads = useRef(/* @__PURE__ */ new Map());
|
|
2986
3214
|
const uploadCounter = useRef(0);
|
|
3215
|
+
const moveCounter = useRef(0);
|
|
2987
3216
|
const values = edited ?? initial;
|
|
2988
3217
|
const setValues = useCallback(
|
|
2989
3218
|
(next) => {
|
|
2990
3219
|
setGiven((previous) => previous ?? initial);
|
|
2991
|
-
|
|
3220
|
+
commit(
|
|
3221
|
+
written(
|
|
3222
|
+
store.current,
|
|
3223
|
+
initial,
|
|
3224
|
+
(before) => typeof next === "function" ? next(before) : next
|
|
3225
|
+
)
|
|
3226
|
+
);
|
|
2992
3227
|
},
|
|
2993
|
-
[initial]
|
|
3228
|
+
[initial, commit]
|
|
3229
|
+
);
|
|
3230
|
+
const moveRows = useCallback(
|
|
3231
|
+
(listId, order2) => {
|
|
3232
|
+
const seq = moveCounter.current + 1;
|
|
3233
|
+
const next = rowsMoved(store.current, initial, listId, order2, seq);
|
|
3234
|
+
if (next === store.current) return;
|
|
3235
|
+
moveCounter.current = seq;
|
|
3236
|
+
setGiven((previous) => previous ?? initial);
|
|
3237
|
+
commit(next);
|
|
3238
|
+
},
|
|
3239
|
+
[initial, commit]
|
|
3240
|
+
);
|
|
3241
|
+
const removeItem = useCallback(
|
|
3242
|
+
(listId, index) => moveRows(listId, withoutRow(index)),
|
|
3243
|
+
[moveRows]
|
|
3244
|
+
);
|
|
3245
|
+
const moveItem = useCallback(
|
|
3246
|
+
(listId, from, to) => moveRows(listId, rowMovedTo(from, to)),
|
|
3247
|
+
[moveRows]
|
|
3248
|
+
);
|
|
3249
|
+
const reset = useCallback(
|
|
3250
|
+
(next) => {
|
|
3251
|
+
commit({ edited: next ?? null, failed: EMPTY_IDS, uploads: NO_UPLOADS, moves: NO_MOVES });
|
|
3252
|
+
setGiven(next ?? null);
|
|
3253
|
+
setAttempted(false);
|
|
3254
|
+
setResets((count) => count + 1);
|
|
3255
|
+
},
|
|
3256
|
+
[commit]
|
|
2994
3257
|
);
|
|
2995
|
-
const reset = useCallback((next) => {
|
|
2996
|
-
pendingUploads.current.clear();
|
|
2997
|
-
setEdited(next ?? null);
|
|
2998
|
-
setGiven(next ?? null);
|
|
2999
|
-
setUploadingIds(EMPTY_IDS);
|
|
3000
|
-
setFailedUploadIds(EMPTY_IDS);
|
|
3001
|
-
setAttempted(false);
|
|
3002
|
-
setResets((count) => count + 1);
|
|
3003
|
-
}, []);
|
|
3004
3258
|
const dropFile = useMemo(() => {
|
|
3005
3259
|
if (!uploadFile) return void 0;
|
|
3006
3260
|
return (id, file) => {
|
|
3007
3261
|
const token = ++uploadCounter.current;
|
|
3008
|
-
|
|
3009
|
-
const current = () => pendingUploads.current.get(id) === token;
|
|
3010
|
-
setUploadingIds((previous) => withId(previous, id));
|
|
3011
|
-
setFailedUploadIds((previous) => withoutId(previous, id));
|
|
3262
|
+
commit(uploadDropped(store.current, initial, id, token));
|
|
3012
3263
|
const path = id.split(".");
|
|
3013
3264
|
let upload;
|
|
3014
3265
|
try {
|
|
@@ -3016,23 +3267,21 @@ function useMethodForm({
|
|
|
3016
3267
|
} catch (error) {
|
|
3017
3268
|
upload = Promise.reject(error);
|
|
3018
3269
|
}
|
|
3019
|
-
upload.then(
|
|
3020
|
-
(
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
setEdited((previous) => setValueAtPath(previous ?? initial, path, value));
|
|
3025
|
-
},
|
|
3026
|
-
() => {
|
|
3027
|
-
if (current()) setFailedUploadIds((previous) => withId(previous, id));
|
|
3270
|
+
const landed = upload.then((stored) => {
|
|
3271
|
+
if (!placeOf(store.current, token)) {
|
|
3272
|
+
throw new Error(
|
|
3273
|
+
`A newer file, a reset or the removal of its row replaced the upload dropped at "${id}".`
|
|
3274
|
+
);
|
|
3028
3275
|
}
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3276
|
+
const value = typeof stored === "string" ? { url: stored, filename: file.name } : { url: stored.url, filename: stored.filename ?? file.name };
|
|
3277
|
+
setGiven((previous) => previous ?? initial);
|
|
3278
|
+
commit(uploadLanded(store.current, initial, token, value));
|
|
3279
|
+
return value;
|
|
3033
3280
|
});
|
|
3281
|
+
landed.then(void 0, () => commit(uploadFailed(store.current, initial, token)));
|
|
3282
|
+
return landed;
|
|
3034
3283
|
};
|
|
3035
|
-
}, [uploadFile, initial]);
|
|
3284
|
+
}, [uploadFile, initial, commit]);
|
|
3036
3285
|
const readiness = useMemo(() => computeReadiness(fields, values), [fields, values]);
|
|
3037
3286
|
const inputs = useMemo(
|
|
3038
3287
|
() => apiInputsFromRunValues(values, fields, contract.inputs),
|
|
@@ -3058,6 +3307,9 @@ function useMethodForm({
|
|
|
3058
3307
|
attempted,
|
|
3059
3308
|
touched,
|
|
3060
3309
|
setValues,
|
|
3310
|
+
removeItem,
|
|
3311
|
+
moveItem,
|
|
3312
|
+
rowMoves: held.moves,
|
|
3061
3313
|
reset,
|
|
3062
3314
|
attempt,
|
|
3063
3315
|
resets,
|
|
@@ -3093,6 +3345,8 @@ function MethodFormFields({
|
|
|
3093
3345
|
fields,
|
|
3094
3346
|
values,
|
|
3095
3347
|
setValues,
|
|
3348
|
+
removeItem,
|
|
3349
|
+
rowMoves,
|
|
3096
3350
|
reset,
|
|
3097
3351
|
attempted,
|
|
3098
3352
|
touched,
|
|
@@ -3113,11 +3367,27 @@ function MethodFormFields({
|
|
|
3113
3367
|
onDropFile: dropFile,
|
|
3114
3368
|
uploadingIds,
|
|
3115
3369
|
uploadErrors,
|
|
3370
|
+
// A list's remove button goes through the form, which carries a failed
|
|
3371
|
+
// upload, or one in flight, along with the rows it renumbers, and logs
|
|
3372
|
+
// the move for every list to move its rows' identities the same way,
|
|
3373
|
+
// whether the button or the host moved them.
|
|
3374
|
+
onRemoveItem: removeItem,
|
|
3375
|
+
rowMoves,
|
|
3116
3376
|
allowUrl,
|
|
3117
3377
|
resolveUrl,
|
|
3118
3378
|
fileSource
|
|
3119
3379
|
}),
|
|
3120
|
-
[
|
|
3380
|
+
[
|
|
3381
|
+
disabled,
|
|
3382
|
+
dropFile,
|
|
3383
|
+
uploadingIds,
|
|
3384
|
+
uploadErrors,
|
|
3385
|
+
removeItem,
|
|
3386
|
+
rowMoves,
|
|
3387
|
+
allowUrl,
|
|
3388
|
+
resolveUrl,
|
|
3389
|
+
fileSource
|
|
3390
|
+
]
|
|
3121
3391
|
);
|
|
3122
3392
|
const folds = (field) => {
|
|
3123
3393
|
const value = ownProp(values, field.name);
|
|
@@ -6197,6 +6467,6 @@ function pdfFileName(field, value, baseName) {
|
|
|
6197
6467
|
return name === void 0 ? "" : name.replace(/\.[^.]+$/, "");
|
|
6198
6468
|
}
|
|
6199
6469
|
|
|
6200
|
-
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, cn, fieldControlClass, fieldStringsFor, humanizeFieldName, renderHtmlPdf, resolveHtmlStorageUrls, saveInBrowser, useFieldDomId, useFieldPresentation, useFieldStrings, useMethodForm, useProseImages, useResolveShareUrl, useResolveUrl, useResolvedUrl };
|
|
6201
|
-
//# sourceMappingURL=chunk-
|
|
6202
|
-
//# sourceMappingURL=chunk-
|
|
6470
|
+
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, brandFillClass, brandFillInkClass, brandFillStrongClass, brandInkClass, cn, fieldControlClass, fieldStringsFor, humanizeFieldName, renderHtmlPdf, resolveHtmlStorageUrls, saveInBrowser, useFieldDomId, useFieldPresentation, useFieldStrings, useMethodForm, useProseImages, useResolveShareUrl, useResolveUrl, useResolvedUrl };
|
|
6471
|
+
//# sourceMappingURL=chunk-5IZWP2X4.js.map
|
|
6472
|
+
//# sourceMappingURL=chunk-5IZWP2X4.js.map
|