@formisch/vue 0.4.0 → 0.5.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 +677 -33
- package/dist/index.js +237 -29
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2,19 +2,51 @@ import * as v from "valibot";
|
|
|
2
2
|
import { computed, createElementBlock, defineComponent, guardReactiveProps, normalizeProps, onBeforeMount, onUnmounted, openBlock, renderSlot, shallowRef as createSignal, toValue, unref } from "vue";
|
|
3
3
|
|
|
4
4
|
//#region ../../packages/core/dist/index.vue.js
|
|
5
|
+
/**
|
|
6
|
+
* The current framework being used.
|
|
7
|
+
*/
|
|
5
8
|
const framework = "vue";
|
|
9
|
+
/**
|
|
10
|
+
* Creates a unique identifier string.
|
|
11
|
+
*
|
|
12
|
+
* @returns The unique identifier.
|
|
13
|
+
*/
|
|
14
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
6
15
|
function createId() {
|
|
7
16
|
return Math.random().toString(36).slice(2);
|
|
8
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Batches multiple signal updates into a single update cycle. This is a
|
|
20
|
+
* no-op in Vue as batching is handled automatically.
|
|
21
|
+
*
|
|
22
|
+
* @param fn The function to execute.
|
|
23
|
+
*
|
|
24
|
+
* @returns The return value of the function.
|
|
25
|
+
*/
|
|
9
26
|
function batch(fn) {
|
|
10
27
|
return fn();
|
|
11
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Executes a function without tracking reactive dependencies. This is a
|
|
31
|
+
* no-op in Vue as untracking is not supported in Vue.
|
|
32
|
+
*
|
|
33
|
+
* @param fn The function to execute.
|
|
34
|
+
*
|
|
35
|
+
* @returns The return value of the function.
|
|
36
|
+
*/
|
|
12
37
|
function untrack(fn) {
|
|
13
38
|
return fn();
|
|
14
39
|
}
|
|
15
40
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
41
|
+
* Initializes a field store recursively based on the schema structure. Handles
|
|
42
|
+
* array, object, and value schemas, setting up all necessary signals and
|
|
43
|
+
* children. Supports wrapped schemas and schema options.
|
|
44
|
+
*
|
|
45
|
+
* @param internalFieldStore The partial field store to initialize.
|
|
46
|
+
* @param schema The Valibot schema defining the field structure.
|
|
47
|
+
* @param initialInput The initial input value.
|
|
48
|
+
* @param path The path to the field in the form.
|
|
49
|
+
* @param nullish Whether the schema is wrapped in a nullish schema.
|
|
18
50
|
*/
|
|
19
51
|
function initializeFieldStore(internalFieldStore, schema, initialInput, path, nullish = false) {
|
|
20
52
|
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`);
|
|
@@ -85,13 +117,13 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
|
|
|
85
117
|
}
|
|
86
118
|
}
|
|
87
119
|
/**
|
|
88
|
-
* Copies the deeply nested state (signal values) from one
|
|
89
|
-
* This includes the `
|
|
120
|
+
* Copies the deeply nested state (signal values) from one field store to
|
|
121
|
+
* another. This includes the `elements`, `errors`, `startInput`, `input`,
|
|
122
|
+
* `isTouched`, `isDirty`, and for arrays `startItems` and `items` properties.
|
|
90
123
|
* Recursively walks through the field stores and copies all signal values.
|
|
91
124
|
*
|
|
92
|
-
* @param
|
|
93
|
-
* @param
|
|
94
|
-
* @param toIndex - The destination index to copy to
|
|
125
|
+
* @param fromInternalFieldStore The source field store to copy from.
|
|
126
|
+
* @param toInternalFieldStore The destination field store to copy to.
|
|
95
127
|
*/
|
|
96
128
|
function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
97
129
|
batch(() => {
|
|
@@ -122,13 +154,14 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
|
122
154
|
});
|
|
123
155
|
}
|
|
124
156
|
/**
|
|
125
|
-
* Resets the state of
|
|
126
|
-
*
|
|
127
|
-
* `
|
|
128
|
-
* Keeps the `initialInput` and `initialItems` state unchanged for
|
|
157
|
+
* Resets the state of a field store (signal values) deeply nested. Sets
|
|
158
|
+
* `elements` to empty array, `errors` to `null`, `isTouched` and `isDirty` to
|
|
159
|
+
* `false`, and `startInput`, `input`, `startItems`, and `items` to the new
|
|
160
|
+
* input value. Keeps the `initialInput` and `initialItems` state unchanged for
|
|
161
|
+
* form reset functionality.
|
|
129
162
|
*
|
|
130
|
-
* @param internalFieldStore
|
|
131
|
-
* @param initialInput
|
|
163
|
+
* @param internalFieldStore The field store to reset.
|
|
164
|
+
* @param initialInput The new input value (can be any type including array or object).
|
|
132
165
|
*/
|
|
133
166
|
function resetItemState(internalFieldStore, initialInput) {
|
|
134
167
|
batch(() => {
|
|
@@ -157,12 +190,13 @@ function resetItemState(internalFieldStore, initialInput) {
|
|
|
157
190
|
});
|
|
158
191
|
}
|
|
159
192
|
/**
|
|
160
|
-
* Swaps the deeply nested state (signal values) between two field stores.
|
|
161
|
-
*
|
|
162
|
-
*
|
|
193
|
+
* Swaps the deeply nested state (signal values) between two field stores. This
|
|
194
|
+
* includes the `elements`, `errors`, `startInput`, `input`, `isTouched`,
|
|
195
|
+
* `isDirty`, and for arrays `startItems` and `items` properties. Recursively
|
|
196
|
+
* walks through the field stores and swaps all signal values.
|
|
163
197
|
*
|
|
164
|
-
* @param firstInternalFieldStore
|
|
165
|
-
* @param secondInternalFieldStore
|
|
198
|
+
* @param firstInternalFieldStore The first field store to swap.
|
|
199
|
+
* @param secondInternalFieldStore The second field store to swap.
|
|
166
200
|
*/
|
|
167
201
|
function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
|
|
168
202
|
batch(() => {
|
|
@@ -217,11 +251,21 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
|
|
|
217
251
|
});
|
|
218
252
|
});
|
|
219
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Returns the current input of the field store. For arrays and objects,
|
|
256
|
+
* recursively collects input from all children. Returns `null` or `undefined`
|
|
257
|
+
* for nullish array/object inputs, or the primitive value for value fields.
|
|
258
|
+
*
|
|
259
|
+
* @param internalFieldStore The field store to get input from.
|
|
260
|
+
*
|
|
261
|
+
* @returns The field input.
|
|
262
|
+
*/
|
|
263
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
220
264
|
function getFieldInput(internalFieldStore) {
|
|
221
265
|
if (internalFieldStore.kind === "array") {
|
|
222
266
|
if (internalFieldStore.input.value) {
|
|
223
267
|
const value = [];
|
|
224
|
-
for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
|
|
268
|
+
for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = /* @__PURE__ */ getFieldInput(internalFieldStore.children[index]);
|
|
225
269
|
return value;
|
|
226
270
|
}
|
|
227
271
|
return internalFieldStore.input.value;
|
|
@@ -229,30 +273,58 @@ function getFieldInput(internalFieldStore) {
|
|
|
229
273
|
if (internalFieldStore.kind === "object") {
|
|
230
274
|
if (internalFieldStore.input.value) {
|
|
231
275
|
const value = {};
|
|
232
|
-
for (const key in internalFieldStore.children) value[key] = getFieldInput(internalFieldStore.children[key]);
|
|
276
|
+
for (const key in internalFieldStore.children) value[key] = /* @__PURE__ */ getFieldInput(internalFieldStore.children[key]);
|
|
233
277
|
return value;
|
|
234
278
|
}
|
|
235
279
|
return internalFieldStore.input.value;
|
|
236
280
|
}
|
|
237
281
|
return internalFieldStore.input.value;
|
|
238
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Returns whether the specified boolean property is true for the field store
|
|
285
|
+
* or any of its nested children. Recursively checks arrays and objects.
|
|
286
|
+
*
|
|
287
|
+
* @param internalFieldStore The field store to check.
|
|
288
|
+
* @param type The boolean property type to check.
|
|
289
|
+
*
|
|
290
|
+
* @returns Whether the property is true.
|
|
291
|
+
*/
|
|
292
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
239
293
|
function getFieldBool(internalFieldStore, type) {
|
|
240
294
|
if (internalFieldStore[type].value) return true;
|
|
241
295
|
if (internalFieldStore.kind === "array") {
|
|
242
|
-
for (let index = 0; index < internalFieldStore.items.value.length; index++) if (getFieldBool(internalFieldStore.children[index], type)) return true;
|
|
296
|
+
for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
|
|
243
297
|
return false;
|
|
244
298
|
}
|
|
245
299
|
if (internalFieldStore.kind == "object") {
|
|
246
|
-
for (const key in internalFieldStore.children) if (getFieldBool(internalFieldStore.children[key], type)) return true;
|
|
300
|
+
for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
|
|
247
301
|
return false;
|
|
248
302
|
}
|
|
249
303
|
return false;
|
|
250
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Returns the field store at the specified path by traversing the form store's
|
|
307
|
+
* children hierarchy.
|
|
308
|
+
*
|
|
309
|
+
* @param internalFormStore The form store to traverse.
|
|
310
|
+
* @param path The path to the field store.
|
|
311
|
+
*
|
|
312
|
+
* @returns The field store.
|
|
313
|
+
*/
|
|
314
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
251
315
|
function getFieldStore(internalFormStore, path) {
|
|
252
316
|
let internalFieldStore = internalFormStore;
|
|
253
317
|
for (const key of path) internalFieldStore = internalFieldStore.children[key];
|
|
254
318
|
return internalFieldStore;
|
|
255
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Sets the specified boolean property for the field store and all nested
|
|
322
|
+
* children. Recursively updates arrays and objects.
|
|
323
|
+
*
|
|
324
|
+
* @param internalFieldStore The field store to update.
|
|
325
|
+
* @param type The boolean property type to set.
|
|
326
|
+
* @param bool The boolean value to set.
|
|
327
|
+
*/
|
|
256
328
|
function setFieldBool(internalFieldStore, type, bool) {
|
|
257
329
|
batch(() => {
|
|
258
330
|
if (internalFieldStore.kind === "array") {
|
|
@@ -262,6 +334,13 @@ function setFieldBool(internalFieldStore, type, bool) {
|
|
|
262
334
|
else internalFieldStore[type].value = bool;
|
|
263
335
|
});
|
|
264
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* Sets the input for a nested field store and all its children, updating
|
|
339
|
+
* touched and dirty states accordingly. Handles dynamic array resizing.
|
|
340
|
+
*
|
|
341
|
+
* @param internalFieldStore The field store to update.
|
|
342
|
+
* @param input The new input value.
|
|
343
|
+
*/
|
|
265
344
|
function setNestedInput(internalFieldStore, input) {
|
|
266
345
|
internalFieldStore.isTouched.value = true;
|
|
267
346
|
if (internalFieldStore.kind === "array") {
|
|
@@ -280,7 +359,7 @@ function setNestedInput(internalFieldStore, input) {
|
|
|
280
359
|
}
|
|
281
360
|
internalFieldStore.items.value = [...items, ...arrayInput.slice(items.length).map(createId)];
|
|
282
361
|
}
|
|
283
|
-
for (let index = 0; index <
|
|
362
|
+
for (let index = 0; index < arrayInput.length; index++) setNestedInput(internalFieldStore.children[index], arrayInput[index]);
|
|
284
363
|
internalFieldStore.input.value = input == null ? input : true;
|
|
285
364
|
internalFieldStore.isDirty.value = internalFieldStore.startInput.value !== internalFieldStore.input.value || internalFieldStore.startItems.value.length !== items.length;
|
|
286
365
|
} else if (internalFieldStore.kind === "object") {
|
|
@@ -293,6 +372,14 @@ function setNestedInput(internalFieldStore, input) {
|
|
|
293
372
|
internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
|
|
294
373
|
}
|
|
295
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* Sets the input for a field at the specified path in the form store,
|
|
377
|
+
* traversing the path and updating all parent fields along the way.
|
|
378
|
+
*
|
|
379
|
+
* @param internalFormStore The form store containing the field.
|
|
380
|
+
* @param path The path to the field.
|
|
381
|
+
* @param input The new input value.
|
|
382
|
+
*/
|
|
296
383
|
function setFieldInput(internalFormStore, path, input) {
|
|
297
384
|
batch(() => {
|
|
298
385
|
untrack(() => {
|
|
@@ -305,6 +392,14 @@ function setFieldInput(internalFormStore, path, input) {
|
|
|
305
392
|
});
|
|
306
393
|
});
|
|
307
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* Sets the initial input for a field store and all its children recursively.
|
|
397
|
+
* For arrays, initializes missing children if needed. Updates `initialInput`
|
|
398
|
+
* and `initialItems` properties.
|
|
399
|
+
*
|
|
400
|
+
* @param internalFieldStore The field store to update.
|
|
401
|
+
* @param initialInput The initial input value.
|
|
402
|
+
*/
|
|
308
403
|
function setInitialFieldInput(internalFieldStore, initialInput) {
|
|
309
404
|
batch(() => {
|
|
310
405
|
if (internalFieldStore.kind === "array") {
|
|
@@ -327,14 +422,32 @@ function setInitialFieldInput(internalFieldStore, initialInput) {
|
|
|
327
422
|
} else internalFieldStore.initialInput.value = initialInput;
|
|
328
423
|
});
|
|
329
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Walks through the field store and all nested children, calling the callback
|
|
427
|
+
* for each field store in depth-first order.
|
|
428
|
+
*
|
|
429
|
+
* @param internalFieldStore The field store to walk.
|
|
430
|
+
* @param callback The callback to invoke for each field store.
|
|
431
|
+
*/
|
|
330
432
|
function walkFieldStore(internalFieldStore, callback) {
|
|
331
433
|
callback(internalFieldStore);
|
|
332
434
|
if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
|
|
333
435
|
else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) walkFieldStore(internalFieldStore.children[key], callback);
|
|
334
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* Creates a new internal form store from the provided configuration.
|
|
439
|
+
* Initializes the field store hierarchy, sets validation modes, and
|
|
440
|
+
* creates form state signals.
|
|
441
|
+
*
|
|
442
|
+
* @param config The form configuration.
|
|
443
|
+
* @param parse The schema parse function.
|
|
444
|
+
*
|
|
445
|
+
* @returns The internal form store.
|
|
446
|
+
*/
|
|
335
447
|
function createFormStore(config, parse) {
|
|
336
448
|
const store = {};
|
|
337
449
|
initializeFieldStore(store, config.schema, config.initialInput, []);
|
|
450
|
+
store.validators = 0;
|
|
338
451
|
store.validate = config.validate ?? "submit";
|
|
339
452
|
store.revalidate = config.revalidate ?? "input";
|
|
340
453
|
store.parse = parse;
|
|
@@ -343,10 +456,20 @@ function createFormStore(config, parse) {
|
|
|
343
456
|
store.isValidating = createSignal(false);
|
|
344
457
|
return store;
|
|
345
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* Validates the form input using the configured Valibot schema. Parses the
|
|
461
|
+
* current form input, processes validation issues, assigns errors to fields,
|
|
462
|
+
* and optionally focuses the first field with an error.
|
|
463
|
+
*
|
|
464
|
+
* @param internalFormStore The form store to validate.
|
|
465
|
+
* @param config The validation configuration.
|
|
466
|
+
*
|
|
467
|
+
* @returns The Valibot validation result.
|
|
468
|
+
*/
|
|
346
469
|
async function validateFormInput(internalFormStore, config) {
|
|
347
470
|
internalFormStore.validators++;
|
|
348
471
|
internalFormStore.isValidating.value = true;
|
|
349
|
-
const result = await internalFormStore.parse(untrack(() => getFieldInput(internalFormStore)));
|
|
472
|
+
const result = await internalFormStore.parse(untrack(() => /* @__PURE__ */ getFieldInput(internalFormStore)));
|
|
350
473
|
let rootErrors;
|
|
351
474
|
let nestedErrors;
|
|
352
475
|
if (result.issues) {
|
|
@@ -385,16 +508,46 @@ async function validateFormInput(internalFormStore, config) {
|
|
|
385
508
|
});
|
|
386
509
|
return result;
|
|
387
510
|
}
|
|
511
|
+
/**
|
|
512
|
+
* Validates the form input if required based on the validation mode and form
|
|
513
|
+
* state. Determines whether to use initial validation mode, revalidation mode,
|
|
514
|
+
* or skip validation entirely.
|
|
515
|
+
*
|
|
516
|
+
* @param internalFormStore The form store to validate.
|
|
517
|
+
* @param internalFieldStore The field store that triggered validation.
|
|
518
|
+
* @param validationMode The validation mode that triggered this check.
|
|
519
|
+
*/
|
|
388
520
|
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);
|
|
521
|
+
if (validationMode === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => /* @__PURE__ */ getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
|
|
390
522
|
}
|
|
523
|
+
/**
|
|
524
|
+
* Internal symbol constant.
|
|
525
|
+
*/
|
|
391
526
|
const INTERNAL = "~internal";
|
|
392
527
|
|
|
393
528
|
//#endregion
|
|
394
529
|
//#region ../../packages/methods/dist/index.vue.js
|
|
395
|
-
|
|
396
|
-
|
|
530
|
+
/**
|
|
531
|
+
* Focuses the first input element of a field. This is useful for
|
|
532
|
+
* programmatically setting focus to a specific field, such as after
|
|
533
|
+
* validation errors or user interactions.
|
|
534
|
+
*
|
|
535
|
+
* @param form The form store containing the field.
|
|
536
|
+
* @param config The focus field configuration.
|
|
537
|
+
*/
|
|
538
|
+
function focus(form, config) {
|
|
539
|
+
getFieldStore(form[INTERNAL], config.path).elements[0]?.focus();
|
|
397
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Retrieves all error messages from all fields in the form by walking through
|
|
543
|
+
* the entire field store tree. This is useful for displaying a summary of all
|
|
544
|
+
* validation errors across the form.
|
|
545
|
+
*
|
|
546
|
+
* @param form The form store to retrieve errors from.
|
|
547
|
+
*
|
|
548
|
+
* @returns A non-empty array of error messages, or null if no errors exist.
|
|
549
|
+
*/
|
|
550
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
398
551
|
function getAllErrors(form) {
|
|
399
552
|
let allErrors = null;
|
|
400
553
|
walkFieldStore(form[INTERNAL], (internalFieldStore) => {
|
|
@@ -404,12 +557,15 @@ function getAllErrors(form) {
|
|
|
404
557
|
});
|
|
405
558
|
return allErrors;
|
|
406
559
|
}
|
|
560
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
407
561
|
function getErrors(form, config) {
|
|
408
562
|
return (config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]).errors.value;
|
|
409
563
|
}
|
|
564
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
410
565
|
function getInput(form, config) {
|
|
411
566
|
return getFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
|
|
412
567
|
}
|
|
568
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
413
569
|
function handleSubmit(form, handler) {
|
|
414
570
|
return async (event) => {
|
|
415
571
|
event.preventDefault();
|
|
@@ -426,6 +582,13 @@ function handleSubmit(form, handler) {
|
|
|
426
582
|
}
|
|
427
583
|
};
|
|
428
584
|
}
|
|
585
|
+
/**
|
|
586
|
+
* Inserts a new item into a field array at the specified index. All items at
|
|
587
|
+
* or after the insertion point are shifted up by one index.
|
|
588
|
+
*
|
|
589
|
+
* @param form The form store containing the field array.
|
|
590
|
+
* @param config The insert configuration specifying the path, index, and initial value.
|
|
591
|
+
*/
|
|
429
592
|
function insert(form, config) {
|
|
430
593
|
const internalFormStore = form[INTERNAL];
|
|
431
594
|
let internalFieldStore = internalFormStore;
|
|
@@ -453,6 +616,13 @@ function insert(form, config) {
|
|
|
453
616
|
validateIfRequired(internalFormStore, internalArrayStore, "input");
|
|
454
617
|
});
|
|
455
618
|
}
|
|
619
|
+
/**
|
|
620
|
+
* Moves an item from one index to another within a field array. All items
|
|
621
|
+
* between the source and destination indices are shifted accordingly.
|
|
622
|
+
*
|
|
623
|
+
* @param form The form store containing the field array.
|
|
624
|
+
* @param config The move configuration specifying the path and source/destination indices.
|
|
625
|
+
*/
|
|
456
626
|
function move(form, config) {
|
|
457
627
|
const internalFormStore = form[INTERNAL];
|
|
458
628
|
const internalArrayStore = getFieldStore(internalFormStore, config.path);
|
|
@@ -472,6 +642,13 @@ function move(form, config) {
|
|
|
472
642
|
validateIfRequired(internalFormStore, internalArrayStore, "input");
|
|
473
643
|
});
|
|
474
644
|
}
|
|
645
|
+
/**
|
|
646
|
+
* Removes an item from a field array at the specified index. All items after
|
|
647
|
+
* the removed item are shifted down by one index.
|
|
648
|
+
*
|
|
649
|
+
* @param form The form store containing the field array.
|
|
650
|
+
* @param config The remove configuration specifying the path and index.
|
|
651
|
+
*/
|
|
475
652
|
function remove(form, config) {
|
|
476
653
|
const internalFormStore = form[INTERNAL];
|
|
477
654
|
const internalArrayStore = getFieldStore(internalFormStore, config.path);
|
|
@@ -486,6 +663,12 @@ function remove(form, config) {
|
|
|
486
663
|
validateIfRequired(internalFormStore, internalArrayStore, "input");
|
|
487
664
|
});
|
|
488
665
|
}
|
|
666
|
+
/**
|
|
667
|
+
* Replaces an item in a field array at the specified index with new initial input.
|
|
668
|
+
*
|
|
669
|
+
* @param form The form store containing the field array.
|
|
670
|
+
* @param config The replace configuration specifying the path, index, and initial input.
|
|
671
|
+
*/
|
|
489
672
|
function replace(form, config) {
|
|
490
673
|
const internalFormStore = form[INTERNAL];
|
|
491
674
|
const internalArrayStore = getFieldStore(internalFormStore, config.path);
|
|
@@ -541,9 +724,21 @@ function setInput(form, config) {
|
|
|
541
724
|
validateIfRequired(internalFormStore, config.path ? getFieldStore(internalFormStore, config.path) : internalFormStore, "input");
|
|
542
725
|
});
|
|
543
726
|
}
|
|
727
|
+
/**
|
|
728
|
+
* Programmatically requests form submission by calling the native
|
|
729
|
+
* `requestSubmit()` method on the underlying form element.
|
|
730
|
+
*
|
|
731
|
+
* @param form The form store to submit.
|
|
732
|
+
*/
|
|
544
733
|
function submit(form) {
|
|
545
734
|
form[INTERNAL].element?.requestSubmit();
|
|
546
735
|
}
|
|
736
|
+
/**
|
|
737
|
+
* Swaps two items in a field array by exchanging their positions.
|
|
738
|
+
*
|
|
739
|
+
* @param form The form store containing the field array.
|
|
740
|
+
* @param config The swap configuration specifying the path and indices to swap.
|
|
741
|
+
*/
|
|
547
742
|
function swap(form, config) {
|
|
548
743
|
const internalFormStore = form[INTERNAL];
|
|
549
744
|
const internalArrayStore = getFieldStore(internalFormStore, config.path);
|
|
@@ -560,12 +755,23 @@ function swap(form, config) {
|
|
|
560
755
|
validateIfRequired(internalFormStore, internalArrayStore, "input");
|
|
561
756
|
});
|
|
562
757
|
}
|
|
758
|
+
/**
|
|
759
|
+
* Validates the entire form input against its schema. Returns a safe parse result
|
|
760
|
+
* indicating success or failure with detailed issues. Optionally focuses the first
|
|
761
|
+
* field with validation errors.
|
|
762
|
+
*
|
|
763
|
+
* @param form The form store to validate.
|
|
764
|
+
* @param config The validate form configuration specifying focus behavior.
|
|
765
|
+
*
|
|
766
|
+
* @returns A promise resolving to the validation result.
|
|
767
|
+
*/
|
|
563
768
|
function validate(form, config) {
|
|
564
769
|
return validateFormInput(form[INTERNAL], config);
|
|
565
770
|
}
|
|
566
771
|
|
|
567
772
|
//#endregion
|
|
568
773
|
//#region src/composables/useField/useField.ts
|
|
774
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
569
775
|
function useField(form, config) {
|
|
570
776
|
const path = computed(() => toValue(config).path);
|
|
571
777
|
const internalFormStore = computed(() => toValue(form)[INTERNAL]);
|
|
@@ -624,6 +830,7 @@ function useField(form, config) {
|
|
|
624
830
|
|
|
625
831
|
//#endregion
|
|
626
832
|
//#region src/composables/useFieldArray/useFieldArray.ts
|
|
833
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
627
834
|
function useFieldArray(form, config) {
|
|
628
835
|
const internalFieldStore = computed(() => getFieldStore(toValue(form)[INTERNAL], toValue(config).path));
|
|
629
836
|
const isTouched = computed(() => getFieldBool(internalFieldStore.value, "isTouched"));
|
|
@@ -653,6 +860,7 @@ function useFieldArray(form, config) {
|
|
|
653
860
|
|
|
654
861
|
//#endregion
|
|
655
862
|
//#region src/composables/useForm/useForm.ts
|
|
863
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
656
864
|
function useForm(config) {
|
|
657
865
|
const internalFormStore = createFormStore(config, (input) => v.safeParseAsync(config.schema, input));
|
|
658
866
|
onBeforeMount(async () => {
|
|
@@ -698,7 +906,7 @@ var Field_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
|
|
|
698
906
|
},
|
|
699
907
|
setup(__props) {
|
|
700
908
|
const props = __props;
|
|
701
|
-
const field = useField(() => props.of, () => ({ path: props.path }));
|
|
909
|
+
const field = /* @__PURE__ */ useField(() => props.of, () => ({ path: props.path }));
|
|
702
910
|
return (_ctx, _cache) => {
|
|
703
911
|
return renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(field))));
|
|
704
912
|
};
|
|
@@ -720,7 +928,7 @@ var FieldArray_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
720
928
|
},
|
|
721
929
|
setup(__props) {
|
|
722
930
|
const props = __props;
|
|
723
|
-
const field = useFieldArray(() => props.of, () => ({ path: props.path }));
|
|
931
|
+
const field = /* @__PURE__ */ useFieldArray(() => props.of, () => ({ path: props.path }));
|
|
724
932
|
return (_ctx, _cache) => {
|
|
725
933
|
return renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(field))));
|
|
726
934
|
};
|
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.
|
|
4
|
+
"version": "0.5.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/
|
|
47
|
-
"@formisch/
|
|
46
|
+
"@formisch/methods": "0.4.0",
|
|
47
|
+
"@formisch/core": "0.4.1"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"typescript": ">=5",
|