@dmitryvim/form-builder 0.2.32 → 0.2.34

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.
@@ -406,6 +406,169 @@ function deepEqual(a, b) {
406
406
  return a === b;
407
407
  }
408
408
 
409
+ // src/utils/styles.ts
410
+ function mountCounterInLabel(wrapper, counter) {
411
+ const labelRow = wrapper.querySelector(
412
+ ":scope > [data-fb-label-row]"
413
+ );
414
+ if (labelRow) labelRow.appendChild(counter);
415
+ }
416
+ function createAddItemRow(classNameSuffix, onClick, options = {}) {
417
+ var _a;
418
+ const label = (_a = options.label) != null ? _a : "";
419
+ const showCounter = options.showCounter !== false;
420
+ const row = document.createElement("div");
421
+ row.className = "fb-add-row mt-2";
422
+ row.style.cssText = "display:flex;align-items:stretch;width:100%;";
423
+ const button = document.createElement("button");
424
+ button.type = "button";
425
+ button.className = `add-${classNameSuffix}-btn`;
426
+ button.style.cssText = `
427
+ flex: 1 1 auto;
428
+ display: inline-flex;
429
+ align-items: center;
430
+ justify-content: center;
431
+ gap: 6px;
432
+ padding: 6px 10px;
433
+ border: 1px dashed var(--fb-primary-color);
434
+ border-radius: var(--fb-border-radius);
435
+ background: transparent;
436
+ color: var(--fb-primary-color);
437
+ font-size: var(--fb-font-size-small, var(--fb-font-size));
438
+ font-weight: 500;
439
+ font-family: var(--fb-font-family);
440
+ cursor: pointer;
441
+ transition: border-color var(--fb-transition-duration), color var(--fb-transition-duration), background-color var(--fb-transition-duration);
442
+ `;
443
+ button.textContent = label ? `+ ${label}` : "+";
444
+ button.addEventListener("mouseenter", () => {
445
+ if (button.disabled) return;
446
+ button.style.borderStyle = "solid";
447
+ button.style.backgroundColor = "var(--fb-background-hover-color)";
448
+ });
449
+ button.addEventListener("mouseleave", () => {
450
+ button.style.borderStyle = "dashed";
451
+ button.style.backgroundColor = "transparent";
452
+ });
453
+ button.onclick = onClick;
454
+ const counter = document.createElement("span");
455
+ counter.className = "fb-add-counter";
456
+ counter.style.cssText = `
457
+ margin-left: auto;
458
+ font-size: var(--fb-font-size-small, 0.875rem);
459
+ color: var(--fb-text-secondary-color);
460
+ font-weight: 400;
461
+ `;
462
+ if (!showCounter) counter.style.display = "none";
463
+ row.appendChild(button);
464
+ const update = (current, max) => {
465
+ const reached = current >= max;
466
+ row.style.display = reached ? "none" : "flex";
467
+ button.style.display = reached ? "none" : "inline-flex";
468
+ button.disabled = reached;
469
+ if (showCounter) {
470
+ counter.textContent = `${current}/${max === Infinity ? "\u221E" : max}`;
471
+ }
472
+ };
473
+ return { row, button, counter, update };
474
+ }
475
+ function createSlideAddTile(onClick, options = {}) {
476
+ var _a;
477
+ const label = (_a = options.label) != null ? _a : "";
478
+ const tile = document.createElement("button");
479
+ tile.type = "button";
480
+ tile.className = "add-container-btn fb-slide-add";
481
+ tile.style.cssText = `
482
+ display: flex;
483
+ flex-direction: column;
484
+ align-items: center;
485
+ justify-content: center;
486
+ gap: 12px;
487
+ width: 100%;
488
+ min-height: 180px;
489
+ align-self: stretch;
490
+ padding: 24px 16px;
491
+ border: 1.5px dashed var(--fb-primary-color);
492
+ border-radius: var(--fb-border-radius);
493
+ background: transparent;
494
+ color: var(--fb-primary-color);
495
+ font-size: var(--fb-font-size-small, var(--fb-font-size));
496
+ font-weight: 500;
497
+ font-family: var(--fb-font-family);
498
+ cursor: pointer;
499
+ transition: border-color var(--fb-transition-duration), color var(--fb-transition-duration), background-color var(--fb-transition-duration);
500
+ `;
501
+ const circle = document.createElement("span");
502
+ circle.className = "fb-slide-add-circle";
503
+ circle.style.cssText = `
504
+ display: inline-flex;
505
+ align-items: center;
506
+ justify-content: center;
507
+ width: 36px;
508
+ height: 36px;
509
+ border: 1px solid var(--fb-primary-color);
510
+ border-radius: 50%;
511
+ background: var(--fb-background-color);
512
+ font-size: 20px;
513
+ line-height: 1;
514
+ color: inherit;
515
+ transition: inherit;
516
+ `;
517
+ circle.textContent = "+";
518
+ tile.appendChild(circle);
519
+ if (label) {
520
+ const text = document.createElement("span");
521
+ text.textContent = label;
522
+ tile.appendChild(text);
523
+ }
524
+ tile.addEventListener("mouseenter", () => {
525
+ if (tile.disabled) return;
526
+ tile.style.borderStyle = "solid";
527
+ tile.style.backgroundColor = "var(--fb-background-hover-color)";
528
+ });
529
+ tile.addEventListener("mouseleave", () => {
530
+ tile.style.borderStyle = "dashed";
531
+ tile.style.backgroundColor = "transparent";
532
+ });
533
+ tile.onclick = onClick;
534
+ const counter = document.createElement("span");
535
+ counter.className = "fb-add-counter";
536
+ counter.style.cssText = `
537
+ margin-left: auto;
538
+ font-size: var(--fb-font-size-small, 0.875rem);
539
+ color: var(--fb-text-secondary-color);
540
+ font-weight: 400;
541
+ `;
542
+ const update = (current, max) => {
543
+ const reached = current >= max;
544
+ tile.style.display = reached ? "none" : "flex";
545
+ tile.disabled = reached;
546
+ counter.textContent = `${current}/${max === Infinity ? "\u221E" : max}`;
547
+ };
548
+ return { tile, counter, update };
549
+ }
550
+ function applyActionButtonStyles(button, isFormLevel = false) {
551
+ button.style.cssText = `
552
+ background-color: var(--fb-action-bg-color);
553
+ color: var(--fb-action-text-color);
554
+ border: var(--fb-border-width) solid var(--fb-action-border-color);
555
+ padding: ${isFormLevel ? "0.5rem 1rem" : "0.5rem 0.75rem"};
556
+ font-size: var(--fb-font-size);
557
+ font-weight: var(--fb-font-weight-medium);
558
+ border-radius: var(--fb-border-radius);
559
+ transition: all var(--fb-transition-duration);
560
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
561
+ `;
562
+ button.addEventListener("mouseenter", () => {
563
+ button.style.backgroundColor = "var(--fb-action-hover-bg-color)";
564
+ button.style.borderColor = "var(--fb-action-hover-border-color)";
565
+ });
566
+ button.addEventListener("mouseleave", () => {
567
+ button.style.backgroundColor = "var(--fb-action-bg-color)";
568
+ button.style.borderColor = "var(--fb-action-border-color)";
569
+ });
570
+ }
571
+
409
572
  // src/components/text.ts
