@dmitryvim/form-builder 0.2.15 → 0.2.17

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.
@@ -3739,6 +3739,18 @@ function updateSliderField(element, fieldPath, value, context) {
3739
3739
  }
3740
3740
 
3741
3741
  // src/components/container.ts
3742
+ function extractChildDefaults(elements) {
3743
+ const defaults = {};
3744
+ for (const child of elements) {
3745
+ if ("default" in child && child.default !== void 0) {
3746
+ defaults[child.key] = child.default;
3747
+ }
3748
+ }
3749
+ return defaults;
3750
+ }
3751
+ function mergeWithDefaults(prefill, defaults) {
3752
+ return { ...defaults, ...prefill };
3753
+ }
3742
3754
  function extractRootFormData(formRoot) {
3743
3755
  const data = {};
3744
3756
  const inputs = formRoot.querySelectorAll(
@@ -3814,10 +3826,13 @@ function renderSingleContainerElement(element, ctx, wrapper, pathKey) {
3814
3826
  containerWrap.appendChild(hintsElement);
3815
3827
  }
3816
3828
  }
3829
+ const childDefaults = extractChildDefaults(element.elements);
3830
+ const containerPrefill = ((_a = ctx.prefill) == null ? void 0 : _a[element.key]) || {};
3831
+ const mergedPrefill = mergeWithDefaults(containerPrefill, childDefaults);
3817
3832
  const subCtx = {
3818
3833
  path: pathJoin(ctx.path, element.key),
3819
- prefill: ((_a = ctx.prefill) == null ? void 0 : _a[element.key]) || {},
3820
- // Sliced data for value population
3834
+ prefill: mergedPrefill,
3835
+ // Merged prefill with defaults for enableIf evaluation
3821
3836
  formData: (_b = ctx.formData) != null ? _b : ctx.prefill,
3822
3837
  // Complete root data for enableIf evaluation
3823
3838
  state: ctx.state
@@ -3848,6 +3863,7 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
3848
3863
  const min = (_a = element.minCount) != null ? _a : 0;
3849
3864
  const max = (_b = element.maxCount) != null ? _b : Infinity;
3850
3865
  const pre = Array.isArray((_c = ctx.prefill) == null ? void 0 : _c[element.key]) ? ctx.prefill[element.key] : null;
3866
+ const childDefaults = extractChildDefaults(element.elements);
3851
3867
  const countItems = () => itemsWrap.querySelectorAll(":scope > .containerItem").length;
3852
3868
  const createAddButton = () => {
3853
3869
  const add = document.createElement("button");
@@ -3874,7 +3890,8 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
3874
3890
  const subCtx = {
3875
3891
  state: ctx.state,
3876
3892
  path: pathJoin(ctx.path, `${element.key}[${idx}]`),
3877
- prefill: {},
3893
+ prefill: childDefaults,
3894
+ // Defaults for enableIf evaluation
3878
3895
  formData: currentFormData
3879
3896
  // Current root data from DOM for enableIf
3880
3897
  };
@@ -3910,10 +3927,7 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
3910
3927
  rem.addEventListener("mouseleave", () => {
3911
3928
  rem.style.backgroundColor = "transparent";
3912
3929
  });
3913
- rem.onclick = () => {
3914
- item.remove();
3915
- updateAddButton();
3916
- };
3930
+ rem.onclick = () => handleRemoveItem(item);
3917
3931
  item.style.position = "relative";
3918
3932
  item.appendChild(rem);
3919
3933
  }
@@ -3935,13 +3949,19 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
3935
3949
  }
3936
3950
  countDisplay.textContent = `${currentCount}/${max === Infinity ? "\u221E" : max}`;
3937
3951
  };
3952
+ const handleRemoveItem = (item) => {
3953
+ item.remove();
3954
+ updateAddButton();
3955
+ };
3938
3956
  if (pre && Array.isArray(pre)) {
3939
3957
  pre.forEach((prefillObj, idx) => {
3940
3958
  var _a2;
3959
+ const mergedPrefill = mergeWithDefaults(prefillObj || {}, childDefaults);
3941
3960
  const subCtx = {
3942
3961
  state: ctx.state,
3943
3962
  path: pathJoin(ctx.path, `${element.key}[${idx}]`),
3944
- prefill: prefillObj || {},
3963
+ prefill: mergedPrefill,
3964
+ // Merged prefill with defaults for enableIf
3945
3965
  formData: (_a2 = ctx.formData) != null ? _a2 : ctx.prefill
3946
3966
  // Complete root data for enableIf
3947
3967
  };
@@ -3977,10 +3997,7 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
3977
3997
  rem.addEventListener("mouseleave", () => {
3978
3998
  rem.style.backgroundColor = "transparent";
3979
3999
  });
3980
- rem.onclick = () => {
3981
- item.remove();
3982
- updateAddButton();
3983
- };
4000
+ rem.onclick = () => handleRemoveItem(item);
3984
4001
  item.style.position = "relative";
3985
4002
  item.appendChild(rem);
3986
4003
  }
@@ -3993,7 +4010,8 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
3993
4010
  const subCtx = {
3994
4011
  state: ctx.state,
3995
4012
  path: pathJoin(ctx.path, `${element.key}[${idx}]`),
3996
- prefill: {},
4013
+ prefill: childDefaults,
4014
+ // Defaults for enableIf evaluation
3997
4015
  formData: (_d = ctx.formData) != null ? _d : ctx.prefill
3998
4016
  // Complete root data for enableIf
3999
4017
  };
@@ -4030,8 +4048,7 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
4030
4048
  });
