@formisch/vue 0.2.1 → 0.3.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.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as v from "valibot";
2
- import * as vue5 from "vue";
2
+ import * as vue11 from "vue";
3
3
  import { ComponentPublicInstance, MaybeRefOrGetter, ShallowRef as Signal } from "vue";
4
4
 
5
5
  //#region ../../packages/core/dist/index.vue.d.ts
@@ -18,29 +18,34 @@ interface InternalBaseStore {
18
18
  kind: "array" | "object" | "value";
19
19
  name: string;
20
20
  schema: Schema;
21
+ initialElements: FieldElement[];
21
22
  elements: FieldElement[];
22
23
  errors: Signal<[string, ...string[]] | null>;
24
+ isTouched: Signal<boolean>;
25
+ isDirty: Signal<boolean>;
23
26
  }
24
27
  interface InternalArrayStore extends InternalBaseStore {
25
28
  kind: "array";
26
29
  children: InternalFieldStore[];
30
+ initialInput: Signal<true | null | undefined>;
31
+ startInput: Signal<true | null | undefined>;
32
+ input: Signal<true | null | undefined>;
27
33
  initialItems: Signal<string[]>;
28
34
  startItems: Signal<string[]>;
29
35
  items: Signal<string[]>;
30
- isTouched: Signal<boolean>;
31
- isDirty: Signal<boolean>;
32
36
  }
33
37
  interface InternalObjectStore extends InternalBaseStore {
34
38
  kind: "object";
35
39
  children: Record<string, InternalFieldStore>;
40
+ initialInput: Signal<true | null | undefined>;
41
+ startInput: Signal<true | null | undefined>;
42
+ input: Signal<true | null | undefined>;
36
43
  }
37
44
  interface InternalValueStore extends InternalBaseStore {
38
45
  kind: "value";
39
46
  initialInput: Signal<unknown>;
40
47
  startInput: Signal<unknown>;
41
48
  input: Signal<unknown>;
42
- isTouched: Signal<boolean>;
43
- isDirty: Signal<boolean>;
44
49
  }
45
50
  type InternalFieldStore = InternalArrayStore | InternalObjectStore | InternalValueStore;
46
51
  //#endregion
@@ -344,14 +349,14 @@ interface FieldProps<TSchema extends Schema = Schema, TFieldPath extends Require
344
349
  readonly path: ValidPath<v.InferInput<TSchema>, TFieldPath>;
345
350
  }
346
351
  declare const _default: <TSchema extends Schema, TFieldPath extends RequiredPath>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal$2<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
347
- props: __VLS_PrettifyLocal$2<Pick<Partial<{}> & Omit<{} & vue5.VNodeProps & vue5.AllowedComponentProps & vue5.ComponentCustomProps, never>, never> & FieldProps<TSchema, TFieldPath> & {}> & vue5.PublicProps;
348
- expose(exposed: vue5.ShallowUnwrapRef<{}>): void;
352
+ props: __VLS_PrettifyLocal$2<Pick<Partial<{}> & Omit<{} & vue11.VNodeProps & vue11.AllowedComponentProps & vue11.ComponentCustomProps, never>, never> & FieldProps<TSchema, TFieldPath> & {}> & vue11.PublicProps;
353
+ expose(exposed: vue11.ShallowUnwrapRef<{}>): void;
349
354
  attrs: any;
350
355
  slots: {
351
356
  default(props: FieldStore<TSchema, TFieldPath>): any;
352
357
  };
353
358
  emit: {};
354
- }>) => vue5.VNode & {
359
+ }>) => vue11.VNode & {
355
360
  __ctx?: Awaited<typeof __VLS_setup>;
356
361
  };
357
362
  type __VLS_PrettifyLocal$2<T> = { [K in keyof T as K]: T[K] } & {};
@@ -365,14 +370,14 @@ interface FieldArrayProps<TSchema extends Schema = Schema, TFieldArrayPath exten
365
370
  readonly path: ValidArrayPath<v.InferInput<TSchema>, TFieldArrayPath>;
366
371
  }