410
573
  function createCharCounter(element, input, isTextarea = false) {
411
574
  const counter = document.createElement("span");
@@ -458,12 +621,13 @@ function renderTextElement(element, ctx, wrapper, pathKey) {
458
621
  const readonly = isElementReadonly(element, state, ctx);
459
622
  const inputWrapper = document.createElement("div");
460
623
  inputWrapper.style.cssText = "position: relative;";
624
+ const hasCharCounter = !readonly && (element.minLength != null || element.maxLength != null);
461
625
  const textInput = document.createElement("input");
462
626
  textInput.type = "text";
463
627
  textInput.className = "w-full rounded-lg";
464
628
  textInput.style.cssText = `
465
629
  padding: var(--fb-input-padding-y) var(--fb-input-padding-x);
466
- padding-right: 60px;
630
+ ${hasCharCounter ? "padding-right: 60px;" : ""}
467
631
  border: var(--fb-border-width) solid var(--fb-border-color);
468
632
  border-radius: var(--fb-border-radius);
469
633
  background-color: ${readonly ? "var(--fb-background-readonly-color)" : "var(--fb-background-color)"};
@@ -508,7 +672,7 @@ function renderTextElement(element, ctx, wrapper, pathKey) {
508
672
  textInput.addEventListener("input", handleChange);
509
673
  }
510
674
  inputWrapper.appendChild(textInput);
511
- if (!readonly && (element.minLength != null || element.maxLength != null)) {
675
+ if (hasCharCounter) {
512
676
  const counter = createCharCounter(element, textInput, false);
513
677
  inputWrapper.appendChild(counter);
514
678
  }
@@ -520,6 +684,7 @@ function renderMultipleTextElement(element, ctx, wrapper, pathKey) {
520
684
  const readonly = isElementReadonly(element, state, ctx);
521
685
  const prefillValues = ctx.prefill[element.key] || [];
522
686
  const values = Array.isArray(prefillValues) ? [...prefillValues] : [];
687
+ const hasCharCounter = !readonly && (element.minLength != null || element.maxLength != null);
523
688
  const minCount = (_a = element.minCount) != null ? _a : 1;
524
689
  const maxCount = (_b = element.maxCount) != null ? _b : Infinity;
525
690
  while (values.length < minCount) {
@@ -546,7 +711,7 @@ function renderMultipleTextElement(element, ctx, wrapper, pathKey) {
546
711
  textInput.type = "text";
547
712
  textInput.style.cssText = `
548
713
  padding: var(--fb-input-padding-y) var(--fb-input-padding-x);
549
- padding-right: 60px;
714
+ ${hasCharCounter ? "padding-right: 60px;" : ""}
550
715
  border: var(--fb-border-width) solid var(--fb-border-color);
551
716
  border-radius: var(--fb-border-radius);
552
717
  background-color: ${readonly ? "var(--fb-background-readonly-color)" : "var(--fb-background-color)"};
@@ -590,7 +755,7 @@ function renderMultipleTextElement(element, ctx, wrapper, pathKey) {
590
755
  textInput.addEventListener("input", handleChange);
591
756
  }
592
757
  inputContainer.appendChild(textInput);
593
- if (!readonly && (element.minLength != null || element.maxLength != null)) {
758
+ if (hasCharCounter) {
594
759
  const counter = createCharCounter(element, textInput, false);
595
760
  inputContainer.appendChild(counter);
596
761
  }
@@ -647,50 +812,24 @@ function renderMultipleTextElement(element, ctx, wrapper, pathKey) {
647
812
  removeBtn.style.pointerEvents = disabled ? "none" : "auto";
648
813
  });
649
814
  }
650
- let addRow = null;
651
- let countDisplay = null;
815
+ let addUpdate = null;
652
816
  if (!readonly) {
653
- addRow = document.createElement("div");
654
- addRow.className = "flex items-center gap-3 mt-2";
655
- const addBtn = document.createElement("button");
656
- addBtn.type = "button";
657
- addBtn.className = "add-text-btn px-3 py-1 rounded";
658
- addBtn.style.cssText = `
659
- color: var(--fb-primary-color);
660
- border: var(--fb-border-width) solid var(--fb-primary-color);
661
- background-color: transparent;
662
- font-size: var(--fb-font-size);
663
- transition: all var(--fb-transition-duration);
664
- `;
665
- addBtn.textContent = "+";
666
- addBtn.addEventListener("mouseenter", () => {
667
- addBtn.style.backgroundColor = "var(--fb-background-hover-color)";
668
- });
669
- addBtn.addEventListener("mouseleave", () => {
670
- addBtn.style.backgroundColor = "transparent";
671
- });
672
- addBtn.onclick = () => {
673
- values.push(element.default || "");
674
- addTextItem(element.default || "");
675
- updateAddButton();
676
- updateRemoveButtons();
677
- };
678
- countDisplay = document.createElement("span");
679
- countDisplay.className = "text-sm text-gray-500";
680
- addRow.appendChild(addBtn);
681
- addRow.appendChild(countDisplay);
682
- wrapper.appendChild(addRow);
817
+ const handle = createAddItemRow(
818
+ "text",
819
+ () => {
820
+ values.push(element.default || "");
821
+ addTextItem(element.default || "");
822
+ updateAddButton();
823
+ updateRemoveButtons();
824
+ },
825
+ { label: element.addLabel }
826
+ );
827
+ addUpdate = handle.update;
828
+ mountCounterInLabel(wrapper, handle.counter);
829
+ wrapper.appendChild(handle.row);
683
830
  }
684
831
  function updateAddButton() {
685
- if (!addRow || !countDisplay) return;
686
- const addBtn = addRow.querySelector(".add-text-btn");
687
- if (addBtn) {
688
- const disabled = values.length >= maxCount;
689
- addBtn.disabled = disabled;
690
- addBtn.style.opacity = disabled ? "0.5" : "1";
691
- addBtn.style.pointerEvents = disabled ? "none" : "auto";
692
- }
693
- countDisplay.textContent = `${values.length}/${maxCount === Infinity ? "\u221E" : maxCount}`;
832
+ if (addUpdate) addUpdate(values.length, maxCount);
694
833
  }
695
834
  values.forEach((value) => addTextItem(value));
696
835
  updateAddButton();
@@ -990,52 +1129,24 @@ function renderMultipleTextareaElement(element, ctx, wrapper, pathKey) {
990
1129
  removeBtn.style.pointerEvents = disabled ? "none" : "auto";
991
1130
  });
992
1131
  }
993
- let addRow = null;
994
- let countDisplay = null;
1132
+ let addUpdate = null;
995
1133
  if (!readonly) {
996
- addRow = document.createElement("div");
997
- addRow.className = "flex items-center gap-3 mt-2";
998
- const addBtn = document.createElement("button");
999
- addBtn.type = "button";
1000
- addBtn.className = "add-textarea-btn px-3 py-1 rounded";
1001
- addBtn.style.cssText = `
1002
- color: var(--fb-primary-color);
1003
- border: var(--fb-border-width) solid var(--fb-primary-color);
1004
- background-color: transparent;
1005
- font-size: var(--fb-font-size);
1006
- transition: all var(--fb-transition-duration);
1007
- `;
1008
- addBtn.textContent = "+";
1009
- addBtn.addEventListener("mouseenter", () => {
1010
- addBtn.style.backgroundColor = "var(--fb-background-hover-color)";
1011
- });
1012
- addBtn.addEventListener("mouseleave", () => {
1013
- addBtn.style.backgroundColor = "transparent";
1014
- });
1015
- addBtn.onclick = () => {
1016
- values.push(element.default || "");
1017
- addTextareaItem(element.default || "");
1018
- updateAddButton();
1019
- updateRemoveButtons();
1020
- };
1021
- countDisplay = document.createElement("span");
1022
- countDisplay.className = "text-sm text-gray-500";
1023
- addRow.appendChild(addBtn);
1024
- addRow.appendChild(countDisplay);
1025
- wrapper.appendChild(addRow);
1134
+ const handle = createAddItemRow(
1135
+ "textarea",
1136
+ () => {
1137
+ values.push(element.default || "");
1138
+ addTextareaItem(element.default || "");
1139
+ updateAddButton();
1140
+ updateRemoveButtons();
1141
+ },
1142
+ { label: element.addLabel }
1143
+ );
1144
+ addUpdate = handle.update;
1145
+ mountCounterInLabel(wrapper, handle.counter);
1146
+ wrapper.appendChild(handle.row);
1026
1147
  }
1027
1148
  function updateAddButton() {
1028
- if (!addRow || !countDisplay) return;
1029
- const addBtn = addRow.querySelector(
1030
- ".add-textarea-btn"
1031
- );
1032
- if (addBtn) {
1033
- const disabled = values.length >= maxCount;
1034
- addBtn.disabled = disabled;
1035
- addBtn.style.opacity = disabled ? "0.5" : "1";
1036
- addBtn.style.pointerEvents = disabled ? "none" : "auto";
1037
- }
1038
- countDisplay.textContent = `${values.length}/${maxCount === Infinity ? "\u221E" : maxCount}`;
1149
+ if (addUpdate) addUpdate(values.length, maxCount);
1039
1150
  }
1040
1151
  values.forEach((value) => addTextareaItem(value));
1041
1152
  updateAddButton();
@@ -1242,50 +1353,24 @@ function renderMultipleNumberElement(element, ctx, wrapper, pathKey) {
1242
1353
  removeBtn.style.pointerEvents = disabled ? "none" : "auto";
1243
1354
  });
1244
1355
  }
1245
- let addRow = null;
1246
- let countDisplay = null;
1356
+ let addUpdate = null;
1247
1357
  if (!readonly) {
1248
- addRow = document.createElement("div");
1249
- addRow.className = "flex items-center gap-3 mt-2";
1250
- const addBtn = document.createElement("button");
1251
- addBtn.type = "button";
1252
- addBtn.className = "add-number-btn px-3 py-1 rounded";
1253
- addBtn.style.cssText = `
1254
- color: var(--fb-primary-color);
1255
- border: var(--fb-border-width) solid var(--fb-primary-color);
1256
- background-color: transparent;
1257
- font-size: var(--fb-font-size);
1258
- transition: all var(--fb-transition-duration);
1259
- `;
1260
- addBtn.textContent = "+";
1261
- addBtn.addEventListener("mouseenter", () => {
1262
- addBtn.style.backgroundColor = "var(--fb-background-hover-color)";
1263
- });
1264
- addBtn.addEventListener("mouseleave", () => {
1265
- addBtn.style.backgroundColor = "transparent";
1266
- });
1267
- addBtn.onclick = () => {
1268
- values.push(element.default || "");
1269
- addNumberItem(element.default || "");
1270
- updateAddButton();
1271
- updateRemoveButtons();
1272
- };
1273
- countDisplay = document.createElement("span");
1274
- countDisplay.className = "text-sm text-gray-500";
1275
- addRow.appendChild(addBtn);
1276
- addRow.appendChild(countDisplay);
1277
- wrapper.appendChild(addRow);
1358
+ const handle = createAddItemRow(
1359
+ "number",
1360
+ () => {
1361
+ values.push(element.default || "");
1362
+ addNumberItem(element.default || "");
1363
+ updateAddButton();
1364
+ updateRemoveButtons();
1365
+ },
1366
+ { label: element.addLabel }
1367
+ );
1368
+ addUpdate = handle.update;
1369
+ mountCounterInLabel(wrapper, handle.counter);
1370
+ wrapper.appendChild(handle.row);
1278
1371
  }
