@formisch/svelte 0.1.0 → 0.2.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.
@@ -24,29 +24,34 @@ interface InternalBaseStore {
24
24
  kind: "array" | "object" | "value";
25
25
  name: string;
26
26
  schema: Schema;
27
+ initialElements: FieldElement[];
27
28
  elements: FieldElement[];
28
29
  errors: Signal<[string, ...string[]] | null>;
30
+ isTouched: Signal<boolean>;
31
+ isDirty: Signal<boolean>;
29
32
  }
30
33
  interface InternalArrayStore extends InternalBaseStore {
31
34
  kind: "array";
32
35
  children: InternalFieldStore[];
36
+ initialInput: Signal<true | null | undefined>;
37
+ startInput: Signal<true | null | undefined>;
38
+ input: Signal<true | null | undefined>;
33
39
  initialItems: Signal<string[]>;
34
40
  startItems: Signal<string[]>;
35
41
  items: Signal<string[]>;
36
- isTouched: Signal<boolean>;
37
- isDirty: Signal<boolean>;
38
42
  }
39
43
  interface InternalObjectStore extends InternalBaseStore {
40
44
  kind: "object";
41
45
  children: Record<string, InternalFieldStore>;
46
+ initialInput: Signal<true | null | undefined>;
47
+ startInput: Signal<true | null | undefined>;
48
+ input: Signal<true | null | undefined>;
42
49
  }
43
50
  interface InternalValueStore extends InternalBaseStore {
44
51
  kind: "value";
45
52
  initialInput: Signal<unknown>;
46
53
  startInput: Signal<unknown>;
47
54
  input: Signal<unknown>;
48
- isTouched: Signal<boolean>;
49
- isDirty: Signal<boolean>;
50
55
  }
51
56
  type InternalFieldStore = InternalArrayStore | InternalObjectStore | InternalValueStore;
52
57
  //#endregion
@@ -218,13 +223,13 @@ type FieldSchema = v.ArraySchema<v.BaseSchema<unknown, unknown, v.BaseIssue<unkn
218
223
  * TODO: Add comment
219
224
  * TODO: Should this stay in /primitives or move to /utils?
220
225
  */
221
- declare function initializeFieldStore(internalFieldStore: Partial<InternalFieldStore>, schema: FieldSchema, initialInput: unknown, path: PathKey[]): void;
226
+ declare function initializeFieldStore(internalFieldStore: Partial<InternalFieldStore>, schema: FieldSchema, initialInput: unknown, path: PathKey[], nullish?: boolean): void;
222
227
  //#endregion
223
228
  //#region src/field/setFieldBool/setFieldBool.d.ts
224
229
  declare function setFieldBool(internalFieldStore: InternalFieldStore, type: "isTouched" | "isDirty", bool: boolean): void;
225
230
  //#endregion
226
231
  //#region src/field/setFieldInput/setFieldInput.d.ts
227
- declare function setFieldInput(internalFieldStore: InternalFieldStore, input: unknown): void;
232
+ declare function setFieldInput(internalFormStore: InternalFormStore, path: Path, input: unknown): void;
228
233
  //#endregion
229
234
  //#region src/field/setInitialFieldInput/setInitialFieldInput.d.ts
230
235
  declare function setInitialFieldInput(internalFieldStore: InternalFieldStore, initialInput: unknown): void;
