@formisch/svelte 0.9.0 → 0.10.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.
@@ -14,26 +14,31 @@ function focus(form, config) {
14
14
  }
15
15
 
16
16
  //#endregion
17
- //#region src/getAllErrors/getAllErrors.ts
18
- /**
19
- * Retrieves all error messages from all fields in the form by walking through
20
- * the entire field store tree. This is useful for displaying a summary of all
21
- * validation errors across the form.
22
- *
23
- * @param form The form store to retrieve errors from.
24
- *
25
- * @returns A non-empty array of error messages, or null if no errors exist.
26
- */
17
+ //#region src/getDeepErrorEntries/getDeepErrorEntries.ts
27
18
  /* @__NO_SIDE_EFFECTS__ */
28
- function getAllErrors(form) {
29
- let allErrors = null;
30
- walkFieldStore(form[INTERNAL], (internalFieldStore) => {
31
- if (internalFieldStore.kind === "array") internalFieldStore.items.value;
19
+ function getDeepErrorEntries(form, config) {
20
+ const entries = [];
21
+ walkFieldStore(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], (internalFieldStore) => {
32
22
  const errors = internalFieldStore.errors.value;
33
- if (errors) if (allErrors) allErrors.push(...errors);
34
- else allErrors = [...errors];
23
+ if (errors) entries.push({
24
+ path: internalFieldStore.path,
25
+ errors
26
+ });
35
27
  });
36
- return allErrors;
28
+ return entries;
29
+ }
30
+
31
+ //#endregion
32
+ //#region src/getDeepErrors/getDeepErrors.ts
33
+ /* @__NO_SIDE_EFFECTS__ */
34
+ function getDeepErrors(form, config) {
35
+ let deepErrors = null;
36
+ walkFieldStore(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], (internalFieldStore) => {
37
+ const errors = internalFieldStore.errors.value;
38
+ if (errors) if (deepErrors) deepErrors.push(...errors);
39
+ else deepErrors = [...errors];
40
+ });
41
+ return deepErrors;
37
42
  }
38
43
 
39
44
  //#endregion
@@ -47,9 +52,8 @@ function getDirtyInput(form, config) {
47
52
  //#region src/getDirtyPaths/getDirtyPaths.ts
48
53
  /* @__NO_SIDE_EFFECTS__ */
49
54
  function getDirtyPaths(form, config) {
50
- config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL];
51
55
  const paths = [];
52
- config?.path && [...config.path];
56
+ config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL];
53
57
  return paths;
54
58
  }
55
59
 
@@ -112,26 +116,51 @@ function insert(form, config) {
112
116
  internalArrayStore.items.value = newItems;
113
117
  for (let index = items.length; index > insertIndex; index--) {
114
118
  if (!internalArrayStore.children[index]) {
115
- const path = JSON.parse(internalArrayStore.name);
116
119
  internalArrayStore.children[index] = {};
117
- path.push(index);
118
- initializeFieldStore(internalArrayStore.children[index], internalArrayStore.schema.item, void 0, path);
120
+ initializeFieldStore(internalArrayStore.children[index], internalArrayStore.schema.item, void 0, [...internalArrayStore.path, index]);
119
121
  }
120
122
  copyItemState(internalArrayStore.children[index - 1], internalArrayStore.children[index]);
121
123
  }
122
124
  if (!internalArrayStore.children[insertIndex]) {
123
- const path = JSON.parse(internalArrayStore.name);
124
125
  internalArrayStore.children[insertIndex] = {};
125
- path.push(insertIndex);
126
- initializeFieldStore(internalArrayStore.children[insertIndex], internalArrayStore.schema.item, config.initialInput, path);
126
+ initializeFieldStore(internalArrayStore.children[insertIndex], internalArrayStore.schema.item, config.initialInput, [...internalArrayStore.path, insertIndex]);
127
127
  } else resetItemState(internalArrayStore.children[insertIndex], config.initialInput);
128
128
  internalArrayStore.input.value = true;
129
129
  internalArrayStore.isTouched.value = true;
130
+ internalArrayStore.isEdited.value = true;
130
131
  internalArrayStore.isDirty.value = true;
131
132
  validateIfRequired(internalFormStore, internalArrayStore, "input");
132
133
  });
133
134
  }
134
135
 