367
372
  declare const _default$1: <TSchema extends Schema, TFieldArrayPath extends RequiredPath>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal$1<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
368
- props: __VLS_PrettifyLocal$1<Pick<Partial<{}> & Omit<{} & vue5.VNodeProps & vue5.AllowedComponentProps & vue5.ComponentCustomProps, never>, never> & FieldArrayProps<TSchema, TFieldArrayPath> & {}> & vue5.PublicProps;
369
- expose(exposed: vue5.ShallowUnwrapRef<{}>): void;
373
+ props: __VLS_PrettifyLocal$1<Pick<Partial<{}> & Omit<{} & vue11.VNodeProps & vue11.AllowedComponentProps & vue11.ComponentCustomProps, never>, never> & FieldArrayProps<TSchema, TFieldArrayPath> & {}> & vue11.PublicProps;
374
+ expose(exposed: vue11.ShallowUnwrapRef<{}>): void;
370
375
  attrs: any;
371
376
  slots: {
372
377
  default(props: FieldArrayStore<TSchema, TFieldArrayPath>): any;
373
378
  };
374
379
  emit: {};
375
- }>) => vue5.VNode & {
380
+ }>) => vue11.VNode & {
376
381
  __ctx?: Awaited<typeof __VLS_setup>;
377
382
  };
378
383
  type __VLS_PrettifyLocal$1<T> = { [K in keyof T as K]: T[K] } & {};
@@ -383,14 +388,14 @@ interface FormProps<TSchema extends Schema = Schema> {
383
388
  onSubmit: SubmitHandler<TSchema>;
384
389
  }
385
390
  declare const _default$2: <TSchema extends Schema = Schema>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
386
- props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & vue5.VNodeProps & vue5.AllowedComponentProps & vue5.ComponentCustomProps, never>, never> & FormProps<TSchema> & {}> & vue5.PublicProps;
387
- expose(exposed: vue5.ShallowUnwrapRef<{}>): void;
391
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & vue11.VNodeProps & vue11.AllowedComponentProps & vue11.ComponentCustomProps, never>, never> & FormProps<TSchema> & {}> & vue11.PublicProps;
392
+ expose(exposed: vue11.ShallowUnwrapRef<{}>): void;
388
393
  attrs: any;
389
394
  slots: {
390
395
  default?: (props: {}) => any;
391
396
  };
392
397
  emit: {};
393
- }>) => vue5.VNode & {
398
+ }>) => vue11.VNode & {
394
399
  __ctx?: Awaited<typeof __VLS_setup>;
395
400
  };
396
401
  type __VLS_PrettifyLocal<T> = { [K in keyof T as K]: T[K] } & {};
package/dist/index.js CHANGED
@@ -16,16 +16,21 @@ function untrack(fn) {
16
16
  * TODO: Add comment
17
17
  * TODO: Should this stay in /primitives or move to /utils?
18
18
  */
19
- function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
19
+ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nullish = false) {
20
20
  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`);
21
21
  else if (schema.type === "lazy") initializeFieldStore(internalFieldStore, schema.getter(void 0), initialInput, path);
22
- 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);
22
+ 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);
23
+ else if (schema.type === "non_nullable" || schema.type === "non_nullish" || schema.type === "non_optional") initializeFieldStore(internalFieldStore, schema.wrapped, initialInput, path);
23
24
  else if (schema.type === "intersect" || schema.type === "union" || schema.type === "variant") for (const schemaOption of schema.options) initializeFieldStore(internalFieldStore, schemaOption, initialInput, path);
24
25
  else {
25
26
  internalFieldStore.schema = schema;
26
27
  internalFieldStore.name = JSON.stringify(path);
27
- internalFieldStore.elements = [];
28
+ const initialElements = [];
29
+ internalFieldStore.initialElements = initialElements;
30
+ internalFieldStore.elements = initialElements;
28
31
  internalFieldStore.errors = createSignal(null);
32
+ internalFieldStore.isTouched = createSignal(false);
33
+ internalFieldStore.isDirty = createSignal(false);
29
34
  if (schema.type === "array" || schema.type === "loose_tuple" || schema.type === "strict_tuple" || schema.type === "tuple") {
30
35
  if (internalFieldStore.kind && internalFieldStore.kind !== "array") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "array"`);
