react-f0rm 0.11.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -58,10 +58,21 @@
58
58
  pathCache.set(path, value);
59
59
  return value;
60
60
  }
61
+ const isIndex = (segment) => /^-?\d+$/.test(segment);
61
62
  function parsePath(path) {
62
63
  const result = [];
63
64
  let identifier = "";
64
65
  const flushIdentifier = () => {
66
+ if (isIndex(identifier)) {
67
+ const dotted = [...result.map(String), identifier].join(".");
68
+ const bracket = result.reduce(
69
+ (acc, seg) => acc + (typeof seg === "number" ? `[${seg}]` : `${acc ? "." : ""}${seg}`),
70
+ ""
71
+ );
72
+ throw new TypeError(
73
+ `Numeric path segment must use bracket notation: "${dotted}" \u2192 "${bracket}[${identifier}]" (path: ${path})`
74
+ );
75
+ }
65
76
  result.push(identifier);
66
77
  identifier = "";
67
78
  };
@@ -90,7 +101,7 @@
90
101
  throw new TypeError(`Unterminated bracket in path: ${path}`);
91
102
  }
92
103
  const content = path.slice(i + 1, close);
93
- result.push(/^-?\d+$/.test(content) ? Number(content) : content);
104
+ result.push(isIndex(content) ? Number(content) : content);
94
105
  i = close;
95
106
  }
96
107
  } else {
@@ -127,9 +138,10 @@
127
138
  function set(values, path, value) {
128
139
  if (!path.length) return value;
129
140
  const [prop, ...props] = path;
130
- if (typeof prop === "number") {
141
+ const index = typeof prop === "number" ? prop : Array.isArray(values) && typeof prop === "string" && isIndex(prop) ? Number(prop) : void 0;
142
+ if (index !== void 0) {
131
143
  const arr = Array.isArray(values) ? values.slice() : [];
132
- arr[prop] = set(arr[prop], props, value);
144
+ arr[index] = set(arr[index], props, value);
133
145
  return arr;
134
146
  }
135
147
  return { ...values, [prop]: set(values && values[prop], props, value) };
@@ -143,7 +155,7 @@
143
155
  const prop = path[i];
144
156
  if (!owned.has(container)) {
145
157
  let copy;
146
- if (typeof prop === "number") {
158
+ if (typeof prop === "number" || Array.isArray(container) && typeof prop === "string" && isIndex(prop)) {
147
159
  copy = Array.isArray(container) ? container.slice() : [];
148
160
  } else {
149
161
  copy = { ...container };
@@ -253,9 +265,16 @@
253
265
  return getValueByPath(form, create$1(name));
254
266
  }
255
267
  function getValueByPath({ initialValues, parsedValues, values, deleted }, path) {
256
- if (values.has(path.key)) return values.get(path.key);
257
- if (deleted.has(path.key)) return void 0;
258
- return get(parsedValues ?? initialValues, path.value);
268
+ const { key, value: segments } = path;
269
+ if (values.has(key)) return values.get(key);
270
+ if (deleted.has(key)) return void 0;
271
+ for (let i = segments.length - 1; i > 0; i--) {
272
+ const ancestorKey = JSON.stringify(segments.slice(0, i));
273
+ if (values.has(ancestorKey)) {
274
+ return get(values.get(ancestorKey), segments.slice(i));
275
+ }
276
+ }
277
+ return get(parsedValues ?? initialValues, segments);
259
278
  }
260
279
  function setValue(form, name, value, options) {
261
280
  setValueByPath(form, create$1(name), value, options);
@@ -263,6 +282,7 @@
263
282
  function setValueByPath(form, path, value, options) {
264
283
  const { emitter, values, deleted } = form;
265
284
  values.set(path.key, value);
285
+ pruneDescendantKeys(values, path);
266
286
  reviveBranch(deleted, path);
267
287
  pruneDirtyBaselines(form, path);
268
288
  if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);
@@ -496,6 +516,13 @@
496
516
  }
497
517
  return false;
498
518
  }
519
+ function pruneDescendantKeys(values, { key }) {
520
+ if (!values.size) return;
521
+ const stem = `${key.slice(0, -1)},`;
522
+ for (const k of values.keys()) {
523
+ if (k.startsWith(stem)) values.delete(k);
524
+ }
525
+ }
499
526
  function reviveBranch(deleted, { key }) {
500
527
  if (!deleted.size) return;
501
528
  for (const tombstone of deleted) {
@@ -597,7 +624,10 @@
597
624
  }
598
625
  function setFormErrors(form, result, segments = [], footprint) {
599
626
  Object.entries(result).forEach(([key, value]) => {
600
- const path = [...segments, ...normalizePath(key)];
627
+ const path = [
628
+ ...segments,
629
+ ...isIndex(key) ? [key] : normalizePath(key)
630
+ ];
601
631
  if (typeof value === "string") {
602
632
  if (value) {
603
633
  setError(form, path, value);