@formisch/solid 0.10.0 → 0.12.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/dev.jsx CHANGED
@@ -23,11 +23,13 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
23
23
  else {
24
24
  internalFieldStore.schema = schema;
25
25
  internalFieldStore.name = JSON.stringify(path);
26
+ internalFieldStore.path = path;
26
27
  const initialElements = [];
27
28
  internalFieldStore.initialElements = initialElements;
28
29
  internalFieldStore.elements = initialElements;
29
30
  internalFieldStore.errors = /* @__PURE__ */ createSignal(null);
30
31
  internalFieldStore.isTouched = /* @__PURE__ */ createSignal(false);
32
+ internalFieldStore.isEdited = /* @__PURE__ */ createSignal(false);
31
33
  internalFieldStore.isDirty = /* @__PURE__ */ createSignal(false);
32
34
  if (schema.type === "array" || schema.type === "loose_tuple" || schema.type === "strict_tuple" || schema.type === "tuple") {
33
35
  if (internalFieldStore.kind && internalFieldStore.kind !== "array") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "array"`);
@@ -37,16 +39,13 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
37
39
  if (schema.type === "array") {
38
40
  if (initialInput) for (let index = 0; index < initialInput.length; index++) {
39
41
  internalFieldStore.children[index] = {};
40
- path.push(index);
41
- initializeFieldStore(internalFieldStore.children[index], schema.item, initialInput[index], path);
42
- path.pop();
42
+ initializeFieldStore(internalFieldStore.children[index], schema.item, initialInput[index], [...path, index]);
43
43
  }
44
44
  } else for (let index = 0; index < schema.items.length; index++) {
45
45
  internalFieldStore.children[index] = {};
46
- path.push(index);
47
- initializeFieldStore(internalFieldStore.children[index], schema.items[index], initialInput?.[index], path);
48
- path.pop();
46
+ initializeFieldStore(internalFieldStore.children[index], schema.items[index], initialInput?.[index], [...path, index]);
49
47
  }
48
+ internalFieldStore.isNullish = nullish;
50
49
  const arrayInput = nullish && initialInput == null ? initialInput : true;
51
50
  internalFieldStore.initialInput = /* @__PURE__ */ createSignal(arrayInput);
52
51
  internalFieldStore.startInput = /* @__PURE__ */ createSignal(arrayInput);
@@ -63,10 +62,9 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
63
62
  internalFieldStore.children ??= {};
64
63
  for (const key in schema.entries) {
65
64
  internalFieldStore.children[key] ??= {};
66
- path.push(key);
67
- initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput?.[key], path);
68
- path.pop();
65
+ initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput?.[key], [...path, key]);
69
66
  }
67
+ internalFieldStore.isNullish = nullish;
70
68
  const objectInput = nullish && initialInput == null ? initialInput : true;
71
69
  internalFieldStore.initialInput = /* @__PURE__ */ createSignal(objectInput);
72
70
  internalFieldStore.startInput = /* @__PURE__ */ createSignal(objectInput);
@@ -91,19 +89,16 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
91
89
  toInternalFieldStore.startInput.value = fromInternalFieldStore.startInput.value;
92
90
  toInternalFieldStore.input.value = fromInternalFieldStore.input.value;
93
91
  toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
92
+ toInternalFieldStore.isEdited.value = fromInternalFieldStore.isEdited.value;
94
93
  toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
95
94
  if (fromInternalFieldStore.kind === "array" && toInternalFieldStore.kind === "array") {
96
95
  const fromItems = fromInternalFieldStore.items.value;
97
96
  toInternalFieldStore.startItems.value = fromInternalFieldStore.startItems.value;
98
97
  toInternalFieldStore.items.value = fromItems;
99
- let path;
100
98
  for (let index = 0; index < fromItems.length; index++) {
101
99
  if (!toInternalFieldStore.children[index]) {
102
- path ??= JSON.parse(toInternalFieldStore.name);
103
100
  toInternalFieldStore.children[index] = {};
104
- path.push(index);
105
- initializeFieldStore(toInternalFieldStore.children[index], toInternalFieldStore.schema.item, void 0, path);
106
- path.pop();
101
+ initializeFieldStore(toInternalFieldStore.children[index], toInternalFieldStore.schema.item, void 0, [...toInternalFieldStore.path, index]);
107
102
  }
108
103
  copyItemState(fromInternalFieldStore.children[index], toInternalFieldStore.children[index]);
109
104
  }
@@ -111,29 +106,42 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
111
106
  });
112
107
  });
113
108
  }
114
- function resetItemState(internalFieldStore, initialInput) {
109
+ function resetItemState(internalFieldStore, input, keepStart = false) {
115
110
  batch(() => {
116
- internalFieldStore.elements = [];
111
+ const elements = [];
112
+ if (internalFieldStore.elements === internalFieldStore.initialElements) internalFieldStore.initialElements = elements;
113
+ internalFieldStore.elements = elements;
117
114
  internalFieldStore.errors.value = null;
118
115
  internalFieldStore.isTouched.value = false;
116
+ internalFieldStore.isEdited.value = false;
119
117
  internalFieldStore.isDirty.value = false;
120
118
  if (internalFieldStore.kind === "array" || internalFieldStore.kind === "object") {
121
- const objectInput = initialInput == null ? initialInput : true;
122
- internalFieldStore.startInput.value = objectInput;
119
+ const objectInput = internalFieldStore.isNullish && input == null ? input : true;
120
+ if (!keepStart) internalFieldStore.startInput.value = objectInput;
123
121
  internalFieldStore.input.value = objectInput;
124
- if (internalFieldStore.kind === "array") if (initialInput) {
125
- const newItems = initialInput.map(createId);
126
- internalFieldStore.startItems.value = newItems;
127
- internalFieldStore.items.value = newItems;
128
- for (let index = 0; index < initialInput.length; index++) if (internalFieldStore.children[index]) resetItemState(internalFieldStore.children[index], initialInput[index]);
129
- } else {
130
- internalFieldStore.startItems.value = [];
131
- internalFieldStore.items.value = [];
132
- }
133
- else for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], initialInput?.[key]);
122
+ if (internalFieldStore.kind === "array") {
123
+ const isTuple = internalFieldStore.schema.type !== "array";
124
+ if (input || isTuple) {
125
+ const length = isTuple ? internalFieldStore.children.length : input.length;
126
+ const newItems = Array.from({ length }, createId);
127
+ if (!keepStart) internalFieldStore.startItems.value = newItems;
128
+ internalFieldStore.items.value = newItems;
129
+ for (let index = 0; index < length; index++) {
130
+ const itemInput = input?.[index];
131
+ if (internalFieldStore.children[index]) resetItemState(internalFieldStore.children[index], itemInput, keepStart);
132
+ else {
133
+ internalFieldStore.children[index] = {};
134
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, itemInput, [...internalFieldStore.path, index]);
135
+ }
136
+ }
137
+ } else {
138
+ if (!keepStart) internalFieldStore.startItems.value = [];
139
+ internalFieldStore.items.value = [];
140
+ }
141
+ } else for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], input?.[key], keepStart);
134
142
  } else {
135
- internalFieldStore.startInput.value = initialInput;
136
- internalFieldStore.input.value = initialInput;
143
+ if (!keepStart) internalFieldStore.startInput.value = input;
144
+ internalFieldStore.input.value = input;
137
145
  }
138
146
  });
139
147
  }
@@ -155,6 +163,9 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
155
163
  const tempIsTouched = firstInternalFieldStore.isTouched.value;
156
164
  firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
157
165
  secondInternalFieldStore.isTouched.value = tempIsTouched;
166
+ const tempIsEdited = firstInternalFieldStore.isEdited.value;
167
+ firstInternalFieldStore.isEdited.value = secondInternalFieldStore.isEdited.value;
168
+ secondInternalFieldStore.isEdited.value = tempIsEdited;
158
169
  const tempIsDirty = firstInternalFieldStore.isDirty.value;
159
170
  firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
160
171
  secondInternalFieldStore.isDirty.value = tempIsDirty;
@@ -167,22 +178,14 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
167
178
  firstInternalFieldStore.items.value = secondItems;
168
179
  secondInternalFieldStore.items.value = firstItems;
169
180
  const maxLength = Math.max(firstItems.length, secondItems.length);
170
- let firstPath;
171
- let secondPath;
172
181
  for (let index = 0; index < maxLength; index++) {
173
182
  if (!firstInternalFieldStore.children[index]) {
174
- firstPath ??= JSON.parse(firstInternalFieldStore.name);
175
183
  firstInternalFieldStore.children[index] = {};
176
- firstPath.push(index);
177
- initializeFieldStore(firstInternalFieldStore.children[index], firstInternalFieldStore.schema.item, void 0, firstPath);
178
- firstPath.pop();
184
+ initializeFieldStore(firstInternalFieldStore.children[index], firstInternalFieldStore.schema.item, void 0, [...firstInternalFieldStore.path, index]);
179
185
  }
180
186
  if (!secondInternalFieldStore.children[index]) {
181
- secondPath ??= JSON.parse(secondInternalFieldStore.name);
182
187
  secondInternalFieldStore.children[index] = {};
183
- secondPath.push(index);
184
- initializeFieldStore(secondInternalFieldStore.children[index], secondInternalFieldStore.schema.item, void 0, secondPath);
185
- secondPath.pop();
188
+ initializeFieldStore(secondInternalFieldStore.children[index], secondInternalFieldStore.schema.item, void 0, [...secondInternalFieldStore.path, index]);
186
189
  }
187
190
  swapItemState(firstInternalFieldStore.children[index], secondInternalFieldStore.children[index]);
188
191
  }
@@ -190,20 +193,27 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
190
193
  });
191
194
  });
192
195
  }
193
- // @__NO_SIDE_EFFECTS__
194
- function getFieldBool(internalFieldStore, type) {
195
- if (internalFieldStore[type].value) return true;
196
- if (internalFieldStore.kind === "array") {
197
- for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
198
- return false;
196
+ function focusFieldElement(internalFieldStore) {
197
+ for (const element of internalFieldStore.elements) {
198
+ element.focus();
199
+ if (element.getRootNode().activeElement === element) return true;
199
200
  }
200
- if (internalFieldStore.kind == "object") {
201
- for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
202
- return false;
201
+ return false;
202
+ }
203
+ function walkFieldStore(internalFieldStore, callback) {
204
+ if (callback(internalFieldStore)) return true;
205
+ if (internalFieldStore.kind === "array") {
206
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) if (walkFieldStore(internalFieldStore.children[index], callback)) return true;
207
+ } else if (internalFieldStore.kind === "object") {
208
+ for (const key in internalFieldStore.children) if (walkFieldStore(internalFieldStore.children[key], callback)) return true;
203
209
  }
204
210
  return false;
205
211
  }
206
212
  // @__NO_SIDE_EFFECTS__
213
+ function getFieldBool(internalFieldStore, type) {
214
+ return walkFieldStore(internalFieldStore, (internalFieldStore$1) => Boolean(internalFieldStore$1[type].value));
215
+ }
216
+ // @__NO_SIDE_EFFECTS__
207
217
  function getDirtyFieldInput(internalFieldStore, dirtyOnly = true) {
208
218
  if (dirtyOnly && !/* @__PURE__ */ getFieldBool(internalFieldStore, "isDirty")) return;
209
219
  if (internalFieldStore.kind === "array") {
@@ -273,32 +283,30 @@ function getFieldStore(internalFormStore, path) {
273
283
  }
274
284
  function setFieldBool(internalFieldStore, type, bool) {
275
285
  batch(() => {
276
- if (internalFieldStore.kind === "array") {
277
- internalFieldStore[type].value = bool;
278
- for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) setFieldBool(internalFieldStore.children[index], type, bool);
279
- } else if (internalFieldStore.kind == "object") for (const key in internalFieldStore.children) setFieldBool(internalFieldStore.children[key], type, bool);
280
- else internalFieldStore[type].value = bool;
286
+ untrack(() => {
287
+ walkFieldStore(internalFieldStore, (internalFieldStore$1) => {
288
+ internalFieldStore$1[type].value = bool;
289
+ });
290
+ });
281
291
  });
282
292
  }
283
293
  function setNestedInput(internalFieldStore, input) {
284
294
  internalFieldStore.isTouched.value = true;
295
+ internalFieldStore.isEdited.value = true;
285
296
  if (internalFieldStore.kind === "array") {
286
297
  const arrayInput = input ?? [];
287
298
  const items = internalFieldStore.items.value;
288
- if (arrayInput.length < items.length) internalFieldStore.items.value = items.slice(0, arrayInput.length);
289
- else if (arrayInput.length > items.length) {
290
- if (arrayInput.length > internalFieldStore.children.length) {
291
- const path = JSON.parse(internalFieldStore.name);
292
- for (let index = internalFieldStore.children.length; index < arrayInput.length; index++) {
293
- internalFieldStore.children[index] = {};
294
- path.push(index);
295
- initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, arrayInput[index], path);
296
- path.pop();
297
- }
299
+ const length = internalFieldStore.schema.type === "array" ? arrayInput.length : internalFieldStore.children.length;
300
+ if (length < items.length) internalFieldStore.items.value = items.slice(0, length);
301
+ else if (length > items.length) {
302
+ for (let index = items.length; index < length; index++) if (internalFieldStore.children[index]) resetItemState(internalFieldStore.children[index], arrayInput[index], true);
303
+ else {
304
+ internalFieldStore.children[index] = {};
305
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, arrayInput[index], [...internalFieldStore.path, index]);
298
306
  }
299
- internalFieldStore.items.value = [...items, ...arrayInput.slice(items.length).map(createId)];
307
+ internalFieldStore.items.value = [...items, ...Array.from({ length: length - items.length }, createId)];
300
308
  }
301
- for (let index = 0; index < arrayInput.length; index++) setNestedInput(internalFieldStore.children[index], arrayInput[index]);
309
+ for (let index = 0; index < length; index++) setNestedInput(internalFieldStore.children[index], arrayInput[index]);
302
310
  internalFieldStore.input.value = input == null ? input : true;
303
311
  internalFieldStore.isDirty.value = internalFieldStore.startInput.value !== internalFieldStore.input.value || internalFieldStore.startItems.value.length !== internalFieldStore.items.value.length;
304
312
  } else if (internalFieldStore.kind === "object") {
@@ -326,30 +334,21 @@ function setFieldInput(internalFormStore, path, input) {
326
334
  function setInitialFieldInput(internalFieldStore, initialInput) {
327
335
  batch(() => {
328
336
  if (internalFieldStore.kind === "array") {
329
- internalFieldStore.input.value = initialInput == null ? initialInput : true;
337
+ internalFieldStore.initialInput.value = initialInput == null ? initialInput : true;
330
338
  const initialArrayInput = initialInput ?? [];
331
- if (initialArrayInput.length > internalFieldStore.children.length) {
332
- const path = JSON.parse(internalFieldStore.name);
333
- for (let index = internalFieldStore.children.length; index < initialArrayInput.length; index++) {
334
- internalFieldStore.children[index] = {};
335
- path.push(index);
336
- initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, initialArrayInput[index], path);
337
- path.pop();
338
- }
339
+ const length = internalFieldStore.schema.type === "array" ? initialArrayInput.length : internalFieldStore.children.length;
340
+ if (length > internalFieldStore.children.length) for (let index = internalFieldStore.children.length; index < length; index++) {
341
+ internalFieldStore.children[index] = {};
342
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, initialArrayInput[index], [...internalFieldStore.path, index]);
339
343
  }
340
- internalFieldStore.initialItems.value = initialArrayInput.map(createId);
344
+ internalFieldStore.initialItems.value = Array.from({ length }, createId);
341
345
  for (let index = 0; index < internalFieldStore.children.length; index++) setInitialFieldInput(internalFieldStore.children[index], initialArrayInput[index]);
342
346
  } else if (internalFieldStore.kind === "object") {
343
- internalFieldStore.input.value = initialInput == null ? initialInput : true;
347
+ internalFieldStore.initialInput.value = initialInput == null ? initialInput : true;
344
348
  for (const key in internalFieldStore.children) setInitialFieldInput(internalFieldStore.children[key], initialInput?.[key]);
345
349
  } else internalFieldStore.initialInput.value = initialInput;
346
350
  });
347
351
  }
348
- function walkFieldStore(internalFieldStore, callback) {
349
- callback(internalFieldStore);
350
- if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
351
- else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) walkFieldStore(internalFieldStore.children[key], callback);
352
- }
353
352
  function createFormStore(config, parse) {
354
353
  const store = {};
355
354
  initializeFieldStore(store, config.schema, config.initialInput, []);
@@ -365,44 +364,51 @@ function createFormStore(config, parse) {
365
364
  async function validateFormInput(internalFormStore, config) {
366
365
  internalFormStore.validators++;
367
366
  internalFormStore.isValidating.value = true;
368
- const result = await internalFormStore.parse(untrack(() => /* @__PURE__ */ getFieldInput(internalFormStore)));
369
- let rootErrors;
370
- let nestedErrors;
371
- if (result.issues) {
372
- nestedErrors = {};
373
- for (const issue of result.issues) if (issue.path) {
374
- const path = [];
375
- for (const pathItem of issue.path) {
376
- const key = pathItem.key;
377
- const keyType = typeof key;
378
- const itemType = pathItem.type;
379
- if (keyType !== "string" && keyType !== "number" || itemType === "map" || itemType === "set") break;
380
- path.push(key);
381
- }
382
- const name = JSON.stringify(path);
383
- const fieldErrors = nestedErrors[name];
384
- if (fieldErrors) fieldErrors.push(issue.message);
385
- else nestedErrors[name] = [issue.message];
386
- } else if (rootErrors) rootErrors.push(issue.message);
387
- else rootErrors = [issue.message];
388
- }
389
- let shouldFocus = config?.shouldFocus ?? false;
390
- batch(() => {
391
- walkFieldStore(internalFormStore, (internalFieldStore) => {
392
- if (internalFieldStore.name === "[]") internalFieldStore.errors.value = rootErrors ?? null;
393
- else {
394
- const fieldErrors = nestedErrors?.[internalFieldStore.name] ?? null;
395
- internalFieldStore.errors.value = fieldErrors;
396
- if (shouldFocus && fieldErrors) {
397
- internalFieldStore.elements[0]?.focus();
398
- shouldFocus = false;
367
+ try {
368
+ const result = await internalFormStore.parse(untrack(() => /* @__PURE__ */ getFieldInput(internalFormStore)));
369
+ let rootErrors;
370
+ let nestedErrors;
371
+ if (result.issues) {
372
+ nestedErrors = {};
373
+ for (const issue of result.issues) if (issue.path) {
374
+ const path = [];
375
+ for (const pathItem of issue.path) {
376
+ const key = pathItem.key;
377
+ const keyType = typeof key;
378
+ const itemType = pathItem.type;
379
+ if (keyType !== "string" && keyType !== "number" || itemType === "map" || itemType === "set") break;
380
+ path.push(key);
399
381
  }
400
- }
382
+ const name = JSON.stringify(path);
383
+ const fieldErrors = nestedErrors[name];
384
+ if (fieldErrors) fieldErrors.push(issue.message);
385
+ else nestedErrors[name] = [issue.message];
386
+ } else if (rootErrors) rootErrors.push(issue.message);
387
+ else rootErrors = [issue.message];
388
+ }
389
+ let shouldFocus = config?.shouldFocus ?? false;
390
+ batch(() => {
391
+ untrack(() => {
392
+ walkFieldStore(internalFormStore, (internalFieldStore) => {
393
+ if (internalFieldStore.path.length === 0) internalFieldStore.errors.value = rootErrors ?? null;
394
+ else {
395
+ const fieldErrors = nestedErrors?.[internalFieldStore.name] ?? null;
396
+ internalFieldStore.errors.value = fieldErrors;
397
+ if (shouldFocus && fieldErrors && focusFieldElement(internalFieldStore)) shouldFocus = false;
398
+ }
399
+ });
400
+ });
401
+ internalFormStore.validators--;
402
+ internalFormStore.isValidating.value = internalFormStore.validators > 0;
401
403
  });
402
- internalFormStore.validators--;
403
- internalFormStore.isValidating.value = internalFormStore.validators > 0;
404
- });
405
- return result;
404
+ return result;
405
+ } catch (error) {
406
+ batch(() => {
407
+ internalFormStore.validators--;
408
+ internalFormStore.isValidating.value = internalFormStore.validators > 0;
409
+ });
410
+ throw error;
411
+ }
406
412
  }
407
413
  function validateIfRequired(internalFormStore, internalFieldStore, validationMode) {
408
414
  if (validationMode === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => /* @__PURE__ */ getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
@@ -411,18 +417,29 @@ var INTERNAL = "~internal";
411
417
 
412
418
  // ../../packages/methods/dist/index.solid.js
413
419
  function focus(form, config) {
414
- getFieldStore(form[INTERNAL], config.path).elements[0]?.focus();
420
+ focusFieldElement(getFieldStore(form[INTERNAL], config.path));
421
+ }
422
+ // @__NO_SIDE_EFFECTS__
423
+ function getDeepErrorEntries(form, config) {
424
+ const entries = [];
425
+ walkFieldStore(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], (internalFieldStore) => {
426
+ const errors = internalFieldStore.errors.value;
427
+ if (errors) entries.push({
428
+ path: internalFieldStore.path,
429
+ errors
430
+ });
431
+ });
432
+ return entries;
415
433
  }
416
434
  // @__NO_SIDE_EFFECTS__
417
- function getAllErrors(form) {
418
- let allErrors = null;
419
- walkFieldStore(form[INTERNAL], (internalFieldStore) => {
420
- if (internalFieldStore.kind === "array") internalFieldStore.items.value;
435
+ function getDeepErrors(form, config) {
436
+ let deepErrors = null;
437
+ walkFieldStore(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], (internalFieldStore) => {
421
438
  const errors = internalFieldStore.errors.value;
422
- if (errors) if (allErrors) allErrors.push(...errors);
423
- else allErrors = [...errors];
439
+ if (errors) if (deepErrors) deepErrors.push(...errors);
440
+ else deepErrors = [...errors];
424
441
  });
425
- return allErrors;
442
+ return deepErrors;
426
443
  }
427
444
  // @__NO_SIDE_EFFECTS__
428
445
  function getDirtyInput(form, config) {
@@ -430,9 +447,8 @@ function getDirtyInput(form, config) {
430
447
  }
431
448
  // @__NO_SIDE_EFFECTS__
432
449
  function getDirtyPaths(form, config) {
433
- config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL];
434
450
  const paths = [];
435
- config?.path && [...config.path];
451
+ config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL];
436
452
  return paths;
437
453
  }
438
454
  // @__NO_SIDE_EFFECTS__
@@ -476,25 +492,38 @@ function insert(form, config) {
476
492
  internalArrayStore.items.value = newItems;
477
493
  for (let index = items.length; index > insertIndex; index--) {
478
494
  if (!internalArrayStore.children[index]) {
479
- const path = JSON.parse(internalArrayStore.name);
480
495
  internalArrayStore.children[index] = {};
481
- path.push(index);
482
- initializeFieldStore(internalArrayStore.children[index], internalArrayStore.schema.item, void 0, path);
496
+ initializeFieldStore(internalArrayStore.children[index], internalArrayStore.schema.item, void 0, [...internalArrayStore.path, index]);
483
497
  }
484
498
  copyItemState(internalArrayStore.children[index - 1], internalArrayStore.children[index]);
485
499
  }
486
500
  if (!internalArrayStore.children[insertIndex]) {
487
- const path = JSON.parse(internalArrayStore.name);
488
501
  internalArrayStore.children[insertIndex] = {};
489
- path.push(insertIndex);
490
- initializeFieldStore(internalArrayStore.children[insertIndex], internalArrayStore.schema.item, config.initialInput, path);
502
+ initializeFieldStore(internalArrayStore.children[insertIndex], internalArrayStore.schema.item, config.initialInput, [...internalArrayStore.path, insertIndex]);
491
503
  } else resetItemState(internalArrayStore.children[insertIndex], config.initialInput);
492
504
  internalArrayStore.input.value = true;
493
505
  internalArrayStore.isTouched.value = true;
506
+ internalArrayStore.isEdited.value = true;
494
507
  internalArrayStore.isDirty.value = true;
495
508
  validateIfRequired(internalFormStore, internalArrayStore, "input");
496
509
  });
497
510
  }
511
+ // @__NO_SIDE_EFFECTS__
512
+ function isDirty(form, config) {
513
+ return getFieldBool(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], "isDirty");
514
+ }
515
+ // @__NO_SIDE_EFFECTS__
516
+ function isEdited(form, config) {
517
+ return getFieldBool(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], "isEdited");
518
+ }
519
+ // @__NO_SIDE_EFFECTS__
520
+ function isTouched(form, config) {
521
+ return getFieldBool(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], "isTouched");
522
+ }
523
+ // @__NO_SIDE_EFFECTS__
524
+ function isValid(form, config) {
525
+ return !getFieldBool(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], "errors");
526
+ }
498
527
  function move(form, config) {
499
528
  const internalFormStore = form[INTERNAL];
500
529
  const internalArrayStore = getFieldStore(internalFormStore, config.path);
@@ -510,6 +539,7 @@ function move(form, config) {
510
539
  else for (let index = config.from; index > config.to; index--) copyItemState(internalArrayStore.children[index - 1], internalArrayStore.children[index]);
511
540
  copyItemState(tempInternalFieldStore, internalArrayStore.children[config.to]);
512
541
  internalArrayStore.isTouched.value = true;
542
+ internalArrayStore.isEdited.value = true;
513
543
  internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
514
544
  validateIfRequired(internalFormStore, internalArrayStore, "input");
515
545
  });
@@ -542,6 +572,7 @@ function remove(form, config) {
542
572
  internalArrayStore.items.value = newItems;
543
573
  for (let index = config.at; index < items.length - 1; index++) copyItemState(internalArrayStore.children[index + 1], internalArrayStore.children[index]);
544
574
  internalArrayStore.isTouched.value = true;
575
+ internalArrayStore.isEdited.value = true;
545
576
  internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
546
577
  validateIfRequired(internalFormStore, internalArrayStore, "input");
547
578
  });
@@ -556,6 +587,7 @@ function replace(form, config) {
556
587
  internalArrayStore.items.value = newItems;
557
588
  resetItemState(internalArrayStore.children[config.at], config.initialInput);
558
589
  internalArrayStore.isTouched.value = true;
590
+ internalArrayStore.isEdited.value = true;
559
591
  internalArrayStore.isDirty.value = true;
560
592
  validateIfRequired(internalFormStore, internalArrayStore, "input");
561
593
  });
@@ -570,6 +602,7 @@ function reset(form, config) {
570
602
  internalFieldStore$1.elements = internalFieldStore$1.initialElements;
571
603
  if (!config?.keepErrors) internalFieldStore$1.errors.value = null;
572
604
  if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
605
+ if (!config?.keepEdited) internalFieldStore$1.isEdited.value = false;
573
606
  internalFieldStore$1.startInput.value = internalFieldStore$1.initialInput.value;
574
607
  if (!config?.keepInput) internalFieldStore$1.input.value = internalFieldStore$1.initialInput.value;
575
608
  if (internalFieldStore$1.kind === "array") {
@@ -616,6 +649,7 @@ function swap(form, config) {
616
649
  internalArrayStore.items.value = newItems;
617
650
  swapItemState(internalArrayStore.children[config.at], internalArrayStore.children[config.and]);
618
651
  internalArrayStore.isTouched.value = true;
652
+ internalArrayStore.isEdited.value = true;
619
653
  internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
620
654
  validateIfRequired(internalFormStore, internalArrayStore, "input");
621
655
  });
@@ -636,6 +670,9 @@ function createForm(config) {
636
670
  const getIsTouched = createMemo(
637
671
  () => getFieldBool(internalFormStore, "isTouched")
638
672
  );
673
+ const getIsEdited = createMemo(
674
+ () => getFieldBool(internalFormStore, "isEdited")
675
+ );
639
676
  const getIsDirty = createMemo(
640
677
  () => getFieldBool(internalFormStore, "isDirty")
641
678
  );
@@ -656,6 +693,9 @@ function createForm(config) {
656
693
  get isTouched() {
657
694
  return getIsTouched();
658
695
  },
696
+ get isEdited() {
697
+ return getIsEdited();
698
+ },
659
699
  get isDirty() {
660
700
  return getIsDirty();
661
701
  },
@@ -695,6 +735,9 @@ function useField(form, config) {
695
735
  const getIsTouched = createMemo2(
696
736
  () => getFieldBool(getInternalFieldStore(), "isTouched")
697
737
  );
738
+ const getIsEdited = createMemo2(
739
+ () => getFieldBool(getInternalFieldStore(), "isEdited")
740
+ );
698
741
  const getIsDirty = createMemo2(
699
742
  () => getFieldBool(getInternalFieldStore(), "isDirty")
700
743
  );
@@ -714,6 +757,9 @@ function useField(form, config) {
714
757
  get isTouched() {
715
758
  return getIsTouched();
716
759
  },
760
+ get isEdited() {
761
+ return getIsEdited();
762
+ },
717
763
  get isDirty() {
718
764
  return getIsDirty();
719
765
  },
@@ -738,9 +784,13 @@ function useField(form, config) {
738
784
  const internalFieldStore = getInternalFieldStore();
739
785
  internalFieldStore.elements.push(element);
740
786
  onCleanup(() => {
741
- internalFieldStore.elements = internalFieldStore.elements.filter(
787
+ const elements = internalFieldStore.elements.filter(
742
788
  (el) => el !== element
743
789
  );
790
+ if (internalFieldStore.elements === internalFieldStore.initialElements) {
791
+ internalFieldStore.initialElements = elements;
792
+ }
793
+ internalFieldStore.elements = elements;
744
794
  });
745
795
  },
746
796
  onFocus() {
@@ -791,6 +841,9 @@ function useFieldArray(form, config) {
791
841
  const getIsTouched = createMemo3(
792
842
  () => getFieldBool(getInternalFieldStore(), "isTouched")
793
843
  );
844
+ const getIsEdited = createMemo3(
845
+ () => getFieldBool(getInternalFieldStore(), "isEdited")
846
+ );
794
847
  const getIsDirty = createMemo3(
795
848
  () => getFieldBool(getInternalFieldStore(), "isDirty")
796
849
  );
@@ -810,6 +863,9 @@ function useFieldArray(form, config) {
810
863
  get isTouched() {
811
864
  return getIsTouched();
812
865
  },
866
+ get isEdited() {
867
+ return getIsEdited();
868
+ },
813
869
  get isDirty() {
814
870
  return getIsDirty();
815
871
  },
@@ -859,13 +915,18 @@ export {
859
915
  Form,
860
916
  createForm,
861
917
  focus,
862
- getAllErrors,
918
+ getDeepErrorEntries,
919
+ getDeepErrors,
863
920
  getDirtyInput,
864
921
  getDirtyPaths,
865
922
  getErrors,
866
923
  getInput,
867
924
  handleSubmit,
868
925
  insert,
926
+ isDirty,
927
+ isEdited,
928
+ isTouched,
929
+ isValid,
869
930
  move,
870
931
  pickDirty,
871
932
  remove,