@dmitryvim/form-builder 0.3.0 → 0.3.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/browser/formbuilder.min.js +150 -120
- package/dist/browser/formbuilder.v0.3.1.min.js +1441 -0
- package/dist/cjs/index.cjs +330 -108
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +325 -107
- package/dist/esm/index.js.map +1 -1
- package/dist/form-builder.js +150 -120
- package/dist/types/components/file/library.d.ts +40 -16
- package/dist/types/components/file/upload.d.ts +111 -2
- package/dist/types/utils/styles.d.ts +9 -1
- package/package.json +1 -1
- package/dist/browser/formbuilder.v0.3.0.min.js +0 -1411
package/dist/cjs/index.cjs
CHANGED
|
@@ -443,6 +443,36 @@ function ensureThemingHooks(doc) {
|
|
|
443
443
|
color: var(--fb-error-color);
|
|
444
444
|
background-color: var(--fb-background-hover-color);
|
|
445
445
|
}
|
|
446
|
+
/* Prefill-suggestion pills rendered by createPrefillHints. Outline pill at rest,
|
|
447
|
+
soft-fill on hover, solid-fill when selected. All colors flow from the active
|
|
448
|
+
theme \u2014 consumers don't need to ship their own CSS. */
|
|
449
|
+
.fb-prefill-hint {
|
|
450
|
+
padding: 0.25rem 0.625rem;
|
|
451
|
+
border: var(--fb-border-width) solid var(--fb-primary-color);
|
|
452
|
+
border-radius: 9999px;
|
|
453
|
+
background: var(--fb-background-color);
|
|
454
|
+
color: var(--fb-primary-color);
|
|
455
|
+
font-size: var(--fb-font-size-small);
|
|
456
|
+
font-weight: var(--fb-font-weight-medium);
|
|
457
|
+
font-family: var(--fb-font-family);
|
|
458
|
+
cursor: pointer;
|
|
459
|
+
transition: background-color var(--fb-transition-duration), border-color var(--fb-transition-duration), color var(--fb-transition-duration);
|
|
460
|
+
}
|
|
461
|
+
.fb-prefill-hint:hover {
|
|
462
|
+
background: var(--fb-primary-soft-color);
|
|
463
|
+
border-color: var(--fb-primary-hover-color);
|
|
464
|
+
color: var(--fb-primary-hover-color);
|
|
465
|
+
}
|
|
466
|
+
.fb-prefill-hint:focus-visible {
|
|
467
|
+
outline: var(--fb-focus-ring-width) solid var(--fb-focus-ring-color);
|
|
468
|
+
outline-offset: 2px;
|
|
469
|
+
}
|
|
470
|
+
.fb-prefill-hint[aria-pressed="true"],
|
|
471
|
+
.fb-prefill-hint.active {
|
|
472
|
+
background: var(--fb-primary-color);
|
|
473
|
+
color: #ffffff;
|
|
474
|
+
border-color: var(--fb-primary-color);
|
|
475
|
+
}
|
|
446
476
|
`;
|
|
447
477
|
doc.head.appendChild(style);
|
|
448
478
|
}
|
|
@@ -454,7 +484,9 @@ function applyAutoExpand(textarea) {
|
|
|
454
484
|
const resize = () => {
|
|
455
485
|
if (!textarea.isConnected) return;
|
|
456
486
|
textarea.style.height = "0";
|
|
457
|
-
|
|
487
|
+
const cs = getComputedStyle(textarea);
|
|
488
|
+
const borderY = parseFloat(cs.borderTopWidth || "0") + parseFloat(cs.borderBottomWidth || "0");
|
|
489
|
+
textarea.style.height = `${textarea.scrollHeight + borderY}px`;
|
|
458
490
|
};
|
|
459
491
|
textarea.addEventListener("input", resize);
|
|
460
492
|
setTimeout(() => {
|
|
@@ -4275,16 +4307,26 @@ function filterAndSlice(allFiles, currentCount, constraints, state) {
|
|
|
4275
4307
|
}
|
|
4276
4308
|
return { accepted, errorMessage: errorParts.join(" \u2022 ") };
|
|
4277
4309
|
}
|
|
4278
|
-
async function uploadBatch(
|
|
4310
|
+
async function uploadBatch(opts) {
|
|
4279
4311
|
var _a;
|
|
4280
|
-
|
|
4312
|
+
const {
|
|
4313
|
+
accepted,
|
|
4314
|
+
listEl,
|
|
4315
|
+
state,
|
|
4316
|
+
shouldHideAddTile,
|
|
4317
|
+
buildSuccessTile,
|
|
4318
|
+
prepareForUpload
|
|
4319
|
+
} = opts;
|
|
4320
|
+
if (listEl && shouldHideAddTile) {
|
|
4281
4321
|
const tilesWrap = ensureTilesWrap(listEl);
|
|
4282
4322
|
const addTile = (_a = tilesWrap.querySelector(".fb-multi-add-tile-js")) != null ? _a : tilesWrap.querySelector(".fb-tile-add");
|
|
4283
4323
|
if (addTile) addTile.style.display = "none";
|
|
4284
4324
|
}
|
|
4325
|
+
prepareForUpload == null ? void 0 : prepareForUpload();
|
|
4326
|
+
const orderedIds = new Array(accepted.length).fill(null);
|
|
4285
4327
|
const failures = [];
|
|
4286
4328
|
await Promise.allSettled(
|
|
4287
|
-
accepted.map(async (file) => {
|
|
4329
|
+
accepted.map(async (file, index) => {
|
|
4288
4330
|
const placeholder = createUploadingTile(file.name, state);
|
|
4289
4331
|
if (listEl) {
|
|
4290
4332
|
const tilesWrap = ensureTilesWrap(listEl);
|
|
@@ -4297,20 +4339,24 @@ async function uploadBatch(accepted, resourceIds, listEl, state) {
|
|
|
4297
4339
|
type: file.type,
|
|
4298
4340
|
size: file.size,
|
|
4299
4341
|
uploadedAt: /* @__PURE__ */ new Date(),
|
|
4300
|
-
file
|
|
4342
|
+
file
|
|
4301
4343
|
});
|
|
4302
|
-
|
|
4344
|
+
orderedIds[index] = rid;
|
|
4345
|
+
if (buildSuccessTile && placeholder.parentNode) {
|
|
4346
|
+
placeholder.replaceWith(buildSuccessTile(rid));
|
|
4347
|
+
} else {
|
|
4348
|
+
placeholder.remove();
|
|
4349
|
+
}
|
|
4303
4350
|
} catch (err) {
|
|
4304
4351
|
const wrapped = err instanceof Error ? err : new Error(String(err));
|
|
4305
4352
|
const cause = wrapped.cause;
|
|
4306
4353
|
const root = cause instanceof Error ? cause : cause !== void 0 ? new Error(String(cause)) : wrapped;
|
|
4307
4354
|
failures.push({ file, error: root });
|
|
4308
|
-
} finally {
|
|
4309
4355
|
placeholder.remove();
|
|
4310
4356
|
}
|
|
4311
4357
|
})
|
|
4312
4358
|
);
|
|
4313
|
-
return { failures };
|
|
4359
|
+
return { failures, orderedIds };
|
|
4314
4360
|
}
|
|
4315
4361
|
function buildBatchErrorMessage(filterError, failures, state) {
|
|
4316
4362
|
if (failures.length === 0) return filterError;
|
|
@@ -4322,69 +4368,72 @@ function buildBatchErrorMessage(filterError, failures, state) {
|
|
|
4322
4368
|
).join(" \u2022 ");
|
|
4323
4369
|
return filterError ? `${filterError} \u2022 ${uploadMsg}` : uploadMsg;
|
|
4324
4370
|
}
|
|
4325
|
-
function
|
|
4371
|
+
async function runMultiFileBatch(opts, files, listEl, errorTarget) {
|
|
4372
|
+
const {
|
|
4373
|
+
resourceIds,
|
|
4374
|
+
state,
|
|
4375
|
+
updateCallback,
|
|
4376
|
+
constraints,
|
|
4377
|
+
pathKey,
|
|
4378
|
+
instance,
|
|
4379
|
+
buildSuccessTile,
|
|
4380
|
+
prepareForUpload,
|
|
4381
|
+
coordinator
|
|
4382
|
+
} = opts;
|
|
4383
|
+
const { accepted, errorMessage } = filterAndSlice(
|
|
4384
|
+
files,
|
|
4385
|
+
coordinator.getOccupiedCount(),
|
|
4386
|
+
constraints,
|
|
4387
|
+
state
|
|
4388
|
+
);
|
|
4389
|
+
if (errorTarget) {
|
|
4390
|
+
if (errorMessage) showFileError(errorTarget, errorMessage);
|
|
4391
|
+
else clearFileError(errorTarget);
|
|
4392
|
+
}
|
|
4393
|
+
const handle = coordinator.beginBatch(accepted.length);
|
|
4394
|
+
const shouldHideAddTile = coordinator.getOccupiedCount() >= constraints.maxCount;
|
|
4395
|
+
const { failures, orderedIds } = await uploadBatch({
|
|
4396
|
+
accepted,
|
|
4397
|
+
listEl,
|
|
4398
|
+
state,
|
|
4399
|
+
shouldHideAddTile,
|
|
4400
|
+
buildSuccessTile,
|
|
4401
|
+
prepareForUpload
|
|
4402
|
+
});
|
|
4403
|
+
handle.setResults(orderedIds);
|
|
4404
|
+
if (instance && pathKey && !state.config.readonly) {
|
|
4405
|
+
instance.triggerOnChange(pathKey, resourceIds);
|
|
4406
|
+
}
|
|
4407
|
+
const { wasLast } = handle.end();
|
|
4408
|
+
if (wasLast) updateCallback();
|
|
4409
|
+
if (errorTarget) {
|
|
4410
|
+
const combined = buildBatchErrorMessage(errorMessage, failures, state);
|
|
4411
|
+
if (combined) showFileError(errorTarget, combined);
|
|
4412
|
+
else clearFileError(errorTarget);
|
|
4413
|
+
}
|
|
4414
|
+
}
|
|
4415
|
+
function setupFilesDropHandler(opts) {
|
|
4416
|
+
const { filesContainer } = opts;
|
|
4326
4417
|
setupDragAndDrop(filesContainer, async (files) => {
|
|
4327
4418
|
var _a;
|
|
4328
|
-
const { accepted, errorMessage } = filterAndSlice(
|
|
4329
|
-
Array.from(files),
|
|
4330
|
-
resourceIds.length,
|
|
4331
|
-
constraints,
|
|
4332
|
-
state
|
|
4333
|
-
);
|
|
4334
|
-
if (errorMessage) {
|
|
4335
|
-
showFileError(filesContainer, errorMessage);
|
|
4336
|
-
} else {
|
|
4337
|
-
clearFileError(filesContainer);
|
|
4338
|
-
}
|
|
4339
4419
|
const list = (_a = filesContainer.querySelector(".files-list")) != null ? _a : filesContainer;
|
|
4340
|
-
|
|
4341
|
-
const combined = buildBatchErrorMessage(errorMessage, failures, state);
|
|
4342
|
-
if (combined) {
|
|
4343
|
-
showFileError(filesContainer, combined);
|
|
4344
|
-
} else {
|
|
4345
|
-
clearFileError(filesContainer);
|
|
4346
|
-
}
|
|
4347
|
-
updateCallback();
|
|
4348
|
-
if (instance && pathKey && !state.config.readonly) {
|
|
4349
|
-
instance.triggerOnChange(pathKey, resourceIds);
|
|
4350
|
-
}
|
|
4420
|
+
await runMultiFileBatch(opts, Array.from(files), list, filesContainer);
|
|
4351
4421
|
});
|
|
4352
4422
|
}
|
|
4353
|
-
function setupFilesPickerHandler(
|
|
4423
|
+
function setupFilesPickerHandler(opts) {
|
|
4424
|
+
const { filesPicker } = opts;
|
|
4354
4425
|
filesPicker.onchange = async () => {
|
|
4426
|
+
var _a, _b;
|
|
4355
4427
|
if (!filesPicker.files) return;
|
|
4356
|
-
const wrapperEl = filesPicker.closest("[data-files-wrapper]")
|
|
4357
|
-
const
|
|
4428
|
+
const wrapperEl = (_a = filesPicker.closest("[data-files-wrapper]")) != null ? _a : filesPicker.parentElement;
|
|
4429
|
+
const listEl = (_b = wrapperEl == null ? void 0 : wrapperEl.querySelector(".files-list")) != null ? _b : null;
|
|
4430
|
+
await runMultiFileBatch(
|
|
4431
|
+
opts,
|
|
4358
4432
|
Array.from(filesPicker.files),
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
state
|
|
4362
|
-
);
|
|
4363
|
-
if (errorMessage && wrapperEl) {
|
|
4364
|
-
showFileError(wrapperEl, errorMessage);
|
|
4365
|
-
} else if (wrapperEl) {
|
|
4366
|
-
clearFileError(wrapperEl);
|
|
4367
|
-
}
|
|
4368
|
-
const listEl = wrapperEl == null ? void 0 : wrapperEl.querySelector(".files-list");
|
|
4369
|
-
const { failures } = await uploadBatch(
|
|
4370
|
-
accepted,
|
|
4371
|
-
resourceIds,
|
|
4372
|
-
listEl != null ? listEl : null,
|
|
4373
|
-
state
|
|
4433
|
+
listEl,
|
|
4434
|
+
wrapperEl
|
|
4374
4435
|
);
|
|
4375
|
-
if (wrapperEl) {
|
|
4376
|
-
const combined = buildBatchErrorMessage(errorMessage, failures, state);
|
|
4377
|
-
if (combined) {
|
|
4378
|
-
showFileError(wrapperEl, combined);
|
|
4379
|
-
} else {
|
|
4380
|
-
clearFileError(wrapperEl);
|
|
4381
|
-
}
|
|
4382
|
-
}
|
|
4383
|
-
updateCallback();
|
|
4384
4436
|
filesPicker.value = "";
|
|
4385
|
-
if (instance && pathKey && !state.config.readonly) {
|
|
4386
|
-
instance.triggerOnChange(pathKey, resourceIds);
|
|
4387
|
-
}
|
|
4388
4437
|
};
|
|
4389
4438
|
}
|
|
4390
4439
|
|
|
@@ -4426,16 +4475,6 @@ function validatePickedResource(resource, allowedExtensions, allowedMimes, maxSi
|
|
|
4426
4475
|
}
|
|
4427
4476
|
return null;
|
|
4428
4477
|
}
|
|
4429
|
-
function readCurrentResourceIds(wrapper) {
|
|
4430
|
-
const raw = wrapper.dataset.resourceIds;
|
|
4431
|
-
if (!raw) return [];
|
|
4432
|
-
try {
|
|
4433
|
-
const parsed = JSON.parse(raw);
|
|
4434
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
4435
|
-
} catch {
|
|
4436
|
-
return [];
|
|
4437
|
-
}
|
|
4438
|
-
}
|
|
4439
4478
|
function registerPickedResource(resource, state) {
|
|
4440
4479
|
var _a;
|
|
4441
4480
|
const existing = state.resourceIndex.get(resource.resourceId);
|
|
@@ -4451,14 +4490,28 @@ function extractPickerError(error, state) {
|
|
|
4451
4490
|
if (error instanceof Error && error.message) return error.message;
|
|
4452
4491
|
return t("pickerError", state);
|
|
4453
4492
|
}
|
|
4454
|
-
async function handleLibraryPickMulti(
|
|
4493
|
+
async function handleLibraryPickMulti(opts) {
|
|
4455
4494
|
var _a;
|
|
4495
|
+
const {
|
|
4496
|
+
state,
|
|
4497
|
+
element,
|
|
4498
|
+
wrapper,
|
|
4499
|
+
fieldPath,
|
|
4500
|
+
resourceIds,
|
|
4501
|
+
maxCount,
|
|
4502
|
+
updateCallback,
|
|
4503
|
+
instance,
|
|
4504
|
+
coordinator,
|
|
4505
|
+
list,
|
|
4506
|
+
buildSuccessTile
|
|
4507
|
+
} = opts;
|
|
4456
4508
|
if (!state.config.pickExistingFiles) return;
|
|
4457
4509
|
const allowedExtensions = getAllowedExtensions(element.accept);
|
|
4458
4510
|
const allowedMimes = getAllowedMimes(element.accept);
|
|
4459
4511
|
const maxSizeMB = (_a = element.maxSize) != null ? _a : Infinity;
|
|
4460
|
-
const
|
|
4461
|
-
const
|
|
4512
|
+
const knownRids = coordinator.getAllKnownRids();
|
|
4513
|
+
const existingSet = new Set(knownRids);
|
|
4514
|
+
const remaining = maxCount === Infinity ? Infinity : Math.max(0, maxCount - coordinator.getOccupiedCount());
|
|
4462
4515
|
let picked;
|
|
4463
4516
|
try {
|
|
4464
4517
|
picked = await state.config.pickExistingFiles({
|
|
@@ -4467,14 +4520,15 @@ async function handleLibraryPickMulti(state, element, wrapper, fieldPath, resour
|
|
|
4467
4520
|
accept: buildAcceptContext(element),
|
|
4468
4521
|
maxSizeMB: maxSizeMB === Infinity ? void 0 : maxSizeMB,
|
|
4469
4522
|
remainingSlots: remaining === Infinity ? void 0 : remaining,
|
|
4470
|
-
|
|
4523
|
+
// Hand the host every rid that's already selected (committed or
|
|
4524
|
+
// staged) so it can grey them out or filter them.
|
|
4525
|
+
selectedResourceIds: knownRids
|
|
4471
4526
|
});
|
|
4472
4527
|
} catch (error) {
|
|
4473
4528
|
showFileError(wrapper, extractPickerError(error, state));
|
|
4474
4529
|
return;
|
|
4475
4530
|
}
|
|
4476
4531
|
if (picked.length === 0) return;
|
|
4477
|
-
const existingSet = new Set(currentIds);
|
|
4478
4532
|
const seen = /* @__PURE__ */ new Set();
|
|
4479
4533
|
const deduped = picked.filter((r) => {
|
|
4480
4534
|
if (existingSet.has(r.resourceId)) return false;
|
|
@@ -4492,10 +4546,18 @@ async function handleLibraryPickMulti(state, element, wrapper, fieldPath, resour
|
|
|
4492
4546
|
);
|
|
4493
4547
|
return err === null;
|
|
4494
4548
|
});
|
|
4495
|
-
const freshRemaining = maxCount === Infinity ? validItems.length : Math.max(0, maxCount -
|
|
4549
|
+
const freshRemaining = maxCount === Infinity ? validItems.length : Math.max(0, maxCount - coordinator.getOccupiedCount());
|
|
4496
4550
|
const accepted = validItems.slice(0, freshRemaining);
|
|
4497
4551
|
const skipped = validItems.length - accepted.length;
|
|
4498
|
-
if (accepted.length === 0)
|
|
4552
|
+
if (accepted.length === 0) {
|
|
4553
|
+
if (skipped > 0) {
|
|
4554
|
+
showFileError(
|
|
4555
|
+
wrapper,
|
|
4556
|
+
t("filesLimitExceeded", state, { skipped, max: maxCount })
|
|
4557
|
+
);
|
|
4558
|
+
}
|
|
4559
|
+
return;
|
|
4560
|
+
}
|
|
4499
4561
|
clearFileError(wrapper);
|
|
4500
4562
|
if (skipped > 0) {
|
|
4501
4563
|
showFileError(
|
|
@@ -4505,13 +4567,22 @@ async function handleLibraryPickMulti(state, element, wrapper, fieldPath, resour
|
|
|
4505
4567
|
}
|
|
4506
4568
|
for (const resource of accepted) {
|
|
4507
4569
|
registerPickedResource(resource, state);
|
|
4508
|
-
resourceIds.push(resource.resourceId);
|
|
4509
4570
|
}
|
|
4510
|
-
|
|
4511
|
-
|
|
4571
|
+
const acceptedIds = accepted.map((r) => r.resourceId);
|
|
4572
|
+
const handle = coordinator.beginBatch(accepted.length);
|
|
4573
|
+
handle.setResults(acceptedIds);
|
|
4512
4574
|
if (!state.config.readonly) {
|
|
4513
4575
|
instance.triggerOnChange(fieldPath, resourceIds);
|
|
4514
4576
|
}
|
|
4577
|
+
const { wasLast } = handle.end();
|
|
4578
|
+
if (wasLast) {
|
|
4579
|
+
updateCallback();
|
|
4580
|
+
} else {
|
|
4581
|
+
const tilesWrap = ensureTilesWrap(list);
|
|
4582
|
+
for (const rid of acceptedIds) {
|
|
4583
|
+
tilesWrap.appendChild(buildSuccessTile(rid));
|
|
4584
|
+
}
|
|
4585
|
+
}
|
|
4515
4586
|
}
|
|
4516
4587
|
async function handleLibraryPickSingle(state, element, container, fileWrapper, pathKey, fieldPath, renderCallback, instance) {
|
|
4517
4588
|
var _a, _b;
|
|
@@ -4839,6 +4910,14 @@ function buildMetaDot() {
|
|
|
4839
4910
|
return dot;
|
|
4840
4911
|
}
|
|
4841
4912
|
var gridResizeObservers = /* @__PURE__ */ new WeakMap();
|
|
4913
|
+
function disposePlaceholdersForUpload(container) {
|
|
4914
|
+
const observer = gridResizeObservers.get(container);
|
|
4915
|
+
if (observer) {
|
|
4916
|
+
observer.disconnect();
|
|
4917
|
+
gridResizeObservers.delete(container);
|
|
4918
|
+
}
|
|
4919
|
+
container.querySelectorAll(".fb-multi-placeholder").forEach((p) => p.remove());
|
|
4920
|
+
}
|
|
4842
4921
|
function renderResourcePills(opts) {
|
|
4843
4922
|
var _a;
|
|
4844
4923
|
const {
|
|
@@ -5193,16 +5272,19 @@ function setupMultiFileEditMode(element, ctx, wrapper, pathKey, maxFiles) {
|
|
|
5193
5272
|
filesPicker.click();
|
|
5194
5273
|
};
|
|
5195
5274
|
const onLibraryPick = state.config.pickExistingFiles && !element.disableLibrary ? () => {
|
|
5196
|
-
handleLibraryPickMulti(
|
|
5275
|
+
handleLibraryPickMulti({
|
|
5197
5276
|
state,
|
|
5198
5277
|
element,
|
|
5199
|
-
filesWrapper,
|
|
5200
|
-
pathKey,
|
|
5201
|
-
initialFiles,
|
|
5202
|
-
maxFiles,
|
|
5203
|
-
updateFilesDisplay,
|
|
5204
|
-
ctx.instance
|
|
5205
|
-
|
|
5278
|
+
wrapper: filesWrapper,
|
|
5279
|
+
fieldPath: pathKey,
|
|
5280
|
+
resourceIds: initialFiles,
|
|
5281
|
+
maxCount: maxFiles,
|
|
5282
|
+
updateCallback: updateFilesDisplay,
|
|
5283
|
+
instance: ctx.instance,
|
|
5284
|
+
coordinator,
|
|
5285
|
+
list,
|
|
5286
|
+
buildSuccessTile
|
|
5287
|
+
}).catch((err) => {
|
|
5206
5288
|
console.error("Library pick failed:", err);
|
|
5207
5289
|
});
|
|
5208
5290
|
} : null;
|
|
@@ -5213,41 +5295,160 @@ function setupMultiFileEditMode(element, ctx, wrapper, pathKey, maxFiles) {
|
|
|
5213
5295
|
rids: initialFiles,
|
|
5214
5296
|
state,
|
|
5215
5297
|
onRemove: currentlyReadonly ? null : (ridToRemove) => {
|
|
5216
|
-
var _a2;
|
|
5298
|
+
var _a2, _b2;
|
|
5217
5299
|
releaseLocalFileUrl((_a2 = state.resourceIndex.get(ridToRemove)) == null ? void 0 : _a2.file);
|
|
5218
5300
|
const index = initialFiles.indexOf(ridToRemove);
|
|
5219
5301
|
if (index > -1) initialFiles.splice(index, 1);
|
|
5220
|
-
|
|
5302
|
+
if (coordinator.hasInFlightBatches()) {
|
|
5303
|
+
pendingRemovals.add(ridToRemove);
|
|
5304
|
+
(_b2 = list.querySelector(`[data-resource-id="${ridToRemove}"]`)) == null ? void 0 : _b2.remove();
|
|
5305
|
+
filesWrapper.dataset.resourceIds = JSON.stringify(initialFiles);
|
|
5306
|
+
} else {
|
|
5307
|
+
updateFilesDisplay();
|
|
5308
|
+
}
|
|
5309
|
+
if (ctx.instance && pathKey && !state.config.readonly) {
|
|
5310
|
+
ctx.instance.triggerOnChange(pathKey, initialFiles);
|
|
5311
|
+
}
|
|
5221
5312
|
},
|
|
5222
5313
|
maxCount: maxFiles < Infinity ? maxFiles : void 0,
|
|
5223
5314
|
isReadonly: currentlyReadonly,
|
|
5224
5315
|
onLibraryPick: currentlyReadonly ? null : onLibraryPick,
|
|
5225
5316
|
element,
|
|
5226
5317
|
onClearAll: currentlyReadonly ? void 0 : () => {
|
|
5318
|
+
var _a2, _b2;
|
|
5319
|
+
for (const rid of initialFiles) {
|
|
5320
|
+
releaseLocalFileUrl((_a2 = state.resourceIndex.get(rid)) == null ? void 0 : _a2.file);
|
|
5321
|
+
}
|
|
5227
5322
|
initialFiles.splice(0);
|
|
5228
|
-
|
|
5323
|
+
if (coordinator.hasInFlightBatches()) {
|
|
5324
|
+
const visibleTiles = list.querySelectorAll("[data-resource-id]");
|
|
5325
|
+
for (const tile of visibleTiles) {
|
|
5326
|
+
const rid = tile.dataset.resourceId;
|
|
5327
|
+
if (rid) {
|
|
5328
|
+
releaseLocalFileUrl((_b2 = state.resourceIndex.get(rid)) == null ? void 0 : _b2.file);
|
|
5329
|
+
pendingRemovals.add(rid);
|
|
5330
|
+
}
|
|
5331
|
+
tile.remove();
|
|
5332
|
+
}
|
|
5333
|
+
filesWrapper.dataset.resourceIds = JSON.stringify(initialFiles);
|
|
5334
|
+
} else {
|
|
5335
|
+
updateFilesDisplay();
|
|
5336
|
+
}
|
|
5337
|
+
if (ctx.instance && pathKey && !state.config.readonly) {
|
|
5338
|
+
ctx.instance.triggerOnChange(pathKey, initialFiles);
|
|
5339
|
+
}
|
|
5229
5340
|
},
|
|
5230
5341
|
openPicker
|
|
5231
5342
|
});
|
|
5232
5343
|
}
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5344
|
+
let inFlightFiles = 0;
|
|
5345
|
+
let activeBatches = 0;
|
|
5346
|
+
let nextBatchOrdinal = 0;
|
|
5347
|
+
let nextCommitOrdinal = 0;
|
|
5348
|
+
const stagedResults = /* @__PURE__ */ new Map();
|
|
5349
|
+
const batchReservations = /* @__PURE__ */ new Map();
|
|
5350
|
+
const pendingRemovals = /* @__PURE__ */ new Set();
|
|
5351
|
+
const drainContiguousStagedResults = () => {
|
|
5352
|
+
var _a2;
|
|
5353
|
+
while (stagedResults.has(nextCommitOrdinal)) {
|
|
5354
|
+
const ordinal = nextCommitOrdinal;
|
|
5355
|
+
const ids = stagedResults.get(ordinal);
|
|
5356
|
+
stagedResults.delete(ordinal);
|
|
5357
|
+
nextCommitOrdinal += 1;
|
|
5358
|
+
const reservation = (_a2 = batchReservations.get(ordinal)) != null ? _a2 : 0;
|
|
5359
|
+
batchReservations.delete(ordinal);
|
|
5360
|
+
inFlightFiles -= reservation;
|
|
5361
|
+
for (const rid of ids) {
|
|
5362
|
+
if (rid === null) continue;
|
|
5363
|
+
if (pendingRemovals.has(rid)) {
|
|
5364
|
+
pendingRemovals.delete(rid);
|
|
5365
|
+
continue;
|
|
5366
|
+
}
|
|
5367
|
+
initialFiles.push(rid);
|
|
5368
|
+
}
|
|
5369
|
+
}
|
|
5370
|
+
filesWrapper.dataset.resourceIds = JSON.stringify(initialFiles);
|
|
5371
|
+
};
|
|
5372
|
+
const coordinator = {
|
|
5373
|
+
getOccupiedCount: () => initialFiles.length + inFlightFiles,
|
|
5374
|
+
getAllKnownRids: () => {
|
|
5375
|
+
const out = [...initialFiles];
|
|
5376
|
+
for (const ids of stagedResults.values()) {
|
|
5377
|
+
for (const rid of ids) {
|
|
5378
|
+
if (rid !== null) out.push(rid);
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
return out;
|
|
5382
|
+
},
|
|
5383
|
+
hasInFlightBatches: () => activeBatches > 0 || batchReservations.size > 0,
|
|
5384
|
+
wasRemovedDuringBatch: (rid) => pendingRemovals.has(rid),
|
|
5385
|
+
beginBatch: (count) => {
|
|
5386
|
+
inFlightFiles += count;
|
|
5387
|
+
activeBatches += 1;
|
|
5388
|
+
const ordinal = nextBatchOrdinal++;
|
|
5389
|
+
batchReservations.set(ordinal, count);
|
|
5390
|
+
return {
|
|
5391
|
+
setResults: (orderedIds) => {
|
|
5392
|
+
stagedResults.set(ordinal, orderedIds);
|
|
5393
|
+
drainContiguousStagedResults();
|
|
5394
|
+
},
|
|
5395
|
+
end: () => {
|
|
5396
|
+
activeBatches -= 1;
|
|
5397
|
+
const wasLast = activeBatches === 0 && batchReservations.size === 0;
|
|
5398
|
+
if (wasLast) {
|
|
5399
|
+
pendingRemovals.clear();
|
|
5400
|
+
}
|
|
5401
|
+
return { wasLast };
|
|
5402
|
+
}
|
|
5403
|
+
};
|
|
5404
|
+
}
|
|
5405
|
+
};
|
|
5406
|
+
const buildSuccessTile = (rid) => {
|
|
5407
|
+
const currentlyReadonly = isElementReadonly(element, state);
|
|
5408
|
+
return buildPreviewTile(
|
|
5409
|
+
rid,
|
|
5410
|
+
state,
|
|
5411
|
+
!currentlyReadonly,
|
|
5412
|
+
currentlyReadonly ? null : () => {
|
|
5413
|
+
var _a2, _b2, _c;
|
|
5414
|
+
releaseLocalFileUrl((_a2 = state.resourceIndex.get(rid)) == null ? void 0 : _a2.file);
|
|
5415
|
+
const idx = initialFiles.indexOf(rid);
|
|
5416
|
+
if (idx > -1) {
|
|
5417
|
+
initialFiles.splice(idx, 1);
|
|
5418
|
+
if (coordinator.hasInFlightBatches()) {
|
|
5419
|
+
pendingRemovals.add(rid);
|
|
5420
|
+
(_b2 = list.querySelector(`[data-resource-id="${rid}"]`)) == null ? void 0 : _b2.remove();
|
|
5421
|
+
filesWrapper.dataset.resourceIds = JSON.stringify(initialFiles);
|
|
5422
|
+
} else {
|
|
5423
|
+
updateFilesDisplay();
|
|
5424
|
+
}
|
|
5425
|
+
if (ctx.instance && pathKey && !state.config.readonly) {
|
|
5426
|
+
ctx.instance.triggerOnChange(pathKey, initialFiles);
|
|
5427
|
+
}
|
|
5428
|
+
return;
|
|
5429
|
+
}
|
|
5430
|
+
pendingRemovals.add(rid);
|
|
5431
|
+
(_c = list.querySelector(`[data-resource-id="${rid}"]`)) == null ? void 0 : _c.remove();
|
|
5432
|
+
if (ctx.instance && pathKey && !state.config.readonly) {
|
|
5433
|
+
ctx.instance.triggerOnChange(pathKey, initialFiles);
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5436
|
+
);
|
|
5437
|
+
};
|
|
5438
|
+
const prepareForUpload = () => disposePlaceholdersForUpload(list);
|
|
5439
|
+
const sharedHandlerOpts = {
|
|
5440
|
+
resourceIds: initialFiles,
|
|
5245
5441
|
state,
|
|
5246
|
-
updateFilesDisplay,
|
|
5442
|
+
updateCallback: updateFilesDisplay,
|
|
5247
5443
|
constraints,
|
|
5248
5444
|
pathKey,
|
|
5249
|
-
ctx.instance
|
|
5250
|
-
|
|
5445
|
+
instance: ctx.instance,
|
|
5446
|
+
buildSuccessTile,
|
|
5447
|
+
prepareForUpload,
|
|
5448
|
+
coordinator
|
|
5449
|
+
};
|
|
5450
|
+
setupFilesDropHandler({ ...sharedHandlerOpts, filesContainer });
|
|
5451
|
+
setupFilesPickerHandler({ ...sharedHandlerOpts, filesPicker });
|
|
5251
5452
|
updateFilesDisplay();
|
|
5252
5453
|
wrapper.appendChild(filesWrapper);
|
|
5253
5454
|
}
|
|
@@ -11032,6 +11233,7 @@ var exampleThemes = {
|
|
|
11032
11233
|
},
|
|
11033
11234
|
// Picaz wizard design tokens — derived from the Picaz Wizard mockups.
|
|
11034
11235
|
// Pairs with the host-side .card / .section-num / .lede chrome that wraps the form.
|
|
11236
|
+
// Assumes Inter is loaded by the host (e.g. via Google Fonts in index.html).
|
|
11035
11237
|
picaz: {
|
|
11036
11238
|
...defaultTheme,
|
|
11037
11239
|
primaryColor: "#2f5bea",
|
|
@@ -11063,6 +11265,9 @@ var exampleThemes = {
|
|
|
11063
11265
|
fileUploadBgColor: "#fafcff",
|
|
11064
11266
|
fileUploadBorderColor: "#cdd6e3",
|
|
11065
11267
|
fileUploadHoverBorderColor: "#2f5bea",
|
|
11268
|
+
// Picaz uses roomier inputs (11/14px) than the defaultTheme compact density.
|
|
11269
|
+
inputPaddingX: "14px",
|
|
11270
|
+
inputPaddingY: "11px",
|
|
11066
11271
|
borderRadius: "12px",
|
|
11067
11272
|
borderRadiusSmall: "8px",
|
|
11068
11273
|
borderRadiusLarge: "16px",
|
|
@@ -11070,7 +11275,17 @@ var exampleThemes = {
|
|
|
11070
11275
|
fontFamily: '"Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif',
|
|
11071
11276
|
shadowCard: "0 1px 2px rgba(15,23,42,.04), 0 1px 0 rgba(15,23,42,.02)",
|
|
11072
11277
|
shadowPopover: "0 12px 32px -12px rgba(15,23,42,.18), 0 4px 12px -6px rgba(15,23,42,.08)",
|
|
11073
|
-
focusRingColor: "#2f5bea"
|
|
11278
|
+
focusRingColor: "#2f5bea",
|
|
11279
|
+
// Slide cards: subtle gradient lift, no rest-state shadow (mockup adds it
|
|
11280
|
+
// only on hover, which form-builder doesn't yet differentiate).
|
|
11281
|
+
slideCardBg: "linear-gradient(180deg, #f7f9fc 0%, #dde3ee 100%)",
|
|
11282
|
+
slideCardShadow: "none",
|
|
11283
|
+
slideCardRadius: "16px",
|
|
11284
|
+
// Tiny uppercase captions above grouped lists ("ПРЕИМУЩЕСТВА" in the mockup).
|
|
11285
|
+
labelSectionFontSize: "0.625rem",
|
|
11286
|
+
// 10px
|
|
11287
|
+
labelSectionLetterSpacing: "0.07em",
|
|
11288
|
+
labelSectionTextTransform: "uppercase"
|
|
11074
11289
|
}
|
|
11075
11290
|
};
|
|
11076
11291
|
|
|
@@ -11436,6 +11651,13 @@ var FormBuilderInstance = class {
|
|
|
11436
11651
|
const value = hintValues[fieldKey];
|
|
11437
11652
|
this.updateField(fullPath, value);
|
|
11438
11653
|
}
|
|
11654
|
+
const group = target.closest(".fb-prefill-hints");
|
|
11655
|
+
if (group) {
|
|
11656
|
+
group.querySelectorAll(
|
|
11657
|
+
'.fb-prefill-hint[aria-pressed="true"]'
|
|
11658
|
+
).forEach((el) => el.removeAttribute("aria-pressed"));
|
|
11659
|
+
}
|
|
11660
|
+
target.setAttribute("aria-pressed", "true");
|
|
11439
11661
|
} catch (error) {
|
|
11440
11662
|
console.error("Error parsing prefill hint values:", error);
|
|
11441
11663
|
}
|