31
36
  internalFieldStore.kind = "array";
@@ -44,12 +49,14 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
44
49
  initializeFieldStore(internalFieldStore.children[index], schema.items[index], initialInput?.[index], path);
45
50
  path.pop();
46
51
  }
52
+ const arrayInput = nullish && initialInput == null ? initialInput : true;
53
+ internalFieldStore.initialInput = createSignal(arrayInput);
54
+ internalFieldStore.startInput = createSignal(arrayInput);
55
+ internalFieldStore.input = createSignal(arrayInput);
47
56
  const initialItems = internalFieldStore.children.map(createId);
48
57
  internalFieldStore.initialItems = createSignal(initialItems);
49
58
  internalFieldStore.startItems = createSignal(initialItems);
50
59
  internalFieldStore.items = createSignal(initialItems);
51
- internalFieldStore.isTouched = createSignal(false);
52
- internalFieldStore.isDirty = createSignal(false);
53
60
  }
54
61
  } else if (schema.type === "loose_object" || schema.type === "object" || schema.type === "strict_object") {
55
62
  if (internalFieldStore.kind && internalFieldStore.kind !== "object") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "object"`);
@@ -62,6 +69,10 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
62
69
  initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput?.[key], path);
63
70
  path.pop();
64
71
  }
72
+ const objectInput = nullish && initialInput == null ? initialInput : true;
73
+ internalFieldStore.initialInput = createSignal(objectInput);
74
+ internalFieldStore.startInput = createSignal(objectInput);
75
+ internalFieldStore.input = createSignal(objectInput);
65
76
  }
66
77
  } else {
67
78
  internalFieldStore.kind = "value";
@@ -69,8 +80,6 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
69
80
  internalFieldStore.initialInput = createSignal(initialInput);
70
81
  internalFieldStore.startInput = createSignal(initialInput);
71
82
  internalFieldStore.input = createSignal(initialInput);
72
- internalFieldStore.isTouched = createSignal(false);
73
- internalFieldStore.isDirty = createSignal(false);
74
83
  }
75
84
  }
76
85
  }
@@ -87,10 +96,14 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
87
96
  function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
88
97
  batch(() => {
89
98
  untrack(() => {
99
+ toInternalFieldStore.elements = fromInternalFieldStore.elements;
100
+ toInternalFieldStore.errors.value = fromInternalFieldStore.errors.value;
101
+ toInternalFieldStore.startInput.value = fromInternalFieldStore.startInput.value;
102
+ toInternalFieldStore.input.value = fromInternalFieldStore.input.value;
103
+ toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
104
+ toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
90
105
  if (fromInternalFieldStore.kind === "array" && toInternalFieldStore.kind === "array") {
91
106
  const fromItems = fromInternalFieldStore.items.value;
92
- toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
93
- toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
94
107
  toInternalFieldStore.startItems.value = fromInternalFieldStore.startItems.value;
95
108
  toInternalFieldStore.items.value = fromItems;
96
109
  let path;
@@ -105,12 +118,6 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
105
118
  copyItemState(fromInternalFieldStore.children[index], toInternalFieldStore.children[index]);
106
119
  }
107
120
  } else if (fromInternalFieldStore.kind === "object" && toInternalFieldStore.kind === "object") for (const key in fromInternalFieldStore.children) copyItemState(fromInternalFieldStore.children[key], toInternalFieldStore.children[key]);
108
- else if (fromInternalFieldStore.kind === "value" && toInternalFieldStore.kind === "value") {
109
- toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
110
- toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
111
- toInternalFieldStore.startInput.value = fromInternalFieldStore.startInput.value;
112
- toInternalFieldStore.input.value = fromInternalFieldStore.input.value;
113
- }
114
121
  });
115
122
  });
116
123
  }
@@ -125,11 +132,15 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
125
132
  */
126
133
  function resetItemState(internalFieldStore, initialInput) {
127
134
  batch(() => {
135
+ internalFieldStore.elements = [];
128
136
  internalFieldStore.errors.value = null;
129
- if (internalFieldStore.kind === "array") {
130
- internalFieldStore.isTouched.value = false;
131
- internalFieldStore.isDirty.value = false;
132
- if (initialInput) {
137
+ internalFieldStore.isTouched.value = false;
138
+ internalFieldStore.isDirty.value = false;
139
+ if (internalFieldStore.kind === "array" || internalFieldStore.kind === "object") {
140
+ const objectInput = initialInput == null ? initialInput : true;
141
+ internalFieldStore.startInput.value = objectInput;
142
+ internalFieldStore.input.value = objectInput;
143
+ if (internalFieldStore.kind === "array") if (initialInput) {
133
144
  const newItems = initialInput.map(createId);
134
145
  internalFieldStore.startItems.value = newItems;
135
146
  internalFieldStore.items.value = newItems;
@@ -138,10 +149,8 @@ function resetItemState(internalFieldStore, initialInput) {
138
149
  internalFieldStore.startItems.value = [];
139
150
  internalFieldStore.items.value = [];
140
151
  }
141
- } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], initialInput?.[key]);
142
- else {
143
- internalFieldStore.isTouched.value = false;
144
- internalFieldStore.isDirty.value = false;
152
+ else for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], initialInput?.[key]);
153
+ } else {
145
154
  internalFieldStore.startInput.value = initialInput;
146
155
  internalFieldStore.input.value = initialInput;
147
156
  }
@@ -158,15 +167,27 @@ function resetItemState(internalFieldStore, initialInput) {
158
167
  function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
159
168
  batch(() => {
160
169
  untrack(() => {
170
+ const tempElements = firstInternalFieldStore.elements;
171
+ firstInternalFieldStore.elements = secondInternalFieldStore.elements;
172
+ secondInternalFieldStore.elements = tempElements;
173
+ const tempErrors = firstInternalFieldStore.errors.value;
174
+ firstInternalFieldStore.errors.value = secondInternalFieldStore.errors.value;
175
+ secondInternalFieldStore.errors.value = tempErrors;
176
+ const tempStartInput = firstInternalFieldStore.startInput.value;
177
+ firstInternalFieldStore.startInput.value = secondInternalFieldStore.startInput.value;
178
+ secondInternalFieldStore.startInput.value = tempStartInput;
179
+ const tempInput = firstInternalFieldStore.input.value;
180
+ firstInternalFieldStore.input.value = secondInternalFieldStore.input.value;
181
+ secondInternalFieldStore.input.value = tempInput;
182
+ const tempIsTouched = firstInternalFieldStore.isTouched.value;
183
+ firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
184
+ secondInternalFieldStore.isTouched.value = tempIsTouched;
185
+ const tempIsDirty = firstInternalFieldStore.isDirty.value;
186
+ firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
187
+ secondInternalFieldStore.isDirty.value = tempIsDirty;
161
188
  if (firstInternalFieldStore.kind === "array" && secondInternalFieldStore.kind === "array") {
162
189
  const firstItems = firstInternalFieldStore.items.value;
163
190
  const secondItems = secondInternalFieldStore.items.value;
164
- const tempIsTouched = firstInternalFieldStore.isTouched.value;
165
- firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
166
- secondInternalFieldStore.isTouched.value = tempIsTouched;
167
- const tempIsDirty = firstInternalFieldStore.isDirty.value;
168
- firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
169
- secondInternalFieldStore.isDirty.value = tempIsDirty;
170
191
  const tempStartItems = firstInternalFieldStore.startItems.value;
171
192
  firstInternalFieldStore.startItems.value = secondInternalFieldStore.startItems.value;
172
193
  secondInternalFieldStore.startItems.value = tempStartItems;
@@ -193,48 +214,39 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
193
214
  swapItemState(firstInternalFieldStore.children[index], secondInternalFieldStore.children[index]);
194
215
  }
195
216
  } else if (firstInternalFieldStore.kind === "object" && secondInternalFieldStore.kind === "object") for (const key in firstInternalFieldStore.children) swapItemState(firstInternalFieldStore.children[key], secondInternalFieldStore.children[key]);
196
- else if (firstInternalFieldStore.kind === "value" && secondInternalFieldStore.kind === "value") {
197
- const tempIsTouched = firstInternalFieldStore.isTouched.value;
198
- firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
199
- secondInternalFieldStore.isTouched.value = tempIsTouched;
200
- const tempIsDirty = firstInternalFieldStore.isDirty.value;
201
- firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
202
- secondInternalFieldStore.isDirty.value = tempIsDirty;
203
- const tempStartInput = firstInternalFieldStore.startInput.value;
204
- firstInternalFieldStore.startInput.value = secondInternalFieldStore.startInput.value;
205
- secondInternalFieldStore.startInput.value = tempStartInput;
206
- const tempInput = firstInternalFieldStore.input.value;
207
- firstInternalFieldStore.input.value = secondInternalFieldStore.input.value;
208
- secondInternalFieldStore.input.value = tempInput;
209
- }
210
217
  });
211
218
  });
212
219
  }
213
220
  function getFieldInput(internalFieldStore) {
214
221
  if (internalFieldStore.kind === "array") {
215
- const value = [];
216
- for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
217
- return value;
222
+ if (internalFieldStore.input.value) {
223
+ const value = [];
224
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
225
+ return value;
226
+ }
227
+ return internalFieldStore.input.value;
218
228
  }
219
229
  if (internalFieldStore.kind === "object") {
220
- const value = {};
221
- for (const key in internalFieldStore.children) value[key] = getFieldInput(internalFieldStore.children[key]);
222
- return value;
230
+ if (internalFieldStore.input.value) {
231
+ const value = {};
232
+ for (const key in internalFieldStore.children) value[key] = getFieldInput(internalFieldStore.children[key]);
233
+ return value;
234
+ }
235
+ return internalFieldStore.input.value;
223
236
  }
224
237
  return internalFieldStore.input.value;
225
238
  }
226
239
  function getFieldBool(internalFieldStore, type) {
240
+ if (internalFieldStore[type].value) return true;
227
241
  if (internalFieldStore.kind === "array") {
228
- if (internalFieldStore[type].value) return true;
229
242
  for (let index = 0; index < internalFieldStore.items.value.length; index++) if (getFieldBool(internalFieldStore.children[index], type)) return true;
230
243
  return false;
231
244
  }
232
245
  if (internalFieldStore.kind == "object") {
233
- if (type === "errors" && internalFieldStore[type].value) return true;
234
246
  for (const key in internalFieldStore.children) if (getFieldBool(internalFieldStore.children[key], type)) return true;
235
247
  return false;
236
248
  }
237
- return !!internalFieldStore[type].value;
249
+ return false;
238
250
  }
239
251
  function getFieldStore(internalFormStore, path) {
240
252
  let internalFieldStore = internalFormStore;
@@ -250,38 +262,53 @@ function setFieldBool(internalFieldStore, type, bool) {
250
262
  else internalFieldStore[type].value = bool;
251
263
  });
252
264
  }
253
- function setFieldInput(internalFieldStore, input) {
254
- batch(() => {
255
- if (internalFieldStore.kind === "array") {
256
- const arrayInput = input ?? [];
257
- const items = untrack(() => internalFieldStore.items.value);
258
- if (arrayInput.length < items.length) internalFieldStore.items.value = items.slice(0, arrayInput.length);
259
- else if (arrayInput.length > items.length) {
260
- if (arrayInput.length > internalFieldStore.children.length) {
261
- const path = JSON.parse(internalFieldStore.name);
262
- for (let index = internalFieldStore.children.length; index < arrayInput.length; index++) {
263
- internalFieldStore.children[index] = {};
264
- path.push(index);
265
- initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, arrayInput[index], path);
266
- path.pop();
267
- }
265
+ function setNestedInput(internalFieldStore, input) {
266
+ internalFieldStore.isTouched.value = true;
267
+ if (internalFieldStore.kind === "array") {
268
+ const arrayInput = input ?? [];
269
+ const items = internalFieldStore.items.value;
270
+ if (arrayInput.length < items.length) internalFieldStore.items.value = items.slice(0, arrayInput.length);
271
+ else if (arrayInput.length > items.length) {
272
+ if (arrayInput.length > internalFieldStore.children.length) {
273
+ const path = JSON.parse(internalFieldStore.name);
274
+ for (let index = internalFieldStore.children.length; index < arrayInput.length; index++) {
275
+ internalFieldStore.children[index] = {};
276
+ path.push(index);
277
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, arrayInput[index], path);
278
+ path.pop();
268
279
  }
269
- internalFieldStore.items.value = [...items, ...arrayInput.slice(items.length).map(createId)];
270
280
  }
271
- for (let index = 0; index < items.length; index++) setFieldInput(internalFieldStore.children[index], arrayInput[index]);
272
- internalFieldStore.isDirty.value = untrack(() => internalFieldStore.startItems.value).length !== items.length;
273
- } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setFieldInput(internalFieldStore.children[key], input?.[key]);
274
- else {
275
- internalFieldStore.input.value = input;
276
- internalFieldStore.isTouched.value = true;
277
- const startInput = untrack(() => internalFieldStore.startInput.value);
278
- internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
281
+ internalFieldStore.items.value = [...items, ...arrayInput.slice(items.length).map(createId)];
279
282
  }
283
+ for (let index = 0; index < items.length; index++) setNestedInput(internalFieldStore.children[index], arrayInput[index]);
284
+ internalFieldStore.input.value = input == null ? input : true;
285
+ internalFieldStore.isDirty.value = internalFieldStore.startInput.value !== internalFieldStore.input.value || internalFieldStore.startItems.value.length !== items.length;
286
+ } else if (internalFieldStore.kind === "object") {
287
+ for (const key in internalFieldStore.children) setNestedInput(internalFieldStore.children[key], input?.[key]);
288
+ internalFieldStore.input.value = input == null ? input : true;
289
+ internalFieldStore.isDirty.value = internalFieldStore.startInput.value !== internalFieldStore.input.value;
290
+ } else {
291
+ internalFieldStore.input.value = input;
292
+ const startInput = internalFieldStore.startInput.value;
293
+ internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
294
+ }
295
+ }
296
+ function setFieldInput(internalFormStore, path, input) {
297
+ batch(() => {
298
+ untrack(() => {
299
+ let internalFieldStore = internalFormStore;
300
+ for (let index = 0; index < path.length; index++) {
301
+ internalFieldStore = internalFieldStore.children[path[index]];
302
+ if (index < path.length - 1) internalFieldStore.input.value = true;
303
+ else setNestedInput(internalFieldStore, input);
304
+ }
305
+ });
280
306
  });
281
307
  }
282
308
  function setInitialFieldInput(internalFieldStore, initialInput) {
283
309
  batch(() => {
284
310
  if (internalFieldStore.kind === "array") {
311
+ internalFieldStore.input.value = initialInput == null ? initialInput : true;
285
312
  const initialArrayInput = initialInput ?? [];
286
313
  if (initialArrayInput.length > internalFieldStore.children.length) {
287
314
  const path = JSON.parse(internalFieldStore.name);
@@ -294,8 +321,10 @@ function setInitialFieldInput(internalFieldStore, initialInput) {
294
321
  }
295
322
  internalFieldStore.initialItems.value = initialArrayInput.map(createId);
296
323
  for (let index = 0; index < internalFieldStore.children.length; index++) setInitialFieldInput(internalFieldStore.children[index], initialArrayInput[index]);
297
- } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setInitialFieldInput(internalFieldStore.children[key], initialInput?.[key]);
298
- else internalFieldStore.initialInput.value = initialInput;
324
+ } else if (internalFieldStore.kind === "object") {
325
+ internalFieldStore.input.value = initialInput == null ? initialInput : true;
326
+ for (const key in internalFieldStore.children) setInitialFieldInput(internalFieldStore.children[key], initialInput?.[key]);
327
+ } else internalFieldStore.initialInput.value = initialInput;
299
328
  });
300
329
  }
301
330
  function walkFieldStore(internalFieldStore, callback) {
@@ -356,8 +385,8 @@ async function validateFormInput(internalFormStore, config) {
356
385
  });
357
386
  return result;
358
387
  }
359
- function validateIfRequired(internalFormStore, internalFieldStore, validationModes) {
360
- if (validationModes === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
388
+ function validateIfRequired(internalFormStore, internalFieldStore, validationMode) {
389
+ if (validationMode === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
361
390
  }
362
391
  const INTERNAL = "~internal";
363
392
 
@@ -399,7 +428,12 @@ function handleSubmit(form, handler) {
399
428
  }
400
429
  function insert(form, config) {
401
430
  const internalFormStore = form[INTERNAL];
402
- const internalArrayStore = getFieldStore(internalFormStore, config.path);
431
+ let internalFieldStore = internalFormStore;
432
+ for (let index = 0; index < config.path.length; index++) {
433
+ internalFieldStore = internalFieldStore.children[config.path[index]];
434
+ if (index < config.path.length - 1) internalFieldStore.input.value = true;
435
+ }
436
+ const internalArrayStore = internalFieldStore;
403
437
  const items = untrack(() => internalArrayStore.items.value);
404
438
  const insertIndex = config.at === void 0 ? items.length : config.at;
405
439
  if (insertIndex >= 0 && insertIndex <= items.length) batch(() => {
@@ -413,6 +447,7 @@ function insert(form, config) {
413
447
  path.push(insertIndex);
414
448
  initializeFieldStore(internalArrayStore.children[insertIndex], internalArrayStore.schema.item, config.initialInput, path);
415
449
  } else resetItemState(internalArrayStore.children[insertIndex], config.initialInput);
450
+ internalArrayStore.input.value = true;
416
451
  internalArrayStore.isTouched.value = true;
417
452
  internalArrayStore.isDirty.value = true;
418
453
  validateIfRequired(internalFormStore, internalArrayStore, "input");
@@ -472,17 +507,20 @@ function reset(form, config) {
472
507
  const internalFieldStore = config?.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
473
508
  if (config?.initialInput) setInitialFieldInput(internalFieldStore, config.initialInput);
474
509
  walkFieldStore(internalFieldStore, (internalFieldStore$1) => {
510
+ internalFieldStore$1.elements = internalFieldStore$1.initialElements;
475
511
  if (!config?.keepErrors) internalFieldStore$1.errors.value = null;
512
+ if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
513
+ internalFieldStore$1.startInput.value = internalFieldStore$1.initialInput.value;
514
+ if (!config?.keepInput) internalFieldStore$1.input.value = internalFieldStore$1.initialInput.value;
476
515
  if (internalFieldStore$1.kind === "array") {
477
516
  internalFieldStore$1.startItems.value = internalFieldStore$1.initialItems.value;
478
517
  if (!config?.keepInput || internalFieldStore$1.startItems.value.length === internalFieldStore$1.items.value.length) internalFieldStore$1.items.value = internalFieldStore$1.initialItems.value;
479
- if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
480
- internalFieldStore$1.isDirty.value = internalFieldStore$1.startItems.value !== internalFieldStore$1.items.value;
481
- } else if (internalFieldStore$1.kind === "value") {
482
- internalFieldStore$1.startInput.value = internalFieldStore$1.initialInput.value;
483
- if (!config?.keepInput) internalFieldStore$1.input.value = internalFieldStore$1.initialInput.value;
484
- if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
485
- internalFieldStore$1.isDirty.value = internalFieldStore$1.startInput.value !== internalFieldStore$1.input.value;
518
+ internalFieldStore$1.isDirty.value = internalFieldStore$1.startInput.value !== internalFieldStore$1.input.value || internalFieldStore$1.startItems.value !== internalFieldStore$1.items.value;
519
+ } else if (internalFieldStore$1.kind === "object") internalFieldStore$1.isDirty.value = internalFieldStore$1.startInput.value !== internalFieldStore$1.input.value;
520
+ else {
521
+ const startInput = internalFieldStore$1.startInput.value;
522
+ const input = internalFieldStore$1.input.value;
523
+ internalFieldStore$1.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
486
524
  for (const element of internalFieldStore$1.elements) if (element.type === "file") element.value = "";
487
525
  }
488
526
  });
@@ -499,9 +537,8 @@ function setErrors(form, config) {
499
537
  function setInput(form, config) {
500
538
  batch(() => {
501
539
  const internalFormStore = form[INTERNAL];
502
- const internalFieldStore = config.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
503
- setFieldInput(internalFieldStore, config.input);
504
- validateIfRequired(internalFormStore, internalFieldStore, "input");
540
+ setFieldInput(internalFormStore, config.path ?? [], config.input);
541
+ validateIfRequired(internalFormStore, config.path ? getFieldStore(internalFormStore, config.path) : internalFormStore, "input");
505
542
  });
506
543
  }
507
544
  function submit(form) {
@@ -530,7 +567,9 @@ function validate(form, config) {
530
567
  //#endregion
531
568
  //#region src/composables/useField/useField.ts
532
569
  function useField(form, config) {
533
- const internalFieldStore = computed(() => getFieldStore(toValue(form)[INTERNAL], toValue(config).path));
570
+ const path = computed(() => toValue(config).path);
571
+ const internalFormStore = computed(() => toValue(form)[INTERNAL]);
572
+ const internalFieldStore = computed(() => getFieldStore(internalFormStore.value, path.value));
534
573
  onUnmounted(() => {
535
574
  internalFieldStore.value.elements = internalFieldStore.value.elements.filter((element) => element.isConnected);
536
575
  });
@@ -540,14 +579,14 @@ function useField(form, config) {
540
579
  const isValid = computed(() => !getFieldBool(internalFieldStore.value, "errors"));
541
580
  return {
542
581
  get path() {
543
- return toValue(config).path;
582
+ return path.value;
544
583
  },
545
584
  get input() {
546
585
  return input.value;
547
586
  },
548
587
  set input(value) {
549
- setFieldInput(internalFieldStore.value, value);
550
- validateIfRequired(toValue(form)[INTERNAL], internalFieldStore.value, "input");
588
+ setFieldInput(internalFormStore.value, path.value, value);
589
+ validateIfRequired(internalFormStore.value, internalFieldStore.value, "input");
551
590
  },
552
591
  get errors() {
553
592
  return internalFieldStore.value.errors.value;
@@ -571,13 +610,13 @@ function useField(form, config) {
571
610
  },
572
611
  onFocus() {
573
612
  setFieldBool(internalFieldStore.value, "isTouched", true);
574
- validateIfRequired(toValue(form)[INTERNAL], internalFieldStore.value, "touch");
613
+ validateIfRequired(internalFormStore.value, internalFieldStore.value, "touch");
575
614
  },
576
615
  onChange() {
577
- validateIfRequired(toValue(form)[INTERNAL], internalFieldStore.value, "change");
616
+ validateIfRequired(internalFormStore.value, internalFieldStore.value, "change");
578
617
  },
579
618
  onBlur() {
580
- validateIfRequired(toValue(form)[INTERNAL], internalFieldStore.value, "blur");
619
+ validateIfRequired(internalFormStore.value, internalFieldStore.value, "blur");
581
620
  }
582
621
  }
583
622
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@formisch/vue",
3
3
  "description": "The modular and type-safe form library for Vue",
4
- "version": "0.2.1",
4
+ "version": "0.3.0",
5
5
  "license": "MIT",
6
6
  "author": "Fabian Hiller",
7
7
  "homepage": "https://formisch.dev",
@@ -43,8 +43,8 @@
43
43
  "valibot": "^1.1.0",
44
44
  "vue": "^3.5.18",
45
45
  "vue-tsc": "^3.0.4",
46
- "@formisch/core": "0.3.1",
47
- "@formisch/methods": "0.2.0"
46
+ "@formisch/core": "0.4.0",
47
+ "@formisch/methods": "0.3.0"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "typescript": ">=5",