@@ -242,7 +247,7 @@ interface ValidateFormInputConfig {
242
247
  declare function validateFormInput(internalFormStore: InternalFormStore, config?: ValidateFormInputConfig): Promise<v.SafeParseResult<Schema>>;
243
248
  //#endregion
244
249
  //#region src/form/validateIfRequired/validateIfRequired.d.ts
245
- declare function validateIfRequired(internalFormStore: InternalFormStore, internalFieldStore: InternalFieldStore, validationModes: ValidationMode): void;
250
+ declare function validateIfRequired(internalFormStore: InternalFormStore, internalFieldStore: InternalFieldStore, validationMode: ValidationMode): void;
246
251
  //#endregion
247
252
  //#region src/framework/index.d.ts
248
253
  type Framework = "preact" | "qwik" | "solid" | "svelte" | "vue";
@@ -27,16 +27,21 @@ function batch(fn) {
27
27
  * TODO: Add comment
28
28
  * TODO: Should this stay in /primitives or move to /utils?
29
29
  */
30
- function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
30
+ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nullish = false) {
31
31
  if (framework === "qwik" && schema.type === "lazy" || schema.type === "object_with_rest" || schema.type === "record" || schema.type === "tuple_with_rest" || schema.type === "promise") throw new Error(`"${schema.type}" schema is not supported`);
32
32
  else if (schema.type === "lazy") initializeFieldStore(internalFieldStore, schema.getter(void 0), initialInput, path);
33
- else if (schema.type === "exact_optional" || schema.type === "non_nullable" || schema.type === "non_nullish" || schema.type === "non_optional" || schema.type === "nullable" || schema.type === "nullish" || schema.type === "optional" || schema.type === "undefinedable") initializeFieldStore(internalFieldStore, schema.wrapped, initialInput ?? v.getDefault(schema), path);
33
+ else if (schema.type === "exact_optional" || schema.type === "nullable" || schema.type === "nullish" || schema.type === "optional" || schema.type === "undefinedable") initializeFieldStore(internalFieldStore, schema.wrapped, initialInput ?? v.getDefault(schema), path, true);
34
+ else if (schema.type === "non_nullable" || schema.type === "non_nullish" || schema.type === "non_optional") initializeFieldStore(internalFieldStore, schema.wrapped, initialInput, path);
34
35
  else if (schema.type === "intersect" || schema.type === "union" || schema.type === "variant") for (const schemaOption of schema.options) initializeFieldStore(internalFieldStore, schemaOption, initialInput, path);
35
36
  else {
36
37
  internalFieldStore.schema = schema;
37
38
  internalFieldStore.name = JSON.stringify(path);
38
- internalFieldStore.elements = [];
39
+ const initialElements = [];
40
+ internalFieldStore.initialElements = initialElements;
41
+ internalFieldStore.elements = initialElements;
39
42
  internalFieldStore.errors = createSignal(null);
43
+ internalFieldStore.isTouched = createSignal(false);
44
+ internalFieldStore.isDirty = createSignal(false);
40
45
  if (schema.type === "array" || schema.type === "loose_tuple" || schema.type === "strict_tuple" || schema.type === "tuple") {
41
46
  if (internalFieldStore.kind && internalFieldStore.kind !== "array") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "array"`);
42
47
  internalFieldStore.kind = "array";
@@ -52,15 +57,17 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
52
57
  } else for (let index = 0; index < schema.items; index++) {
53
58
  internalFieldStore.children[index] = {};
54
59
  path.push(index);
55
- initializeFieldStore(internalFieldStore.children[index], schema.items[index], initialInput && initialInput[index], path);
60
+ initializeFieldStore(internalFieldStore.children[index], schema.items[index], initialInput?.[index], path);
56
61
  path.pop();
57
62
  }
63
+ const arrayInput = nullish && initialInput == null ? initialInput : true;
64
+ internalFieldStore.initialInput = createSignal(arrayInput);
65
+ internalFieldStore.startInput = createSignal(arrayInput);
66
+ internalFieldStore.input = createSignal(arrayInput);
58
67
  const initialItems = internalFieldStore.children.map(createId);
59
68
  internalFieldStore.initialItems = createSignal(initialItems);
60
69
  internalFieldStore.startItems = createSignal(initialItems);
61
70
  internalFieldStore.items = createSignal(initialItems);
62
- internalFieldStore.isTouched = createSignal(false);
63
- internalFieldStore.isDirty = createSignal(false);
64
71
  }
65
72
  } else if (schema.type === "loose_object" || schema.type === "object" || schema.type === "strict_object") {
66
73
  if (internalFieldStore.kind && internalFieldStore.kind !== "object") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "object"`);
@@ -70,9 +77,13 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
70
77
  for (const key in schema.entries) {
71
78
  internalFieldStore.children[key] = {};
72
79
  path.push(key);
73
- initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput && initialInput[key], path);
80
+ initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput?.[key], path);
74
81
  path.pop();
75
82
  }
83
+ const objectInput = nullish && initialInput == null ? initialInput : true;
84
+ internalFieldStore.initialInput = createSignal(objectInput);
85
+ internalFieldStore.startInput = createSignal(objectInput);
86
+ internalFieldStore.input = createSignal(objectInput);
76
87
  }
77
88
  } else {
78
89
  internalFieldStore.kind = "value";
@@ -80,8 +91,6 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
80
91
  internalFieldStore.initialInput = createSignal(initialInput);
81
92
  internalFieldStore.startInput = createSignal(initialInput);
82
93
  internalFieldStore.input = createSignal(initialInput);
83
- internalFieldStore.isTouched = createSignal(false);
84
- internalFieldStore.isDirty = createSignal(false);
85
94
  }
86
95
  }
87
96
  }
@@ -101,10 +110,14 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
101
110
  function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