1279
1372
  function updateAddButton() {
1280
- if (!addRow || !countDisplay) return;
1281
- const addBtn = addRow.querySelector(".add-number-btn");
1282
- if (addBtn) {
1283
- const disabled = values.length >= maxCount;
1284
- addBtn.disabled = disabled;
1285
- addBtn.style.opacity = disabled ? "0.5" : "1";
1286
- addBtn.style.pointerEvents = disabled ? "none" : "auto";
1287
- }
1288
- countDisplay.textContent = `${values.length}/${maxCount === Infinity ? "\u221E" : maxCount}`;
1373
+ if (addUpdate) addUpdate(values.length, maxCount);
1289
1374
  }
1290
1375
  values.forEach((value) => addNumberItem(value));
1291
1376
  updateAddButton();
@@ -1574,52 +1659,26 @@ function renderMultipleSelectElement(element, ctx, wrapper, pathKey) {
1574
1659
  removeBtn.style.pointerEvents = disabled ? "none" : "auto";
1575
1660
  });
1576
1661
  }
1577
- let addRow = null;
1578
- let countDisplay = null;
1662
+ let addUpdate = null;
1579
1663
  if (!readonly) {
1580
- addRow = document.createElement("div");
1581
- addRow.className = "flex items-center gap-3 mt-2";
1582
- const addBtn = document.createElement("button");
1583
- addBtn.type = "button";
1584
- addBtn.className = "add-select-btn px-3 py-1 rounded";
1585
- addBtn.style.cssText = `
1586
- color: var(--fb-primary-color);
1587
- border: var(--fb-border-width) solid var(--fb-primary-color);
1588
- background-color: transparent;
1589
- font-size: var(--fb-font-size);
1590
- transition: all var(--fb-transition-duration);
1591
- `;
1592
- addBtn.textContent = "+";
1593
- addBtn.addEventListener("mouseenter", () => {
1594
- addBtn.style.backgroundColor = "var(--fb-background-hover-color)";
1595
- });
1596
- addBtn.addEventListener("mouseleave", () => {
1597
- addBtn.style.backgroundColor = "transparent";
1598
- });
1599
- addBtn.onclick = () => {
1600
- var _a2, _b2;
1601
- const defaultValue = element.default || ((_b2 = (_a2 = element.options) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.value) || "";
1602
- values.push(defaultValue);
1603
- addSelectItem(defaultValue);
1604
- updateAddButton();
1605
- updateRemoveButtons();
1606
- };
1607
- countDisplay = document.createElement("span");
1608
- countDisplay.className = "text-sm text-gray-500";
1609
- addRow.appendChild(addBtn);
1610
- addRow.appendChild(countDisplay);
1611
- wrapper.appendChild(addRow);
1664
+ const handle = createAddItemRow(
1665
+ "select",
1666
+ () => {
1667
+ var _a2, _b2;
1668
+ const defaultValue = element.default || ((_b2 = (_a2 = element.options) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.value) || "";
1669
+ values.push(defaultValue);
1670
+ addSelectItem(defaultValue);
1671
+ updateAddButton();
1672
+ updateRemoveButtons();
1673
+ },
1674
+ { label: element.addLabel }
1675
+ );
1676
+ addUpdate = handle.update;
1677
+ mountCounterInLabel(wrapper, handle.counter);
1678
+ wrapper.appendChild(handle.row);
1612
1679
  }
1613
1680
  function updateAddButton() {
1614
- if (!addRow || !countDisplay) return;
1615
- const addBtn = addRow.querySelector(".add-select-btn");
1616
- if (addBtn) {
1617
- const disabled = values.length >= maxCount;
1618
- addBtn.disabled = disabled;
1619
- addBtn.style.opacity = disabled ? "0.5" : "1";
1620
- addBtn.style.pointerEvents = disabled ? "none" : "auto";
1621
- }
1622
- countDisplay.textContent = `${values.length}/${maxCount === Infinity ? "\u221E" : maxCount}`;
1681
+ if (addUpdate) addUpdate(values.length, maxCount);
1623
1682
  }
1624
1683
  values.forEach((value) => addSelectItem(value));
1625
1684
  updateAddButton();
@@ -1968,54 +2027,26 @@ function renderMultipleSwitcherElement(element, ctx, wrapper, pathKey) {
1968
2027
  removeBtn.style.pointerEvents = disabled ? "none" : "auto";
1969
2028
  });
1970
2029
  }