4031
4049
  rem.onclick = () => {
4032
4050
  if (countItems() > min) {
4033
- item.remove();
4034
- updateAddButton();
4051
+ handleRemoveItem(item);
4035
4052
  }
4036
4053
  };
4037
4054
  item.style.position = "relative";
@@ -4090,15 +4107,16 @@ function validateContainerElement(element, key, context) {
4090
4107
  "[data-container-item]"
4091
4108
  );
4092
4109
  const containerWrappers = Array.from(allContainerWrappers).filter((el) => {
4093
- const attr = el.getAttribute("data-container-item");
4094
- return attr == null ? void 0 : attr.startsWith(`${key}[`);
4110
+ const attr = el.getAttribute("data-container-item") || "";
4111
+ if (!attr.startsWith(`${key}[`)) return false;
4112
+ const suffix = attr.slice(key.length);
4113
+ return /^\[\d+\]$/.test(suffix);
4095
4114
  });
4096
- const itemCount = containerWrappers.length;
4097
- for (let i = 0; i < itemCount; i++) {
4115
+ containerWrappers.forEach((itemContainer) => {
4098
4116
  const itemData = {};
4099
- const itemContainer = scopeRoot.querySelector(
4100
- `[data-container-item="${key}[${i}]"]`
4101
- ) || scopeRoot;
4117
+ const containerAttr = itemContainer.getAttribute("data-container-item") || "";
4118
+ const indexMatch = containerAttr.match(/\[(\d+)\]$/);
4119
+ const domIndex = indexMatch ? parseInt(indexMatch[1], 10) : 0;
4102
4120
  element.elements.forEach((child) => {
4103
4121
  var _a;
4104
4122
  if (child.enableIf) {
@@ -4116,7 +4134,7 @@ function validateContainerElement(element, key, context) {
4116
4134
  }
4117
4135
  } catch (error) {
4118
4136
  console.error(
4119
- `Error evaluating enableIf for field "${child.key}" in container "${key}[${i}]":`,
4137
+ `Error evaluating enableIf for field "${child.key}" in container "${key}[${domIndex}]":`,
4120
4138
  error
4121
4139
  );
4122
4140
  }
@@ -4124,7 +4142,7 @@ function validateContainerElement(element, key, context) {
4124
4142
  if (child.hidden || child.type === "hidden") {
4125
4143
  itemData[child.key] = child.default !== void 0 ? child.default : null;
4126
4144
  } else {
4127
- const childKey = `${key}[${i}].${child.key}`;
4145
+ const childKey = `${key}[${domIndex}].${child.key}`;
4128
4146
  itemData[child.key] = validateElement(
4129
4147
  { ...child, key: childKey },
4130
4148
  { path },
@@ -4133,7 +4151,7 @@ function validateContainerElement(element, key, context) {
4133
4151
  }
4134
4152
  });
4135
4153
  items.push(itemData);
4136
- }
4154
+ });
4137
4155
  validateContainerCount(key, items, element);
4138
4156
  return { value: items, errors };
4139
4157
  } else {
@@ -4348,13 +4366,14 @@ if (typeof document !== "undefined") {
4348
4366
  });
4349
4367
  }
4350
4368
  function shouldDisableElement(element, ctx) {
4351
- var _a, _b;
4369
+ var _a, _b, _c;
4352
4370
  if (!element.enableIf) {
4353
4371
  return false;
4354
4372
  }
4355
4373
  try {
4356
4374
  const rootFormData = (_b = (_a = ctx.formData) != null ? _a : ctx.prefill) != null ? _b : {};
4357
- const containerData = ctx.path ? getValueByPath(rootFormData, ctx.path) : void 0;
4375
+ const scope = (_c = element.enableIf.scope) != null ? _c : "relative";
4376
+ const containerData = scope === "relative" && ctx.path ? ctx.prefill : void 0;
4358
4377
  const shouldEnable = evaluateEnableCondition(
4359
4378
  element.enableIf,
4360
4379
  rootFormData,
@@ -5790,8 +5809,18 @@ var FormBuilderInstance = class {
5790
5809
  if ((element.type === "container" || element.type === "group") && "elements" in element && element.elements) {
5791
5810
  const containerData = formData == null ? void 0 : formData[element.key];
5792
5811
  if (Array.isArray(containerData)) {
5793
- containerData.forEach((_, index) => {
5794
- checkElements(element.elements, `${fullPath}[${index}]`);
5812
+ const containerItems = this.state.formRoot.querySelectorAll(
5813
+ `[data-container-item]`
5814
+ );
5815
+ const directItems = Array.from(containerItems).filter((el) => {
5816
+ const attr = el.getAttribute("data-container-item") || "";
5817
+ if (!attr.startsWith(`${fullPath}[`)) return false;
5818
+ const suffix = attr.slice(fullPath.length);
5819
+ return /^\[\d+\]$/.test(suffix);
5820
+ });
5821
+ directItems.forEach((el) => {
5822
+ const attr = el.getAttribute("data-container-item") || "";
5823
+ checkElements(element.elements, attr);
5795
5824
  });
5796
5825
  } else {
5797
5826
  checkElements(element.elements, fullPath);