102
111
  batch(() => {
103
112
  untrack(() => {
113
+ toInternalFieldStore.elements = fromInternalFieldStore.elements;
114
+ toInternalFieldStore.errors.value = fromInternalFieldStore.errors.value;
115
+ toInternalFieldStore.startInput.value = fromInternalFieldStore.startInput.value;
116
+ toInternalFieldStore.input.value = fromInternalFieldStore.input.value;
117
+ toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
118
+ toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
104
119
  if (fromInternalFieldStore.kind === "array" && toInternalFieldStore.kind === "array") {
105
120
  const fromItems = fromInternalFieldStore.items.value;
106
- toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
107
- toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
108
121
  toInternalFieldStore.startItems.value = fromInternalFieldStore.startItems.value;
109
122
  toInternalFieldStore.items.value = fromItems;
110
123
  let path;
@@ -119,12 +132,6 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
119
132
  copyItemState(fromInternalFieldStore.children[index], toInternalFieldStore.children[index]);
120
133
  }
121
134
  } else if (fromInternalFieldStore.kind === "object" && toInternalFieldStore.kind === "object") for (const key in fromInternalFieldStore.children) copyItemState(fromInternalFieldStore.children[key], toInternalFieldStore.children[key]);
122
- else if (fromInternalFieldStore.kind === "value" && toInternalFieldStore.kind === "value") {
123
- toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
124
- toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
125
- toInternalFieldStore.startInput.value = fromInternalFieldStore.startInput.value;
126
- toInternalFieldStore.input.value = fromInternalFieldStore.input.value;
127
- }
128
135
  });
129
136
  });
130
137
  }
@@ -142,11 +149,15 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
142
149
  */