136
+ //#endregion
137
+ //#region src/isDirty/isDirty.ts
138
+ /* @__NO_SIDE_EFFECTS__ */
139
+ function isDirty(form, config) {
140
+ return getFieldBool(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], "isDirty");
141
+ }
142
+
143
+ //#endregion
144
+ //#region src/isEdited/isEdited.ts
145
+ /* @__NO_SIDE_EFFECTS__ */
146
+ function isEdited(form, config) {
147
+ return getFieldBool(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], "isEdited");
148
+ }
149
+
150
+ //#endregion
151
+ //#region src/isTouched/isTouched.ts
152
+ /* @__NO_SIDE_EFFECTS__ */
153
+ function isTouched(form, config) {
154
+ return getFieldBool(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], "isTouched");
155
+ }
156
+
157
+ //#endregion
158
+ //#region src/isValid/isValid.ts
159
+ /* @__NO_SIDE_EFFECTS__ */
160
+ function isValid(form, config) {
161
+ return !getFieldBool(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL], "errors");
162
+ }
163
+
135
164
  //#endregion
136
165
  //#region src/move/move.ts
137
166
  /**
@@ -156,6 +185,7 @@ function move(form, config) {
156
185
  else for (let index = config.from; index > config.to; index--) copyItemState(internalArrayStore.children[index - 1], internalArrayStore.children[index]);
157
186
  copyItemState(tempInternalFieldStore, internalArrayStore.children[config.to]);
158
187
  internalArrayStore.isTouched.value = true;
188
+ internalArrayStore.isEdited.value = true;
159
189
  internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
160
190
  validateIfRequired(internalFormStore, internalArrayStore, "input");
161
191
  });
@@ -225,6 +255,7 @@ function remove(form, config) {
225
255
  internalArrayStore.items.value = newItems;
226
256
  for (let index = config.at; index < items.length - 1; index++) copyItemState(internalArrayStore.children[index + 1], internalArrayStore.children[index]);
227
257
  internalArrayStore.isTouched.value = true;
258
+ internalArrayStore.isEdited.value = true;
228
259
  internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
229
260
  validateIfRequired(internalFormStore, internalArrayStore, "input");
230
261
  });
@@ -248,6 +279,7 @@ function replace(form, config) {
248
279
  internalArrayStore.items.value = newItems;
249
280
  resetItemState(internalArrayStore.children[config.at], config.initialInput);
250
281
  internalArrayStore.isTouched.value = true;
282
+ internalArrayStore.isEdited.value = true;
251
283
  internalArrayStore.isDirty.value = true;
252
284
  validateIfRequired(internalFormStore, internalArrayStore, "input");
253
285
  });
@@ -265,6 +297,7 @@ function reset(form, config) {
265
297
  internalFieldStore$1.elements = internalFieldStore$1.initialElements;
266
298
  if (!config?.keepErrors) internalFieldStore$1.errors.value = null;
267
299
  if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
300
+ if (!config?.keepEdited) internalFieldStore$1.isEdited.value = false;
268
301
  internalFieldStore$1.startInput.value = internalFieldStore$1.initialInput.value;
269
302
  if (!config?.keepInput) internalFieldStore$1.input.value = internalFieldStore$1.initialInput.value;
270
303
  if (internalFieldStore$1.kind === "array") {
@@ -335,6 +368,7 @@ function swap(form, config) {
335
368
  internalArrayStore.items.value = newItems;
336
369
  swapItemState(internalArrayStore.children[config.at], internalArrayStore.children[config.and]);
337
370
  internalArrayStore.isTouched.value = true;
371
+ internalArrayStore.isEdited.value = true;
338
372
  internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
339
373
  validateIfRequired(internalFormStore, internalArrayStore, "input");
340
374
  });
@@ -357,4 +391,4 @@ function validate(form, config) {
357
391
  }
358
392
 
359
393
  //#endregion
360
- export { focus, getAllErrors, getDirtyInput, getDirtyPaths, getErrors, getInput, handleSubmit, insert, move, pickDirty, remove, replace, reset, setErrors, setInput, submit, swap, validate };
394
+ export { focus, getDeepErrorEntries, getDeepErrors, getDirtyInput, getDirtyPaths, getErrors, getInput, handleSubmit, insert, isDirty, isEdited, isTouched, isValid, move, pickDirty, remove, replace, reset, setErrors, setInput, submit, swap, validate };
@@ -10,6 +10,7 @@ export function createForm(config) {
10
10
  }
11
11
  });
12
12
  const isTouched = $derived(getFieldBool(internalFormStore, 'isTouched'));
13
+ const isEdited = $derived(getFieldBool(internalFormStore, 'isEdited'));
13
14
  const isDirty = $derived(getFieldBool(internalFormStore, 'isDirty'));
14
15
  const isValid = $derived(!getFieldBool(internalFormStore, 'errors'));
15
16
  return {
@@ -26,6 +27,9 @@ export function createForm(config) {
26
27
  get isTouched() {
27
28
  return isTouched;
28
29
  },
30
+ get isEdited() {
31
+ return isEdited;
32
+ },
29
33
  get isDirty() {
30
34
  return isDirty;
31
35
  },
@@ -8,6 +8,7 @@ export function useField(form, config) {
8
8
  const internalFieldStore = $derived(getFieldStore(internalFormStore, path));
9
9
  const input = $derived(getFieldInput(internalFieldStore));
10
10
  const isTouched = $derived(getFieldBool(internalFieldStore, 'isTouched'));
11
+ const isEdited = $derived(getFieldBool(internalFieldStore, 'isEdited'));
11
12
  const isDirty = $derived(getFieldBool(internalFieldStore, 'isDirty'));
12
13
  const isValid = $derived(!getFieldBool(internalFieldStore, 'errors'));
13
14
  return {
@@ -23,6 +24,9 @@ export function useField(form, config) {
23
24
  get isTouched() {
24
25
  return isTouched;
25
26
  },
27
+ get isEdited() {
28
+ return isEdited;
29
+ },
26
30
  get isDirty() {
27
31
  return isDirty;
28
32
  },
@@ -5,6 +5,7 @@ export function useFieldArray(form, config) {
5
5
  const path = $derived(unwrap(config).path);
6
6
  const internalFieldStore = $derived(getFieldStore(unwrap(form)[INTERNAL], path));
7
7
  const isTouched = $derived(getFieldBool(internalFieldStore, 'isTouched'));
8
+ const isEdited = $derived(getFieldBool(internalFieldStore, 'isEdited'));
8
9
  const isDirty = $derived(getFieldBool(internalFieldStore, 'isDirty'));
9
10
  const isValid = $derived(!getFieldBool(internalFieldStore, 'errors'));
10
11
  return {
@@ -20,6 +21,9 @@ export function useFieldArray(form, config) {
20
21
  get isTouched() {
21
22
  return isTouched;
22
23
  },
24
+ get isEdited() {
25
+ return isEdited;
26
+ },
23
27
  get isDirty() {
24
28
  return isDirty;
25
29
  },
@@ -54,6 +54,10 @@ export interface FieldStore<TSchema extends FormSchema = FormSchema, TFieldPath
54
54
  * Whether the field has been touched.
55
55
  */
