@formisch/svelte 0.3.0 → 0.4.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/components/Field/Field.svelte +10 -1
- package/dist/components/Field/Field.svelte.d.ts +10 -1
- package/dist/components/FieldArray/FieldArray.svelte +10 -1
- package/dist/components/FieldArray/FieldArray.svelte.d.ts +10 -1
- package/dist/components/Form/Form.svelte +12 -0
- package/dist/components/Form/Form.svelte.d.ts +12 -0
- package/dist/core/index.svelte.d.ts +350 -27
- package/dist/core/index.svelte.js +162 -25
- package/dist/methods/index.svelte.d.ts +317 -3
- package/dist/methods/index.svelte.js +72 -2
- package/dist/runes/createForm/createForm.svelte.d.ts +8 -0
- package/dist/runes/createForm/createForm.svelte.js +30 -60
- package/dist/runes/useField/useField.svelte.d.ts +14 -0
- package/dist/runes/useField/useField.svelte.js +20 -21
- package/dist/runes/useFieldArray/useFieldArray.svelte.d.ts +14 -0
- package/dist/runes/useFieldArray/useFieldArray.svelte.js +6 -5
- package/dist/types/field.d.ts +63 -3
- package/dist/types/form.d.ts +27 -0
- package/package.json +3 -3
|
@@ -2,10 +2,27 @@ import * as v from "valibot";
|
|
|
2
2
|
import { untrack } from "svelte";
|
|
3
3
|
|
|
4
4
|
//#region src/framework/index.svelte.ts
|
|
5
|
+
/**
|
|
6
|
+
* The current framework being used.
|
|
7
|
+
*/
|
|
5
8
|
const framework = "svelte";
|
|
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
|
+
* Creates a reactive signal with an initial value.
|
|
20
|
+
*
|
|
21
|
+
* @param initialValue The initial value.
|
|
22
|
+
*
|
|
23
|
+
* @returns The created signal.
|
|
24
|
+
*/
|
|
25
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
9
26
|
function createSignal(initialValue) {
|
|
10
27
|
let signal = $state.raw(initialValue);
|
|
11
28
|
return {
|
|
@@ -17,6 +34,14 @@ function createSignal(initialValue) {
|
|
|
17
34
|
}
|
|
18
35
|
};
|
|
19
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Batches multiple signal updates into a single update cycle. This is a
|
|
39
|
+
* no-op in Svelte as batching is handled automatically.
|
|
40
|
+
*
|
|
41
|
+
* @param fn The function to execute.
|
|
42
|
+
*
|
|
43
|
+
* @returns The return value of the function.
|
|
44
|
+
*/
|
|
20
45
|
function batch(fn) {
|
|
21
46
|
return fn();
|
|
22
47
|
}
|
|
@@ -24,8 +49,15 @@ function batch(fn) {
|
|
|
24
49
|
//#endregion
|
|
25
50
|
//#region src/field/initializeFieldStore/initializeFieldStore.ts
|
|
26
51
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
52
|
+
* Initializes a field store recursively based on the schema structure. Handles
|
|
53
|
+
* array, object, and value schemas, setting up all necessary signals and
|
|
54
|
+
* children. Supports wrapped schemas and schema options.
|
|
55
|
+
*
|
|
56
|
+
* @param internalFieldStore The partial field store to initialize.
|
|
57
|
+
* @param schema The Valibot schema defining the field structure.
|
|
58
|
+
* @param initialInput The initial input value.
|
|
59
|
+
* @param path The path to the field in the form.
|
|
60
|
+
* @param nullish Whether the schema is wrapped in a nullish schema.
|
|
29
61
|
*/
|
|
30
62
|
function initializeFieldStore(internalFieldStore, schema, initialInput, path, nullish = false) {
|
|
31
63
|
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`);
|
|
@@ -99,13 +131,13 @@ function initializeFieldStore(internalFieldStore, schema, initialInput, path, nu
|
|
|
99
131
|
//#endregion
|
|
100
132
|
//#region src/array/copyItemState/copyItemState.ts
|
|
101
133
|
/**
|
|
102
|
-
* Copies the deeply nested state (signal values) from one
|
|
103
|
-
* This includes the `
|
|
134
|
+
* Copies the deeply nested state (signal values) from one field store to
|
|
135
|
+
* another. This includes the `elements`, `errors`, `startInput`, `input`,
|
|
136
|
+
* `isTouched`, `isDirty`, and for arrays `startItems` and `items` properties.
|
|
104
137
|
* Recursively walks through the field stores and copies all signal values.
|
|
105
138
|
*
|
|
106
|
-
* @param
|
|
107
|
-
* @param
|
|
108
|
-
* @param toIndex - The destination index to copy to
|
|
139
|
+
* @param fromInternalFieldStore The source field store to copy from.
|
|
140
|
+
* @param toInternalFieldStore The destination field store to copy to.
|
|
109
141
|
*/
|
|
110
142
|
function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
111
143
|
batch(() => {
|
|
@@ -139,13 +171,14 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
|
139
171
|
//#endregion
|
|
140
172
|
//#region src/array/resetItemState/resetItemState.ts
|
|
141
173
|
/**
|
|
142
|
-
* Resets the state of
|
|
143
|
-
*
|
|
144
|
-
* `
|
|
145
|
-
* Keeps the `initialInput` and `initialItems` state unchanged for
|
|
174
|
+
* Resets the state of a field store (signal values) deeply nested. Sets
|
|
175
|
+
* `elements` to empty array, `errors` to `null`, `isTouched` and `isDirty` to
|
|
176
|
+
* `false`, and `startInput`, `input`, `startItems`, and `items` to the new
|
|
177
|
+
* input value. Keeps the `initialInput` and `initialItems` state unchanged for
|
|
178
|
+
* form reset functionality.
|
|
146
179
|
*
|
|
147
|
-
* @param internalFieldStore
|
|
148
|
-
* @param initialInput
|
|
180
|
+
* @param internalFieldStore The field store to reset.
|
|
181
|
+
* @param initialInput The new input value (can be any type including array or object).
|
|
149
182
|
*/
|
|
150
183
|
function resetItemState(internalFieldStore, initialInput) {
|
|
151
184
|
batch(() => {
|
|
@@ -177,12 +210,13 @@ function resetItemState(internalFieldStore, initialInput) {
|
|
|
177
210
|
//#endregion
|
|
178
211
|
//#region src/array/swapItemState/swapItemState.ts
|
|
179
212
|
/**
|
|
180
|
-
* Swaps the deeply nested state (signal values) between two field stores.
|
|
181
|
-
*
|
|
182
|
-
*
|
|
213
|
+
* Swaps the deeply nested state (signal values) between two field stores. This
|
|
214
|
+
* includes the `elements`, `errors`, `startInput`, `input`, `isTouched`,
|
|
215
|
+
* `isDirty`, and for arrays `startItems` and `items` properties. Recursively
|
|
216
|
+
* walks through the field stores and swaps all signal values.
|
|
183
217
|
*
|
|
184
|
-
* @param firstInternalFieldStore
|
|
185
|
-
* @param secondInternalFieldStore
|
|
218
|
+
* @param firstInternalFieldStore The first field store to swap.
|
|
219
|
+
* @param secondInternalFieldStore The second field store to swap.
|
|
186
220
|
*/
|
|
187
221
|
function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
|
|
188
222
|
batch(() => {
|
|
@@ -240,11 +274,21 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
|
|
|
240
274
|
|
|
241
275
|
//#endregion
|
|
242
276
|
//#region src/field/getFieldInput/getFieldInput.ts
|
|
277
|
+
/**
|
|
278
|
+
* Returns the current input of the field store. For arrays and objects,
|
|
279
|
+
* recursively collects input from all children. Returns `null` or `undefined`
|
|
280
|
+
* for nullish array/object inputs, or the primitive value for value fields.
|
|
281
|
+
*
|
|
282
|
+
* @param internalFieldStore The field store to get input from.
|
|
283
|
+
*
|
|
284
|
+
* @returns The field input.
|
|
285
|
+
*/
|
|
286
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
243
287
|
function getFieldInput(internalFieldStore) {
|
|
244
288
|
if (internalFieldStore.kind === "array") {
|
|
245
289
|
if (internalFieldStore.input.value) {
|
|
246
290
|
const value = [];
|
|
247
|
-
for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
|
|
291
|
+
for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = /* @__PURE__ */ getFieldInput(internalFieldStore.children[index]);
|
|
248
292
|
return value;
|
|
249
293
|
}
|
|
250
294
|
return internalFieldStore.input.value;
|
|
@@ -252,7 +296,7 @@ function getFieldInput(internalFieldStore) {
|
|
|
252
296
|
if (internalFieldStore.kind === "object") {
|
|
253
297
|
if (internalFieldStore.input.value) {
|
|
254
298
|
const value = {};
|
|
255
|
-
for (const key in internalFieldStore.children) value[key] = getFieldInput(internalFieldStore.children[key]);
|
|
299
|
+
for (const key in internalFieldStore.children) value[key] = /* @__PURE__ */ getFieldInput(internalFieldStore.children[key]);
|
|
256
300
|
return value;
|
|
257
301
|
}
|
|
258
302
|
return internalFieldStore.input.value;
|
|
@@ -263,13 +307,15 @@ function getFieldInput(internalFieldStore) {
|
|
|
263
307
|
//#endregion
|
|
264
308
|
//#region src/field/getElementInput/getElementInput.ts
|
|
265
309
|
/**
|
|
266
|
-
* Returns the current input of the element.
|
|
310
|
+
* Returns the current input of the element. Handles special cases for select
|
|
311
|
+
* multiple, checkbox groups, radio groups, and file inputs.
|
|
267
312
|
*
|
|
268
313
|
* @param element The field element.
|
|
269
|
-
* @param
|
|
314
|
+
* @param internalFieldStore The internal field store.
|
|
270
315
|
*
|
|
271
316
|
* @returns The element input.
|
|
272
317
|
*/
|
|
318
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
273
319
|
function getElementInput(element, internalFieldStore) {
|
|
274
320
|
if (element.options && element.multiple) return [...element.options].filter((option) => option.selected && !option.disabled).map((option) => option.value);
|
|
275
321
|
if (element.type === "checkbox") {
|
|
@@ -291,14 +337,24 @@ function getElementInput(element, internalFieldStore) {
|
|
|
291
337
|
|
|
292
338
|
//#endregion
|
|
293
339
|
//#region src/field/getFieldBool/getFieldBool.ts
|
|
340
|
+
/**
|
|
341
|
+
* Returns whether the specified boolean property is true for the field store
|
|
342
|
+
* or any of its nested children. Recursively checks arrays and objects.
|
|
343
|
+
*
|
|
344
|
+
* @param internalFieldStore The field store to check.
|
|
345
|
+
* @param type The boolean property type to check.
|
|
346
|
+
*
|
|
347
|
+
* @returns Whether the property is true.
|
|
348
|
+
*/
|
|
349
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
294
350
|
function getFieldBool(internalFieldStore, type) {
|
|
295
351
|
if (internalFieldStore[type].value) return true;
|
|
296
352
|
if (internalFieldStore.kind === "array") {
|
|
297
|
-
for (let index = 0; index < internalFieldStore.items.value.length; index++) if (getFieldBool(internalFieldStore.children[index], type)) return true;
|
|
353
|
+
for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
|
|
298
354
|
return false;
|
|
299
355
|
}
|
|
300
356
|
if (internalFieldStore.kind == "object") {
|
|
301
|
-
for (const key in internalFieldStore.children) if (getFieldBool(internalFieldStore.children[key], type)) return true;
|
|
357
|
+
for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
|
|
302
358
|
return false;
|
|
303
359
|
}
|
|
304
360
|
return false;
|
|
@@ -306,6 +362,16 @@ function getFieldBool(internalFieldStore, type) {
|
|
|
306
362
|
|
|
307
363
|
//#endregion
|
|
308
364
|
//#region src/field/getFieldStore/getFieldStore.ts
|
|
365
|
+
/**
|
|
366
|
+
* Returns the field store at the specified path by traversing the form store's
|
|
367
|
+
* children hierarchy.
|
|
368
|
+
*
|
|
369
|
+
* @param internalFormStore The form store to traverse.
|
|
370
|
+
* @param path The path to the field store.
|
|
371
|
+
*
|
|
372
|
+
* @returns The field store.
|
|
373
|
+
*/
|
|
374
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
309
375
|
function getFieldStore(internalFormStore, path) {
|
|
310
376
|
let internalFieldStore = internalFormStore;
|
|
311
377
|
for (const key of path) internalFieldStore = internalFieldStore.children[key];
|
|
@@ -314,6 +380,14 @@ function getFieldStore(internalFormStore, path) {
|
|
|
314
380
|
|
|
315
381
|
//#endregion
|
|
316
382
|
//#region src/field/setFieldBool/setFieldBool.ts
|
|
383
|
+
/**
|
|
384
|
+
* Sets the specified boolean property for the field store and all nested
|
|
385
|
+
* children. Recursively updates arrays and objects.
|
|
386
|
+
*
|
|
387
|
+
* @param internalFieldStore The field store to update.
|
|
388
|
+
* @param type The boolean property type to set.
|
|
389
|
+
* @param bool The boolean value to set.
|
|
390
|
+
*/
|
|
317
391
|
function setFieldBool(internalFieldStore, type, bool) {
|
|
318
392
|
batch(() => {
|
|
319
393
|
if (internalFieldStore.kind === "array") {
|
|
@@ -326,6 +400,13 @@ function setFieldBool(internalFieldStore, type, bool) {
|
|
|
326
400
|
|
|
327
401
|
//#endregion
|
|
328
402
|
//#region src/field/setFieldInput/setFieldInput.ts
|
|
403
|
+
/**
|
|
404
|
+
* Sets the input for a nested field store and all its children, updating
|
|
405
|
+
* touched and dirty states accordingly. Handles dynamic array resizing.
|
|
406
|
+
*
|
|
407
|
+
* @param internalFieldStore The field store to update.
|
|
408
|
+
* @param input The new input value.
|
|
409
|
+
*/
|
|
329
410
|
function setNestedInput(internalFieldStore, input) {
|
|
330
411
|
internalFieldStore.isTouched.value = true;
|
|
331
412
|
if (internalFieldStore.kind === "array") {
|
|
@@ -344,7 +425,7 @@ function setNestedInput(internalFieldStore, input) {
|
|
|
344
425
|
}
|
|
345
426
|
internalFieldStore.items.value = [...items, ...arrayInput.slice(items.length).map(createId)];
|
|
346
427
|
}
|
|
347
|
-
for (let index = 0; index <
|
|
428
|
+
for (let index = 0; index < arrayInput.length; index++) setNestedInput(internalFieldStore.children[index], arrayInput[index]);
|
|
348
429
|
internalFieldStore.input.value = input == null ? input : true;
|
|
349
430
|
internalFieldStore.isDirty.value = internalFieldStore.startInput.value !== internalFieldStore.input.value || internalFieldStore.startItems.value.length !== items.length;
|
|
350
431
|
} else if (internalFieldStore.kind === "object") {
|
|
@@ -357,6 +438,14 @@ function setNestedInput(internalFieldStore, input) {
|
|
|
357
438
|
internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
|
|
358
439
|
}
|
|
359
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* Sets the input for a field at the specified path in the form store,
|
|
443
|
+
* traversing the path and updating all parent fields along the way.
|
|
444
|
+
*
|
|
445
|
+
* @param internalFormStore The form store containing the field.
|
|
446
|
+
* @param path The path to the field.
|
|
447
|
+
* @param input The new input value.
|
|
448
|
+
*/
|
|
360
449
|
function setFieldInput(internalFormStore, path, input) {
|
|
361
450
|
batch(() => {
|
|
362
451
|
untrack(() => {
|
|
@@ -372,6 +461,14 @@ function setFieldInput(internalFormStore, path, input) {
|
|
|
372
461
|
|
|
373
462
|
//#endregion
|
|
374
463
|
//#region src/field/setInitialFieldInput/setInitialFieldInput.ts
|
|
464
|
+
/**
|
|
465
|
+
* Sets the initial input for a field store and all its children recursively.
|
|
466
|
+
* For arrays, initializes missing children if needed. Updates `initialInput`
|
|
467
|
+
* and `initialItems` properties.
|
|
468
|
+
*
|
|
469
|
+
* @param internalFieldStore The field store to update.
|
|
470
|
+
* @param initialInput The initial input value.
|
|
471
|
+
*/
|
|
375
472
|
function setInitialFieldInput(internalFieldStore, initialInput) {
|
|
376
473
|
batch(() => {
|
|
377
474
|
if (internalFieldStore.kind === "array") {
|
|
@@ -397,6 +494,13 @@ function setInitialFieldInput(internalFieldStore, initialInput) {
|
|
|
397
494
|
|
|
398
495
|
//#endregion
|
|
399
496
|
//#region src/field/walkFieldStore/walkFieldStore.ts
|
|
497
|
+
/**
|
|
498
|
+
* Walks through the field store and all nested children, calling the callback
|
|
499
|
+
* for each field store in depth-first order.
|
|
500
|
+
*
|
|
501
|
+
* @param internalFieldStore The field store to walk.
|
|
502
|
+
* @param callback The callback to invoke for each field store.
|
|
503
|
+
*/
|
|
400
504
|
function walkFieldStore(internalFieldStore, callback) {
|
|
401
505
|
callback(internalFieldStore);
|
|
402
506
|
if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
|
|
@@ -405,9 +509,20 @@ function walkFieldStore(internalFieldStore, callback) {
|
|
|
405
509
|
|
|
406
510
|
//#endregion
|
|
407
511
|
//#region src/form/createFormStore/createFormStore.ts
|
|
512
|
+
/**
|
|
513
|
+
* Creates a new internal form store from the provided configuration.
|
|
514
|
+
* Initializes the field store hierarchy, sets validation modes, and
|
|
515
|
+
* creates form state signals.
|
|
516
|
+
*
|
|
517
|
+
* @param config The form configuration.
|
|
518
|
+
* @param parse The schema parse function.
|
|
519
|
+
*
|
|
520
|
+
* @returns The internal form store.
|
|
521
|
+
*/
|
|
408
522
|
function createFormStore(config, parse) {
|
|
409
523
|
const store = {};
|
|
410
524
|
initializeFieldStore(store, config.schema, config.initialInput, []);
|
|
525
|
+
store.validators = 0;
|
|
411
526
|
store.validate = config.validate ?? "submit";
|
|
412
527
|
store.revalidate = config.revalidate ?? "input";
|
|
413
528
|
store.parse = parse;
|
|
@@ -419,6 +534,16 @@ function createFormStore(config, parse) {
|
|
|
419
534
|
|
|
420
535
|
//#endregion
|
|
421
536
|
//#region src/form/validateFormInput/validateFormInput.ts
|
|
537
|
+
/**
|
|
538
|
+
* Validates the form input using the configured Valibot schema. Parses the
|
|
539
|
+
* current form input, processes validation issues, assigns errors to fields,
|
|
540
|
+
* and optionally focuses the first field with an error.
|
|
541
|
+
*
|
|
542
|
+
* @param internalFormStore The form store to validate.
|
|
543
|
+
* @param config The validation configuration.
|
|
544
|
+
*
|
|
545
|
+
* @returns The Valibot validation result.
|
|
546
|
+
*/
|
|
422
547
|
async function validateFormInput(internalFormStore, config) {
|
|
423
548
|
internalFormStore.validators++;
|
|
424
549
|
internalFormStore.isValidating.value = true;
|
|
@@ -464,12 +589,24 @@ async function validateFormInput(internalFormStore, config) {
|
|
|
464
589
|
|
|
465
590
|
//#endregion
|
|
466
591
|
//#region src/form/validateIfRequired/validateIfRequired.ts
|
|
592
|
+
/**
|
|
593
|
+
* Validates the form input if required based on the validation mode and form
|
|
594
|
+
* state. Determines whether to use initial validation mode, revalidation mode,
|
|
595
|
+
* or skip validation entirely.
|
|
596
|
+
*
|
|
597
|
+
* @param internalFormStore The form store to validate.
|
|
598
|
+
* @param internalFieldStore The field store that triggered validation.
|
|
599
|
+
* @param validationMode The validation mode that triggered this check.
|
|
600
|
+
*/
|
|
467
601
|
function validateIfRequired(internalFormStore, internalFieldStore, validationMode) {
|
|
468
602
|
if (validationMode === (internalFormStore.validate === "initial" || (internalFormStore.validate === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidate : internalFormStore.validate)) validateFormInput(internalFormStore);
|
|
469
603
|
}
|
|
470
604
|
|
|
471
605
|
//#endregion
|
|
472
606
|
//#region src/values.ts
|
|
607
|
+
/**
|
|
608
|
+
* Internal symbol constant.
|
|
609
|
+
*/
|
|
473
610
|
const INTERNAL = "~internal";
|
|
474
611
|
|
|
475
612
|
//#endregion
|