143
150
  function resetItemState(internalFieldStore, initialInput) {
144
151
  batch(() => {
152
+ internalFieldStore.elements = [];
145
153
  internalFieldStore.errors.value = null;
146
- if (internalFieldStore.kind === "array") {
147
- internalFieldStore.isTouched.value = false;
148
- internalFieldStore.isDirty.value = false;
149
- if (initialInput) {
154
+ internalFieldStore.isTouched.value = false;
155
+ internalFieldStore.isDirty.value = false;
156
+ if (internalFieldStore.kind === "array" || internalFieldStore.kind === "object") {
157
+ const objectInput = initialInput == null ? initialInput : true;
158
+ internalFieldStore.startInput.value = objectInput;
159
+ internalFieldStore.input.value = objectInput;
160
+ if (internalFieldStore.kind === "array") if (initialInput) {
150
161
  const newItems = initialInput.map(createId);
151
162
  internalFieldStore.startItems.value = newItems;
152
163
  internalFieldStore.items.value = newItems;
@@ -155,10 +166,8 @@ function resetItemState(internalFieldStore, initialInput) {
155
166
  internalFieldStore.startItems.value = [];
156
167
  internalFieldStore.items.value = [];
157
168
  }
158
- } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], initialInput?.[key]);
159
- else {
160
- internalFieldStore.isTouched.value = false;
161
- internalFieldStore.isDirty.value = false;
169
+ else for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], initialInput?.[key]);
170
+ } else {
162
171
  internalFieldStore.startInput.value = initialInput;
163
172
  internalFieldStore.input.value = initialInput;
164
173
  }
@@ -178,15 +187,27 @@ function resetItemState(internalFieldStore, initialInput) {
178
187
  function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
179
188
  batch(() => {
180
189
  untrack(() => {
190
+ const tempElements = firstInternalFieldStore.elements;
191
+ firstInternalFieldStore.elements = secondInternalFieldStore.elements;
192
+ secondInternalFieldStore.elements = tempElements;
193
+ const tempErrors = firstInternalFieldStore.errors.value;
194
+ firstInternalFieldStore.errors.value = secondInternalFieldStore.errors.value;
195
+ secondInternalFieldStore.errors.value = tempErrors;
196
+ const tempStartInput = firstInternalFieldStore.startInput.value;
197
+ firstInternalFieldStore.startInput.value = secondInternalFieldStore.startInput.value;
198
+ secondInternalFieldStore.startInput.value = tempStartInput;
199
+ const tempInput = firstInternalFieldStore.input.value;
200
+ firstInternalFieldStore.input.value = secondInternalFieldStore.input.value;
201
+ secondInternalFieldStore.input.value = tempInput;
202
+ const tempIsTouched = firstInternalFieldStore.isTouched.value;
203
+ firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
204
+ secondInternalFieldStore.isTouched.value = tempIsTouched;
205
+ const tempIsDirty = firstInternalFieldStore.isDirty.value;
206
+ firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
207
+ secondInternalFieldStore.isDirty.value = tempIsDirty;
181
208
  if (firstInternalFieldStore.kind === "array" && secondInternalFieldStore.kind === "array") {
182
209
  const firstItems = firstInternalFieldStore.items.value;
183
210
  const secondItems = secondInternalFieldStore.items.value;
184
- const tempIsTouched = firstInternalFieldStore.isTouched.value;
185
- firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
186
- secondInternalFieldStore.isTouched.value = tempIsTouched;
187
- const tempIsDirty = firstInternalFieldStore.isDirty.value;
188
- firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
189
- secondInternalFieldStore.isDirty.value = tempIsDirty;
190
211
  const tempStartItems = firstInternalFieldStore.startItems.value;
191
212
  firstInternalFieldStore.startItems.value = secondInternalFieldStore.startItems.value;
192
213
  secondInternalFieldStore.startItems.value = tempStartItems;
@@ -213,20 +234,6 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
213
234
  swapItemState(firstInternalFieldStore.children[index], secondInternalFieldStore.children[index]);
214
235
  }
215
236
  } else if (firstInternalFieldStore.kind === "object" && secondInternalFieldStore.kind === "object") for (const key in firstInternalFieldStore.children) swapItemState(firstInternalFieldStore.children[key], secondInternalFieldStore.children[key]);
216
- else if (firstInternalFieldStore.kind === "value" && secondInternalFieldStore.kind === "value") {
217
- const tempIsTouched = firstInternalFieldStore.isTouched.value;
218
- firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
219
- secondInternalFieldStore.isTouched.value = tempIsTouched;
220
- const tempIsDirty = firstInternalFieldStore.isDirty.value;
221
- firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
222
- secondInternalFieldStore.isDirty.value = tempIsDirty;
223
- const tempStartInput = firstInternalFieldStore.startInput.value;
224
- firstInternalFieldStore.startInput.value = secondInternalFieldStore.startInput.value;
225
- secondInternalFieldStore.startInput.value = tempStartInput;
226
- const tempInput = firstInternalFieldStore.input.value;
227
- firstInternalFieldStore.input.value = secondInternalFieldStore.input.value;
228
- secondInternalFieldStore.input.value = tempInput;
229
- }
230
237
  });
231
238
  });
232
239
  }
@@ -235,14 +242,20 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
235
242
  //#region src/field/getFieldInput/getFieldInput.ts
236
243
  function getFieldInput(internalFieldStore) {
237
244
  if (internalFieldStore.kind === "array") {
238
- const value = [];
239
- for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
240
- return value;
245
+ if (internalFieldStore.input.value) {
246
+ const value = [];
247
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
248
+ return value;
249
+ }
250
+ return internalFieldStore.input.value;
241
251
  }
242
252
  if (internalFieldStore.kind === "object") {
243
- const value = {};
244
- for (const key in internalFieldStore.children) value[key] = getFieldInput(internalFieldStore.children[key]);
245
- return value;
253
+ if (internalFieldStore.input.value) {
254
+ const value = {};
255
+ for (const key in internalFieldStore.children) value[key] = getFieldInput(internalFieldStore.children[key]);
256
+ return value;
257
+ }
258
+ return internalFieldStore.input.value;
246
259
  }
247
260
  return internalFieldStore.input.value;
248
261
  }
@@ -279,17 +292,16 @@ function getElementInput(element, internalFieldStore) {
279
292
  //#endregion
280
293
  //#region src/field/getFieldBool/getFieldBool.ts
281
294
  function getFieldBool(internalFieldStore, type) {
295
+ if (internalFieldStore[type].value) return true;
282
296
  if (internalFieldStore.kind === "array") {
283
- if (internalFieldStore[type].value) return true;
284
297
  for (let index = 0; index < internalFieldStore.items.value.length; index++) if (getFieldBool(internalFieldStore.children[index], type)) return true;
285
298
  return false;
286
299
  }
287
300
  if (internalFieldStore.kind == "object") {
288
- if (type === "errors" && internalFieldStore[type].value) return true;
289
301
  for (const key in internalFieldStore.children) if (getFieldBool(internalFieldStore.children[key], type)) return true;
290
302
  return false;
291
303
  }
292
- return !!internalFieldStore[type].value;
304
+ return false;
293
305
  }
294
306
 
295
307
  //#endregion
@@ -314,32 +326,47 @@ function setFieldBool(internalFieldStore, type, bool) {
314
326
 
315
327
  //#endregion
316
328
  //#region src/field/setFieldInput/setFieldInput.ts
317
- function setFieldInput(internalFieldStore, input) {
318
- batch(() => {
319
- if (internalFieldStore.kind === "array") {
320
- const items = untrack(() => internalFieldStore.items.value);
321
- if (input.length < items.length) internalFieldStore.items.value = items.slice(0, input.length);
322
- else if (input.length > items.length) {
323
- if (input.length > internalFieldStore.children.length) {
324
- const path = JSON.parse(internalFieldStore.name);
325
- for (let index = internalFieldStore.children.length; index < input.length; index++) {
326
- internalFieldStore.children[index] = {};
327
- path.push(index);
328
- initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, input[index], path);
329
- path.pop();
330
- }
329
+ function setNestedInput(internalFieldStore, input) {
330
+ internalFieldStore.isTouched.value = true;
331
+ if (internalFieldStore.kind === "array") {
332
+ const arrayInput = input ?? [];
333
+ const items = internalFieldStore.items.value;
334
+ if (arrayInput.length < items.length) internalFieldStore.items.value = items.slice(0, arrayInput.length);
335
+ else if (arrayInput.length > items.length) {
336
+ if (arrayInput.length > internalFieldStore.children.length) {
337
+ const path = JSON.parse(internalFieldStore.name);
338
+ for (let index = internalFieldStore.children.length; index < arrayInput.length; index++) {
339
+ internalFieldStore.children[index] = {};
340
+ path.push(index);
341
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, arrayInput[index], path);
342
+ path.pop();
331
343
  }
332
- internalFieldStore.items.value = [...items, ...input.slice(items.length).map(createId)];
333
344
  }
334
- for (let index = 0; index < items.length; index++) setFieldInput(internalFieldStore.children[index], input[index]);
335
- internalFieldStore.isDirty.value = untrack(() => internalFieldStore.startItems.value).length !== items.length;
336
- } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setFieldInput(internalFieldStore.children[key], input[key]);
337
- else {
338
- internalFieldStore.input.value = input;
339
- internalFieldStore.isTouched.value = true;
340
- const startInput = untrack(() => internalFieldStore.startInput.value);
341
- internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
345
+ internalFieldStore.items.value = [...items, ...arrayInput.slice(items.length).map(createId)];
342
346
  }
347
+ for (let index = 0; index < items.length; index++) setNestedInput(internalFieldStore.children[index], arrayInput[index]);
348
+ internalFieldStore.input.value = input == null ? input : true;
349
+ internalFieldStore.isDirty.value = internalFieldStore.startInput.value !== internalFieldStore.input.value || internalFieldStore.startItems.value.length !== items.length;
350
+ } else if (internalFieldStore.kind === "object") {
351
+ for (const key in internalFieldStore.children) setNestedInput(internalFieldStore.children[key], input?.[key]);
352
+ internalFieldStore.input.value = input == null ? input : true;
353
+ internalFieldStore.isDirty.value = internalFieldStore.startInput.value !== internalFieldStore.input.value;
354
+ } else {
355
+ internalFieldStore.input.value = input;
356
+ const startInput = internalFieldStore.startInput.value;
357
+ internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
358
+ }
359
+ }
360
+ function setFieldInput(internalFormStore, path, input) {
361
+ batch(() => {
362
+ untrack(() => {
363
+ let internalFieldStore = internalFormStore;
364
+ for (let index = 0; index < path.length; index++) {
365
+ internalFieldStore = internalFieldStore.children[path[index]];
366
+ if (index < path.length - 1) internalFieldStore.input.value = true;
367
+ else setNestedInput(internalFieldStore, input);
368
+ }
369
+ });
343
370
  });
344
371
  }
345
372
 
@@ -348,19 +375,23 @@ function setFieldInput(internalFieldStore, input) {
348
375
  function setInitialFieldInput(internalFieldStore, initialInput) {
349
376
  batch(() => {
350
377
  if (internalFieldStore.kind === "array") {
351
- if (initialInput.length > internalFieldStore.children.length) {
378
+ internalFieldStore.input.value = initialInput == null ? initialInput : true;
379
+ const initialArrayInput = initialInput ?? [];
380
+ if (initialArrayInput.length > internalFieldStore.children.length) {
352
381
  const path = JSON.parse(internalFieldStore.name);
353
- for (let index = internalFieldStore.children.length; index < initialInput.length; index++) {
382
+ for (let index = internalFieldStore.children.length; index < initialArrayInput.length; index++) {
354
383
  internalFieldStore.children[index] = {};
355
384
  path.push(index);
356
- initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, initialInput[index], path);
385
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, initialArrayInput[index], path);
357
386
  path.pop();
358
387
  }
359
388
  }
360
- internalFieldStore.initialItems.value = initialInput.map(createId);
361
- for (let index = 0; index < internalFieldStore.children.length; index++) setInitialFieldInput(internalFieldStore.children[index], initialInput?.[index]);
362
- } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setInitialFieldInput(internalFieldStore.children[key], initialInput?.[key]);
363
- else internalFieldStore.initialInput.value = initialInput;
389
+ internalFieldStore.initialItems.value = initialArrayInput.map(createId);
390
+ for (let index = 0; index < internalFieldStore.children.length; index++) setInitialFieldInput(internalFieldStore.children[index], initialArrayInput[index]);
391
+ } else if (internalFieldStore.kind === "object") {
392
+ internalFieldStore.input.value = initialInput == null ? initialInput : true;
393
+ for (const key in internalFieldStore.children) setInitialFieldInput(internalFieldStore.children[key], initialInput?.[key]);
394
+ } else internalFieldStore.initialInput.value = initialInput;
364
395
  });
365
396
  }
366
397
 
@@ -433,8 +464,8 @@ async function validateFormInput(internalFormStore, config) {
433
464
 
434
465
  //#endregion
435
466
  //#region src/form/validateIfRequired/validateIfRequired.ts
436
- function validateIfRequired(internalFormStore, internalFieldStore, validationModes) {
437
- if (validationModes === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
467
+ function validateIfRequired(internalFormStore, internalFieldStore, validationMode) {
468
+ if (validationMode === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
438
469
  }
439
470
 
440
471
  //#endregion
@@ -52,7 +52,12 @@ function handleSubmit(form, handler) {
52
52
  //#region src/insert/insert.ts
53
53
  function insert(form, config) {
54
54
  const internalFormStore = form[INTERNAL];
55
- const internalArrayStore = getFieldStore(internalFormStore, config.path);
55
+ let internalFieldStore = internalFormStore;
56
+ for (let index = 0; index < config.path.length; index++) {
57
+ internalFieldStore = internalFieldStore.children[config.path[index]];
58
+ if (index < config.path.length - 1) internalFieldStore.input.value = true;
59
+ }
60
+ const internalArrayStore = internalFieldStore;
56
61
  const items = untrack(() => internalArrayStore.items.value);
57
62
  const insertIndex = config.at === void 0 ? items.length : config.at;
58
63
  if (insertIndex >= 0 && insertIndex <= items.length) batch(() => {
@@ -66,6 +71,7 @@ function insert(form, config) {
66
71
  path.push(insertIndex);
67
72
  initializeFieldStore(internalArrayStore.children[insertIndex], internalArrayStore.schema.item, config.initialInput, path);
68
73
  } else resetItemState(internalArrayStore.children[insertIndex], config.initialInput);
74
+ internalArrayStore.input.value = true;
69
75
  internalArrayStore.isTouched.value = true;
70
76
  internalArrayStore.isDirty.value = true;
71
77
  validateIfRequired(internalFormStore, internalArrayStore, "input");
@@ -137,17 +143,20 @@ function reset(form, config) {
137
143
  const internalFieldStore = config?.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
138
144
  if (config?.initialInput) setInitialFieldInput(internalFieldStore, config.initialInput);
139
145
  walkFieldStore(internalFieldStore, (internalFieldStore$1) => {
146
+ internalFieldStore$1.elements = internalFieldStore$1.initialElements;
140
147
  if (!config?.keepErrors) internalFieldStore$1.errors.value = null;
148
+ if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
149
+ internalFieldStore$1.startInput.value = internalFieldStore$1.initialInput.value;
150
+ if (!config?.keepInput) internalFieldStore$1.input.value = internalFieldStore$1.initialInput.value;
141
151
  if (internalFieldStore$1.kind === "array") {
142
152
  internalFieldStore$1.startItems.value = internalFieldStore$1.initialItems.value;
143
153
  if (!config?.keepInput || internalFieldStore$1.startItems.value.length === internalFieldStore$1.items.value.length) internalFieldStore$1.items.value = internalFieldStore$1.initialItems.value;
144
- if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
145
- internalFieldStore$1.isDirty.value = internalFieldStore$1.startItems.value !== internalFieldStore$1.items.value;
146
- } else if (internalFieldStore$1.kind === "value") {
147
- internalFieldStore$1.startInput.value = internalFieldStore$1.initialInput.value;
148
- if (!config?.keepInput) internalFieldStore$1.input.value = internalFieldStore$1.initialInput.value;
149
- if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
150
- internalFieldStore$1.isDirty.value = internalFieldStore$1.startInput.value !== internalFieldStore$1.input.value;
154
+ internalFieldStore$1.isDirty.value = internalFieldStore$1.startInput.value !== internalFieldStore$1.input.value || internalFieldStore$1.startItems.value !== internalFieldStore$1.items.value;
155
+ } else if (internalFieldStore$1.kind === "object") internalFieldStore$1.isDirty.value = internalFieldStore$1.startInput.value !== internalFieldStore$1.input.value;
156
+ else {
157
+ const startInput = internalFieldStore$1.startInput.value;
158
+ const input = internalFieldStore$1.input.value;
159
+ internalFieldStore$1.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
151
160
  for (const element of internalFieldStore$1.elements) if (element.type === "file") element.value = "";
152
161
  }
153
162
  });
@@ -170,9 +179,8 @@ function setErrors(form, config) {
170
179
  function setInput(form, config) {
171
180
  batch(() => {
172
181
  const internalFormStore = form[INTERNAL];
173
- const internalFieldStore = config.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
174
- setFieldInput(internalFieldStore, config.input);
175
- validateIfRequired(internalFormStore, internalFieldStore, "input");
182
+ setFieldInput(internalFormStore, config.path ?? [], config.input);
183
+ validateIfRequired(internalFormStore, config.path ? getFieldStore(internalFormStore, config.path) : internalFormStore, "input");
176
184
  });
177
185
  }
178
186
 
@@ -2,37 +2,68 @@ import { createFormStore, getFieldBool, INTERNAL, validateFormInput, } from '../
2
2
  import { onMount } from 'svelte';
3
3
  import * as v from 'valibot';
4
4
  export function createForm(config) {
5
- const internalFormStore = createFormStore(config, (input) => v.safeParseAsync(config.schema, input));
6
- onMount(() => {
5
+ var _a;
6
+ var internalFormStore = createFormStore(config, function (input) {
7
+ return v.safeParseAsync(config.schema, input);
8
+ });
9
+ onMount(function () {
7
10
  if (config.validate === 'initial') {
8
11
  validateFormInput(internalFormStore);
9
12
  }
10
13
  });
11
- const isTouched = $derived(getFieldBool(internalFormStore, 'isTouched'));
12
- const isDirty = $derived(getFieldBool(internalFormStore, 'isDirty'));
13
- const isValid = $derived(!getFieldBool(internalFormStore, 'errors'));
14
- return {
15
- [INTERNAL]: internalFormStore,
16
- get isSubmitting() {
17
- return internalFormStore.isSubmitting.value;
18
- },
19
- get isSubmitted() {
20
- return internalFormStore.isSubmitted.value;
21
- },
22
- get isValidating() {
23
- return internalFormStore.isValidating.value;
24
- },
25
- get isTouched() {
26
- return isTouched;
27
- },
28
- get isDirty() {
29
- return isDirty;
30
- },
31
- get isValid() {
32
- return isValid;
33
- },
34
- get errors() {
35
- return internalFormStore.errors.value;
36
- },
37
- };
14
+ var isTouched = $derived(getFieldBool(internalFormStore, 'isTouched'));
15
+ var isDirty = $derived(getFieldBool(internalFormStore, 'isDirty'));
16
+ var isValid = $derived(!getFieldBool(internalFormStore, 'errors'));
17
+ return _a = {},
18
+ _a[INTERNAL] = internalFormStore,
19
+ Object.defineProperty(_a, "isSubmitting", {
20
+ get: function () {
21
+ return internalFormStore.isSubmitting.value;
22
+ },
23
+ enumerable: false,
24
+ configurable: true
25
+ }),
26
+ Object.defineProperty(_a, "isSubmitted", {
27
+ get: function () {
28
+ return internalFormStore.isSubmitted.value;
29
+ },
30
+ enumerable: false,
31
+ configurable: true
32
+ }),
33
+ Object.defineProperty(_a, "isValidating", {
34
+ get: function () {
35
+ return internalFormStore.isValidating.value;
36
+ },
37
+ enumerable: false,
38
+ configurable: true
39
+ }),
40
+ Object.defineProperty(_a, "isTouched", {
41
+ get: function () {
42
+ return isTouched;
43
+ },
44
+ enumerable: false,
45
+ configurable: true
46
+ }),
47
+ Object.defineProperty(_a, "isDirty", {
48
+ get: function () {
49
+ return isDirty;
50
+ },
51
+ enumerable: false,
52
+ configurable: true
53
+ }),
54
+ Object.defineProperty(_a, "isValid", {
55
+ get: function () {
56
+ return isValid;
57
+ },
58
+ enumerable: false,
59
+ configurable: true
60
+ }),
61
+ Object.defineProperty(_a, "errors", {
62
+ get: function () {
63
+ return internalFormStore.errors.value;
64
+ },
65
+ enumerable: false,
66
+ configurable: true
67
+ }),
68
+ _a;
38
69
  }
@@ -2,13 +2,14 @@ import { getElementInput, getFieldBool, getFieldInput, getFieldStore, INTERNAL,
2
2
  import { createAttachmentKey } from 'svelte/attachments';
3
3
  import { unwrap } from '../../utils/index';
4
4
  export function useField(form, config) {
5
- const path = $derived(unwrap(config).path);
6
- const internalFormStore = $derived(unwrap(form)[INTERNAL]);
7
- const internalFieldStore = $derived(getFieldStore(internalFormStore, path));
8
- const input = $derived(getFieldInput(internalFieldStore));
9
- const isTouched = $derived(getFieldBool(internalFieldStore, 'isTouched'));
10
- const isDirty = $derived(getFieldBool(internalFieldStore, 'isDirty'));
11
- const isValid = $derived(!getFieldBool(internalFieldStore, 'errors'));
5
+ var _a;
6
+ var path = $derived(unwrap(config).path);
7
+ var internalFormStore = $derived(unwrap(form)[INTERNAL]);
8
+ var internalFieldStore = $derived(getFieldStore(internalFormStore, path));
9
+ var input = $derived(getFieldInput(internalFieldStore));
10
+ var isTouched = $derived(getFieldBool(internalFieldStore, 'isTouched'));
11
+ var isDirty = $derived(getFieldBool(internalFieldStore, 'isDirty'));
12
+ var isValid = $derived(!getFieldBool(internalFieldStore, 'errors'));
12
13
  return {
13
14
  get path() {
14
15
  return path;
@@ -28,31 +29,32 @@ export function useField(form, config) {
28
29
  get isValid() {
29
30
  return isValid;
30
31
  },
31
- props: {
32
- get name() {
33
- return internalFieldStore.name;
32
+ props: (_a = {
33
+ get name() {
34
+ return internalFieldStore.name;
35
+ },
36
+ autofocus: !!internalFieldStore.errors.value
34
37
  },
35
- autofocus: !!internalFieldStore.errors.value,
36
- [createAttachmentKey()](element) {
38
+ _a[createAttachmentKey()] = function (element) {
37
39
  internalFieldStore.elements.push(element);
38
- return () => {
39
- internalFieldStore.elements = internalFieldStore.elements.filter((el) => el !== element);
40
+ return function () {
41
+ internalFieldStore.elements = internalFieldStore.elements.filter(function (el) { return el !== element; });
40
42
  };
41
43
  },
42
- onfocus() {
44
+ _a.onfocus = function () {
43
45
  setFieldBool(internalFieldStore, 'isTouched', true);
44
46
  validateIfRequired(internalFormStore, internalFieldStore, 'touch');
45
47
  },
46
- oninput(event) {
47
- setFieldInput(internalFieldStore, getElementInput(event.currentTarget, internalFieldStore));
48
+ _a.oninput = function (event) {
49
+ setFieldInput(internalFormStore, path, getElementInput(event.currentTarget, internalFieldStore));
48
50
  validateIfRequired(internalFormStore, internalFieldStore, 'input');
49
51
  },
50
- onchange() {
52
+ _a.onchange = function () {
51
53
  validateIfRequired(internalFormStore, internalFieldStore, 'change');
52
54
  },
53
- onblur() {
55
+ _a.onblur = function () {
54
56
  validateIfRequired(internalFormStore, internalFieldStore, 'blur');
55
57
  },
56
- },
58
+ _a),
57
59
  };
58
60
  }
@@ -1,11 +1,11 @@
1
1
  import { getFieldBool, getFieldStore, INTERNAL, } from '../../core/index.svelte';
2
2
  import { unwrap } from '../../utils/index';
3
3
  export function useFieldArray(form, config) {
4
- const path = $derived(unwrap(config).path);
5
- const internalFieldStore = $derived(getFieldStore(unwrap(form)[INTERNAL], path));
6
- const isTouched = $derived(getFieldBool(internalFieldStore, 'isTouched'));
7
- const isDirty = $derived(getFieldBool(internalFieldStore, 'isDirty'));
8
- const isValid = $derived(!getFieldBool(internalFieldStore, 'errors'));
4
+ var path = $derived(unwrap(config).path);
5
+ var internalFieldStore = $derived(getFieldStore(unwrap(form)[INTERNAL], path));
6
+ var isTouched = $derived(getFieldBool(internalFieldStore, 'isTouched'));
7
+ var isDirty = $derived(getFieldBool(internalFieldStore, 'isDirty'));
8
+ var isValid = $derived(!getFieldBool(internalFieldStore, 'errors'));
9
9
  return {
10
10
  get path() {
11
11
  return path;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@formisch/svelte",
3
3
  "description": "The modular and type-safe form library for Svelte",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "license": "MIT",
6
6
  "author": "Fabian Hiller",
7
7
  "homepage": "https://formisch.dev",
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/fabian-hiller/formisch"
11
11
  },
12
12
  "keywords": [
13
- "vue",
13
+ "svelte",
14
14
  "form",
15
15
  "typescript",
16
16
  "schema",
@@ -51,8 +51,8 @@
51
51
  "typescript": "^5.9.2",
52
52
  "typescript-eslint": "^8.43.0",
53
53
  "vite": "^7.1.5",
54
- "@formisch/core": "0.2.0",
55
- "@formisch/methods": "0.2.0"
54
+ "@formisch/core": "0.4.0",
55
+ "@formisch/methods": "0.3.0"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "svelte": "^5.29.0",