56
56
  readonly isTouched: boolean;
57
+ /**
58
+ * Whether the field value has been edited.
59
+ */
60
+ readonly isEdited: boolean;
57
61
  /**
58
62
  * Whether the field input differs from its initial value.
59
63
  */
@@ -91,6 +95,10 @@ export interface FieldArrayStore<TSchema extends FormSchema = FormSchema, TField
91
95
  * Whether the field array has been touched.
92
96
  */
93
97
  readonly isTouched: boolean;
98
+ /**
99
+ * Whether the field array value has been edited.
100
+ */
101
+ readonly isEdited: boolean;
94
102
  /**
95
103
  * Whether the field array input differs from its initial value.
96
104
  */
@@ -19,6 +19,10 @@ export interface FormStore<TSchema extends FormSchema = FormSchema> extends Base
19
19
  * Whether any field in the form has been touched.
20
20
  */
21
21
  readonly isTouched: boolean;
22
+ /**
23
+ * Whether any field in the form has been edited.
24
+ */
25
+ readonly isEdited: boolean;
22
26
  /**
23
27
  * Whether any field in the form differs from its initial value.
24
28
  */
@@ -31,7 +35,7 @@ export interface FormStore<TSchema extends FormSchema = FormSchema> extends Base
31
35
  * The current error messages of the form.
32
36
  *
33
37
  * Hint: This property only contains validation errors at the root level
34
- * of the form. To get all errors from all fields, use `getAllErrors`.
38
+ * of the form. To get all errors from all fields, use `getDeepErrors`.
35
39
  */
36
40
  readonly errors: [string, ...string[]] | null;
37
41
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@formisch/svelte",
3
3
  "description": "The lightweight, schema-first, and fully type-safe form library for Svelte",
4
- "version": "0.9.0",
4
+ "version": "0.10.0",
5
5
  "license": "MIT",
6
6
  "author": "Fabian Hiller",
7
7
  "homepage": "https://formisch.dev",