1971
- let addRow = null;
1972
- let countDisplay = null;
2030
+ let addUpdate = null;
1973
2031
  if (!readonly) {
1974
- addRow = document.createElement("div");
1975
- addRow.className = "flex items-center gap-3 mt-2";
1976
- const addBtn = document.createElement("button");
1977
- addBtn.type = "button";
1978
- addBtn.className = "add-switcher-btn px-3 py-1 rounded";
1979
- addBtn.style.cssText = `
1980
- color: var(--fb-primary-color);
1981
- border: var(--fb-border-width) solid var(--fb-primary-color);
1982
- background-color: transparent;
1983
- font-size: var(--fb-font-size);
1984
- transition: all var(--fb-transition-duration);
1985
- `;
1986
- addBtn.textContent = "+";
1987
- addBtn.addEventListener("mouseenter", () => {
1988
- addBtn.style.backgroundColor = "var(--fb-background-hover-color)";
1989
- });
1990
- addBtn.addEventListener("mouseleave", () => {
1991
- addBtn.style.backgroundColor = "transparent";
1992
- });
1993
- addBtn.onclick = () => {
1994
- var _a2, _b2;
1995
- const defaultValue = element.default || ((_b2 = (_a2 = element.options) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.value) || "";
1996
- values.push(defaultValue);
1997
- addSwitcherItem(defaultValue);
1998
- updateAddButton();
1999
- updateRemoveButtons();
2000
- };
2001
- countDisplay = document.createElement("span");
2002
- countDisplay.className = "text-sm text-gray-500";
2003
- addRow.appendChild(addBtn);
2004
- addRow.appendChild(countDisplay);
2005
- wrapper.appendChild(addRow);
2032
+ const handle = createAddItemRow(
2033
+ "switcher",
2034
+ () => {
2035
+ var _a2, _b2;
2036
+ const defaultValue = element.default || ((_b2 = (_a2 = element.options) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.value) || "";
2037
+ values.push(defaultValue);
2038
+ addSwitcherItem(defaultValue);
2039
+ updateAddButton();
2040
+ updateRemoveButtons();
2041
+ },
2042
+ { label: element.addLabel }
2043
+ );
2044
+ addUpdate = handle.update;
2045
+ mountCounterInLabel(wrapper, handle.counter);
2046
+ wrapper.appendChild(handle.row);
2006
2047
  }
2007
2048
  function updateAddButton() {
2008
- if (!addRow || !countDisplay) return;
2009
- const addBtn = addRow.querySelector(
2010
- ".add-switcher-btn"
2011
- );
2012
- if (addBtn) {
2013
- const disabled = values.length >= maxCount;
2014
- addBtn.disabled = disabled;
2015
- addBtn.style.opacity = disabled ? "0.5" : "1";
2016
- addBtn.style.pointerEvents = disabled ? "none" : "auto";
2017
- }
2018
- countDisplay.textContent = `${values.length}/${maxCount === Infinity ? "\u221E" : maxCount}`;
2049
+ if (addUpdate) addUpdate(values.length, maxCount);
2019
2050
  }
2020
2051
  values.forEach((value) => addSwitcherItem(value));
2021
2052
  updateAddButton();
@@ -2895,24 +2926,40 @@ function createTileActions(options) {
2895
2926
  return btn;
2896
2927
  };
2897
2928
  if (replaceHandler) {
2898
- const replaceBtn = makeBtn(ICON_REPLACE, t("replaceFile", state), "fb-tile-action-replace");
2929
+ const replaceBtn = makeBtn(
2930
+ ICON_REPLACE,
2931
+ t("replaceFile", state),
2932
+ "fb-tile-action-replace"
2933
+ );
2899
2934
  replaceBtn.addEventListener("click", () => replaceHandler());
2900
2935
  group.appendChild(replaceBtn);
2901
2936
  }
2902
2937
  if (libraryHandler) {
2903
- const libBtn = makeBtn(ICON_LIBRARY, t("fromLibrary", state), "fb-tile-action-library");
2938
+ const libBtn = makeBtn(
2939
+ ICON_LIBRARY,
2940
+ t("fromLibrary", state),
2941
+ "fb-tile-action-library"
2942
+ );
2904
2943
  libBtn.addEventListener("click", () => libraryHandler());
2905
2944
  group.appendChild(libBtn);
2906
2945
  }
2907
2946
  if (canDownload(state, meta)) {
2908
- const dlBtn = makeBtn(ICON_DOWNLOAD, t("downloadFile", state), "fb-tile-action-download");
2947
+ const dlBtn = makeBtn(
2948
+ ICON_DOWNLOAD,
2949
+ t("downloadFile", state),
2950
+ "fb-tile-action-download"
2951
+ );
2909
2952
  dlBtn.addEventListener("click", () => {
2910
2953
  triggerTileDownload(resourceId, fileName, state, meta);
2911
2954
  });
2912
2955
  group.appendChild(dlBtn);
2913
2956
  }
2914
2957
  if (canOpenInTab(state, meta)) {
2915
- const openBtn = makeBtn(ICON_OPEN, t("openInNewTab", state), "fb-tile-action-open");
2958
+ const openBtn = makeBtn(
2959
+ ICON_OPEN,
2960
+ t("openInNewTab", state),
2961
+ "fb-tile-action-open"
2962
+ );
2916
2963
  openBtn.addEventListener("click", () => {
2917
2964
  triggerTileOpen(resourceId, state, meta).catch((err) => {
2918
2965
  console.error("Open failed:", err);
@@ -2921,7 +2968,11 @@ function createTileActions(options) {
2921
2968
  group.appendChild(openBtn);
2922
2969
  }
2923
2970
  if (canRemove && removeHandler) {
2924
- const rmBtn = makeBtn(ICON_REMOVE, t("removeElement", state), "fb-tile-action-remove");
2971
+ const rmBtn = makeBtn(
2972
+ ICON_REMOVE,
2973
+ t("removeElement", state),
2974
+ "fb-tile-action-remove"
2975
+ );
2925
2976
  rmBtn.addEventListener("click", () => {
2926
2977
  removeHandler();
2927
2978
  });
@@ -2999,11 +3050,17 @@ function positionZoomPopup(popup, tile) {
2999
3050
  } else if (tileRect.bottom + margin + popupSize + padding <= window.innerHeight) {
3000
3051
  top = tileRect.bottom + margin;
3001
3052
  } else {
3002
- top = Math.max(padding, Math.min(window.innerHeight - popupSize - padding, tileRect.top));
3053
+ top = Math.max(
3054
+ padding,
3055
+ Math.min(window.innerHeight - popupSize - padding, tileRect.top)
3056
+ );
3003
3057
  }
3004
3058
  const tileCenterX = tileRect.left + tileRect.width / 2;
3005
3059
  let left = tileCenterX - popupSize / 2;
3006
- left = Math.max(padding, Math.min(window.innerWidth - popupSize - padding, left));
3060
+ left = Math.max(
3061
+ padding,
3062
+ Math.min(window.innerWidth - popupSize - padding, left)
3063
+ );
3007
3064
  popup.style.top = `${top}px`;
3008
3065
  popup.style.left = `${left}px`;
3009
3066
  }
@@ -3047,7 +3104,9 @@ function attachZoomHover(tile, src, alt, actionsEl) {
3047
3104
  const popup = getOrCreateZoomPopup();
3048
3105
  const existingActions = popup.querySelector(".fb-tile-actions");
3049
3106
  if (existingActions) existingActions.remove();
3050
- const img = popup.querySelector(".fb-tile-zoom-preview-img");
3107
+ const img = popup.querySelector(
3108
+ ".fb-tile-zoom-preview-img"
3109
+ );
3051
3110
  img.src = src;
3052
3111
  img.alt = alt;
3053
3112
  if (actionsEl) {
@@ -3075,7 +3134,9 @@ function attachZoomHover(tile, src, alt, actionsEl) {
3075
3134
  });
3076
3135
  }
3077
3136
  function attachClonedActionListeners(cloned, original) {
3078
- const originalBtns = Array.from(original.querySelectorAll(".fb-tile-action-btn"));
3137
+ const originalBtns = Array.from(
3138
+ original.querySelectorAll(".fb-tile-action-btn")
3139
+ );
3079
3140
  const clonedBtns = Array.from(cloned.querySelectorAll(".fb-tile-action-btn"));
3080
3141
  clonedBtns.forEach((clonedBtn, i) => {
3081
3142
  const origBtn = originalBtns[i];
@@ -3129,7 +3190,9 @@ function renderLocalVideoPreview(container, file, videoType, resourceId, state,
3129
3190
  return newContainer;
3130
3191
  }
3131
3192
  function attachVideoButtonHandlers(container, resourceId, state, deps) {
3132
- const changeBtn = container.querySelector(".change-file-btn");
3193
+ const changeBtn = container.querySelector(
3194
+ ".change-file-btn"
3195
+ );
3133
3196
  if (changeBtn) {
3134
3197
  changeBtn.onclick = (e) => {
3135
3198
  var _a;
@@ -3137,7 +3200,9 @@ function attachVideoButtonHandlers(container, resourceId, state, deps) {
3137
3200
  (_a = deps == null ? void 0 : deps.picker) == null ? void 0 : _a.click();
3138
3201
  };
3139
3202
  }
3140
- const deleteBtn = container.querySelector(".delete-file-btn");
3203
+ const deleteBtn = container.querySelector(
3204
+ ".delete-file-btn"
3205
+ );
3141
3206
  if (deleteBtn) {
3142
3207
  deleteBtn.onclick = (e) => {
3143
3208
  e.stopPropagation();
@@ -3275,7 +3340,13 @@ async function renderFilePreview(container, resourceId, state, options = {}) {
3275
3340
  deps
3276
3341
  );
3277
3342
  } else {
3278
- await renderUploadedFilePreview(container, resourceId, fileName, meta, state);
3343
+ await renderUploadedFilePreview(
3344
+ container,
3345
+ resourceId,
3346
+ fileName,
3347
+ meta,
3348
+ state
3349
+ );
3279
3350
  const isVideo = (_a = meta == null ? void 0 : meta.type) == null ? void 0 : _a.startsWith("video/");
3280
3351
  if (!isReadonly && !isVideo) {
3281
3352
  renderDeleteButton(container, resourceId, state);
@@ -3304,7 +3375,8 @@ async function renderFilePreviewReadonly(resourceId, state, fileName, options =
3304
3375
  }
3305
3376
  const localFileUrl = (meta == null ? void 0 : meta.file) instanceof File ? getLocalFileUrl(meta.file) : null;
3306
3377
  const resolveOpenUrl = async () => {
3307
- if (state.config.getDownloadUrl) return state.config.getDownloadUrl(resourceId);
3378
+ if (state.config.getDownloadUrl)
3379
+ return state.config.getDownloadUrl(resourceId);
3308
3380
  if (state.config.getThumbnail) return state.config.getThumbnail(resourceId);
3309
3381
  return localFileUrl;
3310
3382
  };
@@ -3446,7 +3518,8 @@ async function fillTileContent(tile, rid, meta, state, actionsEl) {
3446
3518
  }
3447
3519
  } catch (error) {
3448
3520
  const err = error instanceof Error ? error : new Error(String(error));
3449
- if (state.config.onThumbnailError) state.config.onThumbnailError(err, rid);
3521
+ if (state.config.onThumbnailError)
3522
+ state.config.onThumbnailError(err, rid);
3450
3523
  tile.innerHTML = `<div style="display:flex;align-items:center;justify-content:center;height:100%;font-size:16px;color:var(--fb-error-color,#ef4444);">\u2715</div>`;
3451
3524
  }
3452
3525
  } else {
@@ -3479,7 +3552,8 @@ async function fillTileContent(tile, rid, meta, state, actionsEl) {
3479
3552
  }
3480
3553
  } catch (error) {
3481
3554
  const err = error instanceof Error ? error : new Error(String(error));
3482
- if (state.config.onThumbnailError) state.config.onThumbnailError(err, rid);
3555
+ if (state.config.onThumbnailError)
3556
+ state.config.onThumbnailError(err, rid);
3483
3557
  tile.innerHTML = `<div style="display:flex;align-items:center;justify-content:center;height:100%;font-size:16px;color:var(--fb-error-color,#ef4444);">\u2715</div>`;
3484
3558
  }
3485
3559
  } else {
@@ -3513,7 +3587,8 @@ async function forceDownload(resourceId, fileName, state) {
3513
3587
  if (fileUrl) {
3514
3588
  const finalUrl = fileUrl.startsWith("http") ? fileUrl : new URL(fileUrl, window.location.href).href;
3515
3589
  const response = await fetch(finalUrl);
3516
- if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
3590
+ if (!response.ok)
3591
+ throw new Error(`HTTP error! status: ${response.status}`);
3517
3592
  const blob = await response.blob();
3518
3593
  downloadBlob(blob, fileName);
3519
3594
  } else {
@@ -3562,7 +3637,9 @@ async function uploadSingleFile(file, state) {
3562
3637
  } catch (error) {
3563
3638
  const err = error instanceof Error ? error : new Error(String(error));
3564
3639
  if (state.config.onUploadError) state.config.onUploadError(err, file);
3565
- throw new Error(`File upload failed: ${err.message}`);
3640
+ const wrapped = new Error(`File upload failed: ${err.message}`);
3641
+ wrapped.cause = err;
3642
+ throw wrapped;
3566
3643
  }
3567
3644
  }
3568
3645
  async function handleFileSelect(opts) {
@@ -3675,7 +3752,9 @@ function filterAndSlice(allFiles, currentCount, constraints, state) {
3675
3752
  const rejectedBySize = afterMime.filter(
3676
3753
  (f) => !isFileSizeAllowed(f, constraints.maxSize)
3677
3754
  );
3678
- const valid = afterMime.filter((f) => isFileSizeAllowed(f, constraints.maxSize));
3755
+ const valid = afterMime.filter(
3756
+ (f) => isFileSizeAllowed(f, constraints.maxSize)
3757
+ );
3679
3758
  const remaining = constraints.maxCount === Infinity ? valid.length : Math.max(0, constraints.maxCount - currentCount);
3680
3759
  const accepted = valid.slice(0, remaining);
3681
3760
  const skippedByCount = valid.length - accepted.length;
@@ -3688,7 +3767,13 @@ function filterAndSlice(allFiles, currentCount, constraints, state) {
3688
3767
  if (rejectedByMime.length > 0) {
3689
3768
  const mimes = constraints.allowedMimes.join(", ");
3690
3769
  const names = rejectedByMime.map((f) => f.name).join(", ");
3691
- errorParts.push(t("invalidFileMime", state, { name: names, type: rejectedByMime.map((f) => f.type).join(", "), mimes }));
3770
+ errorParts.push(
3771
+ t("invalidFileMime", state, {
3772
+ name: names,
3773
+ type: rejectedByMime.map((f) => f.type).join(", "),
3774
+ mimes
3775
+ })
3776
+ );
3692
3777
  }
3693
3778
  if (rejectedBySize.length > 0) {
3694
3779
  const names = rejectedBySize.map((f) => f.name).join(", ");
@@ -3713,7 +3798,8 @@ async function uploadBatch(accepted, resourceIds, listEl, state) {
3713
3798
  const addTile = (_a = tilesWrap.querySelector(".fb-multi-add-tile-js")) != null ? _a : tilesWrap.querySelector(".fb-tile-add");
3714
3799
  if (addTile) addTile.style.display = "none";
3715
3800
  }
3716
- await Promise.all(
3801
+ const failures = [];
3802
+ await Promise.allSettled(
3717
3803
  accepted.map(async (file) => {
3718
3804
  const placeholder = createUploadingTile(file.name, state);
3719
3805
  if (listEl) {
@@ -3730,11 +3816,27 @@ async function uploadBatch(accepted, resourceIds, listEl, state) {
3730
3816
  file: void 0
3731
3817
  });
3732
3818
  resourceIds.push(rid);
3819
+ } catch (err) {
3820
+ const wrapped = err instanceof Error ? err : new Error(String(err));
3821
+ const cause = wrapped.cause;
3822
+ const root = cause instanceof Error ? cause : cause !== void 0 ? new Error(String(cause)) : wrapped;
3823
+ failures.push({ file, error: root });
3733
3824
  } finally {
3734
3825
  placeholder.remove();
3735
3826
  }
3736
3827
  })
3737
3828
  );
3829
+ return { failures };
3830
+ }
3831
+ function buildBatchErrorMessage(filterError, failures, state) {
3832
+ if (failures.length === 0) return filterError;
3833
+ const uploadMsg = failures.map(
3834
+ (f) => t("uploadFailed", state, {
3835
+ name: f.file.name,
3836
+ error: f.error.message
3837
+ })
3838
+ ).join(" \u2022 ");
3839
+ return filterError ? `${filterError} \u2022 ${uploadMsg}` : uploadMsg;
3738
3840
  }
3739
3841
  function setupFilesDropHandler(filesContainer, resourceIds, state, updateCallback, constraints, pathKey, instance) {
3740
3842
  setupDragAndDrop(filesContainer, async (files) => {
@@ -3751,7 +3853,13 @@ function setupFilesDropHandler(filesContainer, resourceIds, state, updateCallbac
3751
3853
  clearFileError(filesContainer);
3752
3854
  }
3753
3855
  const list = (_a = filesContainer.querySelector(".files-list")) != null ? _a : filesContainer;
3754
- await uploadBatch(accepted, resourceIds, list, state);
3856
+ const { failures } = await uploadBatch(accepted, resourceIds, list, state);
3857
+ const combined = buildBatchErrorMessage(errorMessage, failures, state);
3858
+ if (combined) {
3859
+ showFileError(filesContainer, combined);
3860
+ } else {
3861
+ clearFileError(filesContainer);
3862
+ }
3755
3863
  updateCallback();
3756
3864
  if (instance && pathKey && !state.config.readonly) {
3757
3865
  instance.triggerOnChange(pathKey, resourceIds);
@@ -3774,7 +3882,20 @@ function setupFilesPickerHandler(filesPicker, resourceIds, state, updateCallback
3774
3882
  clearFileError(wrapperEl);
3775
3883
  }
3776
3884
  const listEl = wrapperEl == null ? void 0 : wrapperEl.querySelector(".files-list");
3777
- await uploadBatch(accepted, resourceIds, listEl != null ? listEl : null, state);
3885
+ const { failures } = await uploadBatch(
3886
+ accepted,
3887
+ resourceIds,
3888
+ listEl != null ? listEl : null,
3889
+ state
3890
+ );
3891
+ if (wrapperEl) {
3892
+ const combined = buildBatchErrorMessage(errorMessage, failures, state);
3893
+ if (combined) {
3894
+ showFileError(wrapperEl, combined);
3895
+ } else {
3896
+ clearFileError(wrapperEl);
3897
+ }
3898
+ }
3778
3899
  updateCallback();
3779
3900
  filesPicker.value = "";
3780
3901
  if (instance && pathKey && !state.config.readonly) {
@@ -3807,10 +3928,17 @@ function validatePickedResource(resource, allowedExtensions, allowedMimes, maxSi
3807
3928
  }
3808
3929
  if (!isMimeAllowed(resource.type, allowedMimes)) {
3809
3930
  const mimes = allowedMimes.join(", ");
3810
- return t("invalidFileMime", state, { name: resource.name, type: resource.type, mimes });
3931
+ return t("invalidFileMime", state, {
3932
+ name: resource.name,
3933
+ type: resource.type,
3934
+ mimes
3935
+ });
3811
3936
  }
3812
3937
  if (!isSizeWithinLimit(resource.size, maxSizeMB)) {
3813
- return t("fileTooLarge", state, { name: resource.name, maxSize: maxSizeMB });
3938
+ return t("fileTooLarge", state, {
3939
+ name: resource.name,
3940
+ maxSize: maxSizeMB
3941
+ });
3814
3942
  }
3815
3943
  return null;
3816
3944
  }
@@ -3871,7 +3999,13 @@ async function handleLibraryPickMulti(state, element, wrapper, fieldPath, resour
3871
3999
  return true;
3872
4000
  });
3873
4001
  const validItems = deduped.filter((r) => {
3874
- const err = validatePickedResource(r, allowedExtensions, allowedMimes, maxSizeMB, state);
4002
+ const err = validatePickedResource(
4003
+ r,
4004
+ allowedExtensions,
4005
+ allowedMimes,
4006
+ maxSizeMB,
4007
+ state
4008
+ );
3875
4009
  return err === null;
3876
4010
  });
3877
4011
  const freshRemaining = maxCount === Infinity ? validItems.length : Math.max(0, maxCount - resourceIds.length);
@@ -3916,14 +4050,22 @@ async function handleLibraryPickSingle(state, element, container, fileWrapper, p
3916
4050
  }
3917
4051
  if (picked.length === 0) return;
3918
4052
  const first = picked[0];
3919
- const validationError = validatePickedResource(first, allowedExtensions, allowedMimes, maxSizeMB, state);
4053
+ const validationError = validatePickedResource(
4054
+ first,
4055
+ allowedExtensions,
4056
+ allowedMimes,
4057
+ maxSizeMB,
4058
+ state
4059
+ );
3920
4060
  if (validationError !== null) {
3921
4061
  showFileError(container, validationError);
3922
4062
  return;
3923
4063
  }
3924
4064
  clearFileError(container);
3925
4065
  registerPickedResource(first, state);
3926
- let hiddenInput = fileWrapper.querySelector('input[type="hidden"]');
4066
+ let hiddenInput = fileWrapper.querySelector(
4067
+ 'input[type="hidden"]'
4068
+ );
3927
4069
  if (!hiddenInput) {
3928
4070
  hiddenInput = document.createElement("input");
3929
4071
  hiddenInput.type = "hidden";
@@ -4087,7 +4229,8 @@ function renderSingleFileFilled(fileContainer, resourceId, state, deps, extras)
4087
4229
  grid.appendChild(tile);
4088
4230
  fileContainer.className = "file-preview-container";
4089
4231
  fileContainer.removeAttribute("style");
4090
- while (fileContainer.firstChild) fileContainer.removeChild(fileContainer.firstChild);
4232
+ while (fileContainer.firstChild)
4233
+ fileContainer.removeChild(fileContainer.firstChild);
4091
4234
  fileContainer.appendChild(outer);
4092
4235
  }
4093
4236
  function buildMultiAddTile(state, hasLibrary, onUploadClick, onLibraryClick, isDragOver = false) {
@@ -4169,7 +4312,9 @@ function buildMetaLine(state, element, ridCount, maxCount, canClearAll, onClearA
4169
4312
  metaText.appendChild(sizeSpan);
4170
4313
  metaText.appendChild(buildMetaDot());
4171
4314
  }
4172
- const exts = getAllowedExtensions(element.accept);
4315
+ const exts = getAllowedExtensions(
4316
+ element.accept
4317
+ );
4173
4318
  if (exts.length > 0) {
4174
4319
  const fmtSpan = document.createElement("span");
4175
4320
  fmtSpan.className = "fb-meta-mono";
@@ -4420,7 +4565,9 @@ function renderFileElementEdit(element, ctx, wrapper, pathKey) {
4420
4565
  },
4421
4566
  onRemove() {
4422
4567
  var _a2;
4423
- const hiddenInput = fileWrapper.querySelector('input[type="hidden"]');
4568
+ const hiddenInput = fileWrapper.querySelector(
4569
+ 'input[type="hidden"]'
4570
+ );
4424
4571
  const currentRid = hiddenInput == null ? void 0 : hiddenInput.value;
4425
4572
  if (currentRid) {
4426
4573
  releaseLocalFileUrl((_a2 = state.resourceIndex.get(currentRid)) == null ? void 0 : _a2.file);
@@ -4430,7 +4577,9 @@ function renderFileElementEdit(element, ctx, wrapper, pathKey) {
4430
4577
  }
4431
4578
  };
4432
4579
  const buildSingleExtras = () => {
4433
- const hasLibrary = Boolean(state.config.pickExistingFiles && !element.disableLibrary);
4580
+ const hasLibrary = Boolean(
4581
+ state.config.pickExistingFiles && !element.disableLibrary
4582
+ );
4434
4583
  return {
4435
4584
  replaceHandler: state.config.uploadFile ? () => picker.click() : null,
4436
4585
  libraryHandler: hasLibrary ? () => {
@@ -4442,7 +4591,13 @@ function renderFileElementEdit(element, ctx, wrapper, pathKey) {
4442
4591
  pathKey,
4443
4592
  pathKey,
4444
4593
  async (rid) => {
4445
- renderSingleFileFilled(fileContainer, rid, state, buildDeps(), buildSingleExtras());
4594
+ renderSingleFileFilled(
4595
+ fileContainer,
4596
+ rid,
4597
+ state,
4598
+ buildDeps(),
4599
+ buildSingleExtras()
4600
+ );
4446
4601
  },
4447
4602
  ctx.instance
4448
4603
  ).catch((err) => {
@@ -4458,14 +4613,21 @@ function renderFileElementEdit(element, ctx, wrapper, pathKey) {
4458
4613
  setupDrop: handlers.setupDrop,
4459
4614
  onRemove: handlers.onRemove,
4460
4615
  onAfterUpload: (container, rid) => {
4461
- renderSingleFileFilled(container, rid, state, buildDeps(), buildSingleExtras());
4616
+ renderSingleFileFilled(
4617
+ container,
4618
+ rid,
4619
+ state,
4620
+ buildDeps(),
4621
+ buildSingleExtras()
4622
+ );
4462
4623
  }
4463
4624
  });
4464
4625
  const renderEmptySingleState = () => {
4465
4626
  ensureFileStyles();
4466
4627
  fileContainer.className = "file-preview-container";
4467
4628
  fileContainer.removeAttribute("style");
4468
- while (fileContainer.firstChild) fileContainer.removeChild(fileContainer.firstChild);
4629
+ while (fileContainer.firstChild)
4630
+ fileContainer.removeChild(fileContainer.firstChild);
4469
4631
  const onLibraryClick = buildSingleExtras().libraryHandler;
4470
4632
  const wideTile = buildWideTile(
4471
4633
  state,
@@ -4610,7 +4772,13 @@ function renderFilesElementEdit(element, ctx, wrapper, pathKey) {
4610
4772
  }
4611
4773
  function renderMultipleFileElementEdit(element, ctx, wrapper, pathKey) {
4612
4774
  var _a;
4613
- setupMultiFileEditMode(element, ctx, wrapper, pathKey, (_a = element.maxCount) != null ? _a : Infinity);
4775
+ setupMultiFileEditMode(
4776
+ element,
4777
+ ctx,
4778
+ wrapper,
4779
+ pathKey,
4780
+ (_a = element.maxCount) != null ? _a : Infinity
4781
+ );
4614
4782
  }
4615
4783
 
4616
4784
  // src/components/file/validate.ts
@@ -4793,7 +4961,11 @@ function renderMultiFileReadonly(rids, state, wrapper, pathKey, _marginTop) {
4793
4961
  const placeholder = placeholders[i];
4794
4962
  const meta = state.resourceIndex.get(resourceId);
4795
4963
  renderFilePreviewReadonly(resourceId, state, meta == null ? void 0 : meta.name).then((tile) => {
4796
- tile.classList.add("fb-readonly-tile", "fb-checker", "fb-tile-resource");
4964
+ tile.classList.add(
4965
+ "fb-readonly-tile",
4966
+ "fb-checker",
4967
+ "fb-tile-resource"
4968
+ );
4797
4969
  tile.dataset.resourceId = resourceId;
4798
4970
  placeholder.replaceWith(tile);
4799
4971
  }).catch(() => {
@@ -5144,51 +5316,25 @@ function renderMultipleColourElement(element, ctx, wrapper, pathKey) {
5144
5316
  removeBtn.style.pointerEvents = disabled ? "none" : "auto";
5145
5317
  });
5146
5318
  }
5147
- let addRow = null;
5148
- let countDisplay = null;
5319
+ let addUpdate = null;
5149
5320
  if (!readonly) {
5150
- addRow = document.createElement("div");
5151
- addRow.className = "flex items-center gap-3 mt-2";
5152
- const addBtn = document.createElement("button");
5153
- addBtn.type = "button";
5154
- addBtn.className = "add-colour-btn px-3 py-1 rounded";
5155
- addBtn.style.cssText = `
5156
- color: var(--fb-primary-color);
5157
- border: var(--fb-border-width) solid var(--fb-primary-color);
5158
- background-color: transparent;
5159
- font-size: var(--fb-font-size);
5160
- transition: all var(--fb-transition-duration);
5161
- `;
5162
- addBtn.textContent = "+";
5163
- addBtn.addEventListener("mouseenter", () => {
5164
- addBtn.style.backgroundColor = "var(--fb-background-hover-color)";
5165
- });
5166
- addBtn.addEventListener("mouseleave", () => {
5167
- addBtn.style.backgroundColor = "transparent";
5168
- });
5169
- addBtn.onclick = () => {
5170
- const defaultColour = element.default || "#000000";
5171
- values.push(defaultColour);
5172
- addColourItem(defaultColour);
5173
- updateAddButton();
5174
- updateRemoveButtons();
5175
- };
5176
- countDisplay = document.createElement("span");
5177
- countDisplay.className = "text-sm text-gray-500";
5178
- addRow.appendChild(addBtn);
5179
- addRow.appendChild(countDisplay);
5180
- wrapper.appendChild(addRow);
5321
+ const handle = createAddItemRow(
5322
+ "colour",
5323
+ () => {
5324
+ const defaultColour = element.default || "#000000";
5325
+ values.push(defaultColour);
5326
+ addColourItem(defaultColour);
5327
+ updateAddButton();
5328
+ updateRemoveButtons();
5329
+ },
5330
+ { label: element.addLabel }
5331
+ );
5332
+ addUpdate = handle.update;
5333
+ mountCounterInLabel(wrapper, handle.counter);
5334
+ wrapper.appendChild(handle.row);
5181
5335
  }
5182
5336
  function updateAddButton() {
5183
- if (!addRow || !countDisplay) return;
5184
- const addBtn = addRow.querySelector(".add-colour-btn");
5185
- if (addBtn) {
5186
- const disabled = values.length >= maxCount;
5187
- addBtn.disabled = disabled;
5188
- addBtn.style.opacity = disabled ? "0.5" : "1";
5189
- addBtn.style.pointerEvents = disabled ? "none" : "auto";
5190
- }
5191
- countDisplay.textContent = `${values.length}/${maxCount === Infinity ? "\u221E" : maxCount}`;
5337
+ if (addUpdate) addUpdate(values.length, maxCount);
5192
5338
  }
5193
5339
  values.forEach((value) => addColourItem(value));
5194
5340
  updateAddButton();
@@ -5630,50 +5776,24 @@ function renderMultipleSliderElement(element, ctx, wrapper, pathKey) {
5630
5776
  removeBtn.style.pointerEvents = disabled ? "none" : "auto";
5631
5777
  });
5632
5778
  }
5633
- let addRow = null;
5634
- let countDisplay = null;
5779
+ let addUpdate = null;
5635
5780
  if (!readonly) {
5636
- addRow = document.createElement("div");
5637
- addRow.className = "flex items-center gap-3 mt-2";
5638
- const addBtn = document.createElement("button");
5639
- addBtn.type = "button";
5640
- addBtn.className = "add-slider-btn px-3 py-1 rounded";
5641
- addBtn.style.cssText = `
5642
- color: var(--fb-primary-color);
5643
- border: var(--fb-border-width) solid var(--fb-primary-color);
5644
- background-color: transparent;
5645
- font-size: var(--fb-font-size);
5646
- transition: all var(--fb-transition-duration);
5647
- `;
5648
- addBtn.textContent = "+";
5649
- addBtn.addEventListener("mouseenter", () => {
5650
- addBtn.style.backgroundColor = "var(--fb-background-hover-color)";
5651
- });
5652
- addBtn.addEventListener("mouseleave", () => {
5653
- addBtn.style.backgroundColor = "transparent";
5654
- });
5655
- addBtn.onclick = () => {
5656
- values.push(defaultValue);
5657
- addSliderItem(defaultValue);
5658
- updateAddButton();
5659
- updateRemoveButtons();
5660
- };
5661
- countDisplay = document.createElement("span");
5662
- countDisplay.className = "text-sm text-gray-500";
5663
- addRow.appendChild(addBtn);
5664
- addRow.appendChild(countDisplay);
5665
- wrapper.appendChild(addRow);
5781
+ const handle = createAddItemRow(
5782
+ "slider",
5783
+ () => {
5784
+ values.push(defaultValue);
5785
+ addSliderItem(defaultValue);
5786
+ updateAddButton();
5787
+ updateRemoveButtons();
5788
+ },
5789
+ { label: element.addLabel }
5790
+ );
5791
+ addUpdate = handle.update;
5792
+ mountCounterInLabel(wrapper, handle.counter);
5793
+ wrapper.appendChild(handle.row);
5666
5794
  }
5667
5795
  function updateAddButton() {
5668
- if (!addRow || !countDisplay) return;
5669
- const addBtn = addRow.querySelector(".add-slider-btn");
5670
- if (addBtn) {
5671
- const disabled = values.length >= maxCount;
5672
- addBtn.disabled = disabled;
5673
- addBtn.style.opacity = disabled ? "0.5" : "1";
5674
- addBtn.style.pointerEvents = disabled ? "none" : "auto";
5675
- }
5676
- countDisplay.textContent = `${values.length}/${maxCount === Infinity ? "\u221E" : maxCount}`;
5796
+ if (addUpdate) addUpdate(values.length, maxCount);
5677
5797
  }
5678
5798
  values.forEach((value) => addSliderItem(value));
5679
5799
  updateAddButton();
@@ -6025,6 +6145,47 @@ function getChildWrapperClass(isSlides, columns) {
6025
6145
  const cols = columns || 1;
6026
6146
  return cols === 1 ? "space-y-2" : `grid grid-cols-${cols} gap-2`;
6027
6147
  }
6148
+ function mountRemoveButton(item, onRemove) {
6149
+ const rem = document.createElement("button");
6150
+ rem.type = "button";
6151
+ rem.className = "fb-item-remove";
6152
+ rem.style.cssText = `
6153
+ width: 22px;
6154
+ height: 22px;
6155
+ display: inline-flex;
6156
+ align-items: center;
6157
+ justify-content: center;
6158
+ padding: 0;
6159
+ line-height: 1;
6160
+ font-size: 14px;
6161
+ color: var(--fb-error-color);
6162
+ background-color: transparent;
6163
+ border: 0;
6164
+ border-radius: 4px;
6165
+ cursor: pointer;
6166
+ flex-shrink: 0;
6167
+ transition: background-color var(--fb-transition-duration);
6168
+ `;
6169
+ rem.textContent = "\u2715";
6170
+ rem.addEventListener("mouseenter", () => {
6171
+ rem.style.backgroundColor = "var(--fb-background-hover-color)";
6172
+ });
6173
+ rem.addEventListener("mouseleave", () => {
6174
+ rem.style.backgroundColor = "transparent";
6175
+ });
6176
+ rem.onclick = onRemove;
6177
+ const labelRow = item.querySelector("[data-fb-label-row]");
6178
+ if (labelRow) {
6179
+ rem.style.marginLeft = "auto";
6180
+ labelRow.appendChild(rem);
6181
+ return;
6182
+ }
6183
+ rem.style.position = "absolute";
6184
+ rem.style.top = "8px";
6185
+ rem.style.right = "8px";
6186
+ item.style.position = "relative";
6187
+ item.appendChild(rem);
6188
+ }
6028
6189
  function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
6029
6190
  var _a, _b, _c, _d;
6030
6191
  const state = ctx.state;
@@ -6032,8 +6193,6 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
6032
6193
  const childInheritedReadonly = containerIsReadonly || ctx.inheritedReadonly;
6033
6194
  const containerWrap = document.createElement("div");
6034
6195
  containerWrap.className = "border border-gray-200 rounded-lg p-2 bg-gray-50";
6035
- const countDisplay = document.createElement("span");
6036
- countDisplay.className = "text-sm text-gray-500";
6037
6196
  const itemsWrap = document.createElement("div");
6038
6197
  const isSlides = element.displayMode === "slides";
6039
6198
  if (isSlides) {
@@ -6055,93 +6214,65 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
6055
6214
  const pre = Array.isArray((_c = ctx.prefill) == null ? void 0 : _c[element.key]) ? ctx.prefill[element.key] : null;
6056
6215
  const childDefaults = extractChildDefaults(element.elements);
6057
6216
  const countItems = () => itemsWrap.querySelectorAll(":scope > .containerItem").length;
6058
- const createAddButton = () => {
6059
- const add = document.createElement("button");
6060
- add.type = "button";
6061
- add.className = "add-container-btn px-3 py-1 rounded";
6062
- add.style.cssText = `
6063
- color: var(--fb-primary-color);
6064
- border: var(--fb-border-width) solid var(--fb-primary-color);
6065
- background-color: transparent;
6066
- font-size: var(--fb-font-size);
6067
- transition: all var(--fb-transition-duration);
6068
- `;
6069
- add.textContent = "+";
6070
- add.addEventListener("mouseenter", () => {
6071
- add.style.backgroundColor = "var(--fb-background-hover-color)";
6072
- });
6073
- add.addEventListener("mouseleave", () => {
6074
- add.style.backgroundColor = "transparent";
6075
- });
6076
- add.onclick = () => {
6077
- if (countItems() < max) {
6078
- const idx = countItems();
6079
- const currentFormData = state.formRoot ? extractRootFormData(state.formRoot) : {};
6080
- const subCtx = {
6081
- state: ctx.state,
6082
- path: pathJoin(ctx.path, `${element.key}[${idx}]`),
6083
- prefill: childDefaults,
6084
- // Defaults for enableIf evaluation
6085
- formData: currentFormData,
6086
- // Current root data from DOM for enableIf
6087
- inheritedReadonly: childInheritedReadonly
6088
- };
6089
- const item = document.createElement("div");
6090
- item.className = "containerItem border border-gray-300 rounded-lg p-2 bg-white";
6091
- item.setAttribute("data-container-item", `${element.key}[${idx}]`);
6092
- const childWrapper = document.createElement("div");
6093
- childWrapper.className = getChildWrapperClass(isSlides, element.columns);
6094
- element.elements.forEach((child) => {
6095
- var _a2;
6096
- if (child.type !== "markdown" && (child.hidden || child.type === "hidden")) {
6097
- childWrapper.appendChild(
6098
- createHiddenInput(
6099
- pathJoin(subCtx.path, child.key),
6100
- (_a2 = "default" in child ? child.default : null) != null ? _a2 : null
6101
- )
6102
- );
6103
- } else {
6104
- childWrapper.appendChild(renderElement(child, subCtx));
6105
- }
6106
- });
6107
- item.appendChild(childWrapper);
6108
- if (!containerIsReadonly) {
6109
- const rem = document.createElement("button");
6110
- rem.type = "button";
6111
- rem.className = "absolute top-2 right-2 px-2 py-1 rounded";
6112
- rem.style.cssText = `
6113
- color: var(--fb-error-color);
6114
- background-color: transparent;
6115
- transition: background-color var(--fb-transition-duration);
6116
- `;
6117
- rem.textContent = "\u2715";
6118
- rem.addEventListener("mouseenter", () => {
6119
- rem.style.backgroundColor = "var(--fb-background-hover-color)";
6120
- });
6121
- rem.addEventListener("mouseleave", () => {
6122
- rem.style.backgroundColor = "transparent";
6123
- });
6124
- rem.onclick = () => handleRemoveItem(item);
6125
- item.style.position = "relative";
6126
- item.appendChild(rem);
6127
- }
6128
- itemsWrap.appendChild(item);
6129
- updateAddButton();
6130
- }
6217
+ const handleAddItem = () => {
6218
+ if (countItems() >= max) return;
6219
+ const idx = countItems();
6220
+ const currentFormData = state.formRoot ? extractRootFormData(state.formRoot) : {};
6221
+ const subCtx = {
6222
+ state: ctx.state,
6223
+ path: pathJoin(ctx.path, `${element.key}[${idx}]`),
6224
+ prefill: childDefaults,
6225
+ // Defaults for enableIf evaluation
6226
+ formData: currentFormData,
6227
+ // Current root data from DOM for enableIf
6228
+ inheritedReadonly: childInheritedReadonly
6131
6229
  };
6132
- return add;
6230
+ const item = document.createElement("div");
6231
+ item.className = "containerItem border border-gray-300 rounded-lg p-2 bg-white";
6232
+ item.setAttribute("data-container-item", `${element.key}[${idx}]`);
6233
+ const childWrapper = document.createElement("div");
6234
+ childWrapper.className = getChildWrapperClass(isSlides, element.columns);
6235
+ element.elements.forEach((child) => {
6236
+ var _a2;
6237
+ if (child.type !== "markdown" && (child.hidden || child.type === "hidden")) {
6238
+ childWrapper.appendChild(
6239
+ createHiddenInput(
6240
+ pathJoin(subCtx.path, child.key),
6241
+ (_a2 = "default" in child ? child.default : null) != null ? _a2 : null
6242
+ )
6243
+ );
6244
+ } else {
6245
+ childWrapper.appendChild(renderElement(child, subCtx));
6246
+ }
6247
+ });
6248
+ item.appendChild(childWrapper);
6249
+ if (!containerIsReadonly) {
6250
+ mountRemoveButton(item, () => handleRemoveItem(item));
6251
+ }
6252
+ if (slideAddTile && slideAddTile.parentElement === itemsWrap) {
6253
+ itemsWrap.insertBefore(item, slideAddTile);
6254
+ } else {
6255
+ itemsWrap.appendChild(item);
6256
+ }
6257
+ updateAddButton();
6133
6258
  };
6134
- const updateAddButton = () => {
6135
- const currentCount = countItems();
6136
- const existingAddBtn = containerWrap.querySelector(
6137
- ".add-container-btn"
6259
+ let slideAddTile = null;
6260
+ let slideAddUpdate = null;
6261
+ let pillAddUpdate = null;
6262
+ const syncSlideTileSize = () => {
6263
+ if (!slideAddTile) return;
6264
+ const firstSlide = itemsWrap.querySelector(
6265
+ ":scope > .containerItem"
6138
6266
  );
6139
- if (existingAddBtn) {
6140
- existingAddBtn.disabled = currentCount >= max;
6141
- existingAddBtn.style.opacity = currentCount >= max ? "0.5" : "1";
6142
- existingAddBtn.style.pointerEvents = currentCount >= max ? "none" : "auto";
6267
+ if (firstSlide && firstSlide.offsetHeight > 0) {
6268
+ slideAddTile.style.minHeight = `${firstSlide.offsetHeight}px`;
6143
6269
  }
6144
- countDisplay.textContent = `${currentCount}/${max === Infinity ? "\u221E" : max}`;
6270
+ };
6271
+ const updateAddButton = () => {
6272
+ const currentCount = countItems();
6273
+ if (slideAddUpdate) slideAddUpdate(currentCount, max);
6274
+ if (pillAddUpdate) pillAddUpdate(currentCount, max);
6275
+ if (slideAddTile) syncSlideTileSize();
6145
6276
  };
6146
6277
  const handleRemoveItem = (item) => {
6147
6278
  item.remove();
@@ -6187,24 +6318,7 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
6187
6318
  });
6188
6319
  item.appendChild(childWrapper);
6189
6320
  if (!containerIsReadonly) {
6190
- const rem = document.createElement("button");
6191
- rem.type = "button";
6192
- rem.className = "absolute top-2 right-2 px-2 py-1 rounded";
6193
- rem.style.cssText = `
6194
- color: var(--fb-error-color);
6195
- background-color: transparent;
6196
- transition: background-color var(--fb-transition-duration);
6197
- `;
6198
- rem.textContent = "\u2715";
6199
- rem.addEventListener("mouseenter", () => {
6200
- rem.style.backgroundColor = "var(--fb-background-hover-color)";
6201
- });
6202
- rem.addEventListener("mouseleave", () => {
6203
- rem.style.backgroundColor = "transparent";
6204
- });
6205
- rem.onclick = () => handleRemoveItem(item);
6206
- item.style.position = "relative";
6207
- item.appendChild(rem);
6321
+ mountRemoveButton(item, () => handleRemoveItem(item));
6208
6322
  }
6209
6323
  itemsWrap.appendChild(item);
6210
6324
  });
@@ -6249,41 +6363,43 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
6249
6363
  }
6250
6364
  });
6251
6365
  item.appendChild(childWrapper);
6252
- const rem = document.createElement("button");
6253
- rem.type = "button";
6254
- rem.className = "absolute top-2 right-2 px-2 py-1 rounded";
6255
- rem.style.cssText = `
6256
- color: var(--fb-error-color);
6257
- background-color: transparent;
6258
- transition: background-color var(--fb-transition-duration);
6259
- `;
6260
- rem.textContent = "\u2715";
6261
- rem.addEventListener("mouseenter", () => {
6262
- rem.style.backgroundColor = "var(--fb-background-hover-color)";
6263
- });
6264
- rem.addEventListener("mouseleave", () => {
6265
- rem.style.backgroundColor = "transparent";
6266
- });
6267
- rem.onclick = () => {
6366
+ mountRemoveButton(item, () => {
6268
6367
  if (countItems() > min) {
6269
6368
  handleRemoveItem(item);
6270
6369
  }
6271
- };
6272
- item.style.position = "relative";
6273
- item.appendChild(rem);
6370
+ });
6274
6371
  itemsWrap.appendChild(item);
6275
6372
  }
6276
6373
  }
6277
6374
  containerWrap.appendChild(itemsWrap);
6278
6375
  if (!containerIsReadonly) {
6279
- const addRow = document.createElement("div");
6280
- addRow.className = "flex items-center gap-3 mt-2";
6281
- addRow.appendChild(createAddButton());
6282
- addRow.appendChild(countDisplay);
6283
- containerWrap.appendChild(addRow);
6376
+ if (isSlides) {
6377
+ itemsWrap.style.alignItems = "stretch";
6378
+ const handle = createSlideAddTile(handleAddItem, {
6379
+ label: element.addLabel
6380
+ });
6381
+ slideAddTile = handle.tile;
6382
+ slideAddUpdate = handle.update;
6383
+ mountCounterInLabel(wrapper, handle.counter);
6384
+ itemsWrap.appendChild(handle.tile);
6385
+ } else {
6386
+ const handle = createAddItemRow("container", handleAddItem, {
6387
+ label: element.addLabel
6388
+ });
6389
+ pillAddUpdate = handle.update;
6390
+ mountCounterInLabel(wrapper, handle.counter);
6391
+ containerWrap.appendChild(handle.row);
6392
+ }
6284
6393
  }
6285
6394
  updateAddButton();
6286
6395
  wrapper.appendChild(containerWrap);
6396
+ if (slideAddTile) {
6397
+ if (typeof requestAnimationFrame === "function") {
6398
+ requestAnimationFrame(syncSlideTileSize);
6399
+ } else {
6400
+ syncSlideTileSize();
6401
+ }
6402
+ }
6287
6403
  }
6288
6404
  var validateElementFunc = null;
6289
6405
  function setValidateElement(fn) {
@@ -9251,10 +9367,7 @@ var TAGS = {
9251
9367
  "-": ["<hr />"]
9252
9368
  };
9253
9369
  function outdent(str) {
9254
- return str.replace(
9255
- RegExp("^" + (str.match(/^(\t| )+/) || "")[0], "gm"),
9256
- ""
9257
- );
9370
+ return str.replace(RegExp("^" + (str.match(/^(\t| )+/) || "")[0], "gm"), "");
9258
9371
  }
9259
9372
  function encodeAttr(str) {
9260
9373
  return (str + "").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -9417,12 +9530,7 @@ function ensureMarkdownStyles() {
9417
9530
  `;
9418
9531
  document.head.appendChild(style);
9419
9532
  }
9420
- var ANCHOR_DANGEROUS_SCHEMES = [
9421
- "javascript:",
9422
- "data:",
9423
- "vbscript:",
9424
- "blob:"
9425
- ];
9533
+ var ANCHOR_DANGEROUS_SCHEMES = ["javascript:", "data:", "vbscript:", "blob:"];
9426
9534
  var IMG_DANGEROUS_SCHEMES = ["javascript:", "vbscript:", "blob:"];
9427
9535
  function isImgSrcDangerous(normalized) {
9428
9536
  if (IMG_DANGEROUS_SCHEMES.some((scheme) => normalized.startsWith(scheme))) {
@@ -9749,6 +9857,7 @@ function createInfoButton(element) {
9749
9857
  function createLabelContainer(element) {
9750
9858
  const label = document.createElement("div");
9751
9859
  label.className = "flex items-center mb-1";
9860
+ label.dataset.fbLabelRow = "";
9752
9861
  const title = createFieldLabel(element);
9753
9862
  label.appendChild(title);
9754
9863
  if (element.description || element.hint) {
@@ -9966,6 +10075,7 @@ var defaultConfig = {
9966
10075
  invalidFileExtension: 'File "{name}" has unsupported format. Allowed: {formats}',
9967
10076
  invalidFileMime: 'File "{name}": file type {type} not allowed (allowed: {mimes})',
9968
10077
  fileTooLarge: 'File "{name}" exceeds maximum size of {maxSize}MB',
10078
+ uploadFailed: 'Failed to upload "{name}": {error}',
9969
10079
  filesLimitExceeded: "{skipped} file(s) skipped: maximum {max} files allowed",
9970
10080
  unsupportedFieldType: "Unsupported field type: {type}",
9971
10081
  invalidOption: "Invalid option",
@@ -10041,6 +10151,7 @@ var defaultConfig = {
10041
10151
  invalidFileExtension: '\u0424\u0430\u0439\u043B "{name}" \u0438\u043C\u0435\u0435\u0442 \u043D\u0435\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442. \u0414\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435: {formats}',
10042
10152
  invalidFileMime: '\u0424\u0430\u0439\u043B "{name}": \u0442\u0438\u043F \u0444\u0430\u0439\u043B\u0430 {type} \u043D\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043D (\u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u044B: {mimes})',
10043
10153
  fileTooLarge: '\u0424\u0430\u0439\u043B "{name}" \u043F\u0440\u0435\u0432\u044B\u0448\u0430\u0435\u0442 \u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0440\u0430\u0437\u043C\u0435\u0440 {maxSize}\u041C\u0411',
10154
+ uploadFailed: '\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C "{name}": {error}',
10044
10155
  filesLimitExceeded: "{skipped} \u0444\u0430\u0439\u043B(\u043E\u0432) \u043F\u0440\u043E\u043F\u0443\u0449\u0435\u043D\u043E: \u043C\u0430\u043A\u0441\u0438\u043C\u0443\u043C {max} \u0444\u0430\u0439\u043B\u043E\u0432",
10045
10156
  unsupportedFieldType: "\u041D\u0435\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0439 \u0442\u0438\u043F \u043F\u043E\u043B\u044F: {type}",
10046
10157
  invalidOption: "\u041D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435",
@@ -10263,29 +10374,6 @@ var exampleThemes = {
10263
10374
  }
10264
10375
  };
10265
10376
 
10266
- // src/utils/styles.ts
10267
- function applyActionButtonStyles(button, isFormLevel = false) {
10268
- button.style.cssText = `
10269
- background-color: var(--fb-action-bg-color);
10270
- color: var(--fb-action-text-color);
10271
- border: var(--fb-border-width) solid var(--fb-action-border-color);
10272
- padding: ${isFormLevel ? "0.5rem 1rem" : "0.5rem 0.75rem"};
10273
- font-size: var(--fb-font-size);
10274
- font-weight: var(--fb-font-weight-medium);
10275
- border-radius: var(--fb-border-radius);
10276
- transition: all var(--fb-transition-duration);
10277
- box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
10278
- `;
10279
- button.addEventListener("mouseenter", () => {
10280
- button.style.backgroundColor = "var(--fb-action-hover-bg-color)";
10281
- button.style.borderColor = "var(--fb-action-hover-border-color)";
10282
- });
10283
- button.addEventListener("mouseleave", () => {
10284
- button.style.backgroundColor = "var(--fb-action-bg-color)";
10285
- button.style.borderColor = "var(--fb-action-border-color)";
10286
- });
10287
- }
10288
-
10289
10377
  // src/components/registry.ts
10290
10378
  function validateHiddenElement(element, key, context) {
10291
10379
  var _a;