@formisch/qwik 0.10.1 → 0.12.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/README.md +5 -1
- package/dist/index.d.ts +228 -63
- package/dist/index.qwik.js +228 -97
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -64,7 +64,11 @@ In addition, Formisch offers several functions (we call them "methods") that can
|
|
|
64
64
|
|
|
65
65
|
## Comparison
|
|
66
66
|
|
|
67
|
-
What makes Formisch unique is its framework-agnostic core, which is fully native to the framework you are using. It works by inserting framework-specific reactivity blocks when the core package is built
|
|
67
|
+
What makes Formisch unique is its framework-agnostic core, which is fully native to the framework you are using. It works by inserting framework-specific reactivity blocks when the core package is built, giving you native performance for any UI update. A modular methods API keeps bundles starting at just ~2.5 kB by only including the methods you import, and end-to-end type safety covers deeply nested paths and field arrays with TypeScript inference that stays fast even as forms grow.
|
|
68
|
+
|
|
69
|
+
## Vision
|
|
70
|
+
|
|
71
|
+
My vision for Formisch is to create a framework-agnostic platform similar to [Vite](https://vite.dev/), but for forms — a shared core that lets the same mental model and codebase work natively across every modern UI framework.
|
|
68
72
|
|
|
69
73
|
## Partners
|
|
70
74
|
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,31 @@ import * as _qwik_dev_core_internal0 from "@qwik.dev/core/internal";
|
|
|
9
9
|
* Schema type.
|
|
10
10
|
*/
|
|
11
11
|
type Schema = v.GenericSchema | v.GenericSchemaAsync;
|
|
12
|
+
/**
|
|
13
|
+
* Object schema type.
|
|
14
|
+
*/
|
|
15
|
+
type ObjectSchema = v.LooseObjectSchema<v.ObjectEntries, v.ErrorMessage<v.LooseObjectIssue> | undefined> | v.ObjectSchema<v.ObjectEntries, v.ErrorMessage<v.ObjectIssue> | undefined> | v.StrictObjectSchema<v.ObjectEntries, v.ErrorMessage<v.StrictObjectIssue> | undefined> | v.VariantSchema<string, v.VariantOptions<string>, v.ErrorMessage<v.VariantIssue> | undefined>;
|
|
16
|
+
/**
|
|
17
|
+
* Object schema async type.
|
|
18
|
+
*/
|
|
19
|
+
type ObjectSchemaAsync = v.LooseObjectSchemaAsync<v.ObjectEntriesAsync, v.ErrorMessage<v.LooseObjectIssue> | undefined> | v.ObjectSchemaAsync<v.ObjectEntriesAsync, v.ErrorMessage<v.ObjectIssue> | undefined> | v.StrictObjectSchemaAsync<v.ObjectEntriesAsync, v.ErrorMessage<v.StrictObjectIssue> | undefined> | v.VariantSchemaAsync<string, v.VariantOptionsAsync<string>, v.ErrorMessage<v.VariantIssue> | undefined>;
|
|
20
|
+
/**
|
|
21
|
+
* Object root schema type.
|
|
22
|
+
*/
|
|
23
|
+
type ObjectRootSchema = ObjectSchema | v.IntersectSchema<ObjectSchema[], v.ErrorMessage<v.IntersectIssue> | undefined> | v.UnionSchema<ObjectSchema[], v.ErrorMessage<v.UnionIssue<v.BaseIssue<unknown>>> | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* Object root schema async type.
|
|
26
|
+
*/
|
|
27
|
+
type ObjectRootSchemaAsync = ObjectSchemaAsync | v.IntersectSchemaAsync<(ObjectSchema | ObjectSchemaAsync)[], v.ErrorMessage<v.IntersectIssue> | undefined> | v.UnionSchemaAsync<(ObjectSchema | ObjectSchemaAsync)[], v.ErrorMessage<v.UnionIssue<v.BaseIssue<unknown>>> | undefined>;
|
|
28
|
+
/**
|
|
29
|
+
* Form schema type.
|
|
30
|
+
*
|
|
31
|
+
* Hint: Forms must have an object root, so only object schemas (sync or async),
|
|
32
|
+
* combinators (intersect, union, variant) whose options resolve to objects, and
|
|
33
|
+
* `lazy` schemas wrapping any of these are allowed at the top level. Use
|
|
34
|
+
* {@link Schema} for nested field schemas.
|
|
35
|
+
*/
|
|
36
|
+
type FormSchema = ObjectRootSchema | ObjectRootSchemaAsync | v.LazySchema<ObjectRootSchema> | v.LazySchemaAsync<ObjectRootSchema | ObjectRootSchemaAsync>;
|
|
12
37
|
//#endregion
|
|
13
38
|
//#region src/types/signal/signal.d.ts
|
|
14
39
|
/**
|
|
@@ -49,6 +74,17 @@ interface InternalBaseStore {
|
|
|
49
74
|
*/
|
|
50
75
|
schema: NoSerialize<Schema>;
|
|
51
76
|
/**
|
|
77
|
+
* The initial elements of the field.
|
|
78
|
+
*
|
|
79
|
+
* Hint: This may look unused, but do not remove it. `copyItemState` and
|
|
80
|
+
* `swapItemState` move the `elements` reference between field stores when
|
|
81
|
+
* array items are inserted, moved, removed or swapped, and `reset` restores
|
|
82
|
+
* each field's original element via `elements = initialElements`. Without it,
|
|
83
|
+
* focus and file reset target the wrong element after a reorder followed by a
|
|
84
|
+
* reset.
|
|
85
|
+
*/
|
|
86
|
+
initialElements: FieldElement[];
|
|
87
|
+
/**
|
|
52
88
|
* The elements of the field.
|
|
53
89
|
*/
|
|
54
90
|
elements: FieldElement[];
|
|
@@ -177,14 +213,6 @@ interface InternalValueStore extends InternalBaseStore {
|
|
|
177
213
|
* The input of the value field.
|
|
178
214
|
*/
|
|
179
215
|
input: Signal<unknown>;
|
|
180
|
-
/**
|
|
181
|
-
* The touched state of the field.
|
|
182
|
-
*/
|
|
183
|
-
isTouched: Signal<boolean>;
|
|
184
|
-
/**
|
|
185
|
-
* The dirty state of the field.
|
|
186
|
-
*/
|
|
187
|
-
isDirty: Signal<boolean>;
|
|
188
216
|
}
|
|
189
217
|
/**
|
|
190
218
|
* Internal field store type.
|
|
@@ -231,17 +259,17 @@ type ValidationMode = "initial" | "touch" | "input" | "change" | "blur" | "submi
|
|
|
231
259
|
/**
|
|
232
260
|
* Submit handler type.
|
|
233
261
|
*/
|
|
234
|
-
type SubmitHandler<TSchema extends
|
|
262
|
+
type SubmitHandler<TSchema extends FormSchema> = (output: v.InferOutput<TSchema>) => MaybePromise<unknown>;
|
|
235
263
|
/**
|
|
236
264
|
* Submit event handler type.
|
|
237
265
|
*/
|
|
238
|
-
type SubmitEventHandler<TSchema extends
|
|
266
|
+
type SubmitEventHandler<TSchema extends FormSchema> = (output: v.InferOutput<TSchema>, event: SubmitEvent) => MaybePromise<unknown>;
|
|
239
267
|
//#endregion
|
|
240
268
|
//#region src/types/form/form.qwik.d.ts
|
|
241
269
|
/**
|
|
242
270
|
* Form config interface.
|
|
243
271
|
*/
|
|
244
|
-
interface FormConfig<TSchema extends
|
|
272
|
+
interface FormConfig<TSchema extends FormSchema = FormSchema> {
|
|
245
273
|
/**
|
|
246
274
|
* The schema of the form.
|
|
247
275
|
*/
|
|
@@ -262,7 +290,7 @@ interface FormConfig<TSchema extends Schema = Schema> {
|
|
|
262
290
|
/**
|
|
263
291
|
* Internal form store interface.
|
|
264
292
|
*/
|
|
265
|
-
interface InternalFormStore<TSchema extends
|
|
293
|
+
interface InternalFormStore<TSchema extends FormSchema = FormSchema> extends InternalObjectStore {
|
|
266
294
|
/**
|
|
267
295
|
* The element of the form.
|
|
268
296
|
*/
|
|
@@ -299,7 +327,7 @@ interface InternalFormStore<TSchema extends Schema = Schema> extends InternalObj
|
|
|
299
327
|
/**
|
|
300
328
|
* Base form store interface.
|
|
301
329
|
*/
|
|
302
|
-
interface BaseFormStore<TSchema extends
|
|
330
|
+
interface BaseFormStore<TSchema extends FormSchema = FormSchema> {
|
|
303
331
|
/**
|
|
304
332
|
* The internal form store.
|
|
305
333
|
*
|
|
@@ -377,7 +405,10 @@ type ExactRequired<TValue> = TValue extends Record<PropertyKey, unknown> ? IsExa
|
|
|
377
405
|
*/
|
|
378
406
|
type PathValue<TValue, TPath extends Path> = TPath extends readonly [infer TKey, ...infer TRest extends Path] ? TKey extends ExactKeysOf<ExactRequired<TValue>> ? PathValue<PropertiesOf<ExactRequired<TValue>>[TKey], TRest> : unknown : TValue;
|
|
379
407
|
/**
|
|
380
|
-
* Checks whether a value is
|
|
408
|
+
* Checks whether a value is a dynamic array or contains one anywhere in its
|
|
409
|
+
* shape. A fixed-length tuple is not itself a dynamic array, but it counts when
|
|
410
|
+
* it contains one, so paths can still navigate through tuples to reach nested
|
|
411
|
+
* arrays.
|
|
381
412
|
*
|
|
382
413
|
* Hint: The inner conditionals (`TValue extends readonly unknown[]` and
|
|
383
414
|
* `TValue extends Record<PropertyKey, unknown>`) distribute over union members,
|
|
@@ -388,7 +419,7 @@ type PathValue<TValue, TPath extends Path> = TPath extends readonly [infer TKey,
|
|
|
388
419
|
* `true extends ...`, which is `true` whenever at least one union member
|
|
389
420
|
* contributed `true`.
|
|
390
421
|
*/
|
|
391
|
-
type IsOrHasArray<TValue> = true extends (IsAny<TValue> extends true ? false : TValue extends readonly unknown[] ? true : TValue extends Record<PropertyKey, unknown> ? { [TKey in keyof TValue]: IsOrHasArray<TValue[TKey]> }[keyof TValue] : false) ? true : false;
|
|
422
|
+
type IsOrHasArray<TValue> = true extends (IsAny<TValue> extends true ? false : TValue extends readonly unknown[] ? number extends TValue["length"] ? true : IsOrHasArray<TValue[number]> : TValue extends Record<PropertyKey, unknown> ? { [TKey in keyof TValue]: IsOrHasArray<TValue[TKey]> }[keyof TValue] : false) ? true : false;
|
|
392
423
|
/**
|
|
393
424
|
* Extracts the exact keys of a tuple, array or object that contain arrays.
|
|
394
425
|
*/
|
|
@@ -403,12 +434,34 @@ type PropertiesOfArrayPath<TValue> = { [TKey in ExactKeysOfArrayPath<TValue>]: T
|
|
|
403
434
|
/**
|
|
404
435
|
* Lazily evaluates only the first valid array path segment based on the given value.
|
|
405
436
|
*/
|
|
406
|
-
type LazyArrayPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValue extends readonly unknown[] ? TValidPath : readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : TPathToCheck extends readonly [infer TFirstKey extends ExactKeysOfArrayPath<TValue>, ...infer TPathRest extends Path] ? LazyArrayPath<Required<PropertiesOfArrayPath<TValue>[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever<ExactKeysOfArrayPath<TValue>> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : never;
|
|
437
|
+
type LazyArrayPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValue extends readonly unknown[] ? number extends TValue["length"] ? TValidPath : IsNever<ExactKeysOfArrayPath<TValue>> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : never : readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : TPathToCheck extends readonly [infer TFirstKey extends ExactKeysOfArrayPath<TValue>, ...infer TPathRest extends Path] ? LazyArrayPath<Required<PropertiesOfArrayPath<TValue>[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever<ExactKeysOfArrayPath<TValue>> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : never;
|
|
407
438
|
/**
|
|
408
439
|
* Returns the path if valid, otherwise the first possible valid array path
|
|
409
440
|
* based on the given value.
|
|
410
441
|
*/
|
|
411
442
|
type ValidArrayPath<TValue, TPath extends RequiredPath> = TPath extends LazyArrayPath<Required<TValue>, TPath> ? TPath : LazyArrayPath<Required<TValue>, TPath>;
|
|
443
|
+
/**
|
|
444
|
+
* Recursive helper for `DirtyPath` that prepends `TKey` to each deeper path,
|
|
445
|
+
* or falls through to `never` when the child is not an object.
|
|
446
|
+
*/
|
|
447
|
+
type DeepDirtyPath<TChild, TKey$1 extends PathKey, TDepth extends 0[]> = TChild extends Record<PropertyKey, unknown> ? readonly [TKey$1, ...DirtyPath<TChild, [...TDepth, 0]>] : never;
|
|
448
|
+
/**
|
|
449
|
+
* Returns the union of all `RequiredPath`s that `getDirtyPaths` can emit
|
|
450
|
+
* for a given input type. Object fields contribute their own path and the
|
|
451
|
+
* paths of their descendants; arrays and tuples are atomic and contribute
|
|
452
|
+
* only their own path, because dirty arrays are returned as complete units.
|
|
453
|
+
*
|
|
454
|
+
* Narrowing is exact for the first 5 levels of nesting; deeper paths fall
|
|
455
|
+
* back to `RequiredPath` to keep the result a complete superset of any
|
|
456
|
+
* path the runtime can address.
|
|
457
|
+
*
|
|
458
|
+
* Hint: Arrays and tuples are atomic because they don't structurally
|
|
459
|
+
* extend `Record<PropertyKey, unknown>` and so fall through to `never`
|
|
460
|
+
* via `DeepDirtyPath` — no explicit array check is needed. `TDepth` is
|
|
461
|
+
* a tuple-length counter capped at 5 to bound TypeScript instantiation
|
|
462
|
+
* cost.
|
|
463
|
+
*/
|
|
464
|
+
type DirtyPath<TValue, TDepth extends 0[] = []> = TDepth["length"] extends 5 ? RequiredPath : TValue extends Record<PropertyKey, unknown> ? { [TKey in ExactKeysOf<TValue>]: readonly [TKey] | DeepDirtyPath<NonNullable<PropertiesOf<TValue>[TKey]>, TKey, TDepth> }[ExactKeysOf<TValue>] : never;
|
|
412
465
|
//#endregion
|
|
413
466
|
//#region src/array/copyItemState/copyItemState.d.ts
|
|
414
467
|
/**
|
|
@@ -427,21 +480,21 @@ type ValidArrayPath<TValue, TPath extends RequiredPath> = TPath extends LazyArra
|
|
|
427
480
|
/**
|
|
428
481
|
* Focus field config interface.
|
|
429
482
|
*/
|
|
430
|
-
interface FocusFieldConfig<TSchema extends
|
|
483
|
+
interface FocusFieldConfig<TSchema extends FormSchema, TFieldPath extends RequiredPath> {
|
|
431
484
|
/**
|
|
432
485
|
* The path to the field to focus.
|
|
433
486
|
*/
|
|
434
487
|
readonly path: ValidPath<v.InferInput<TSchema>, TFieldPath>;
|
|
435
488
|
}
|
|
436
489
|
/**
|
|
437
|
-
* Focuses the first input element of a field. This is useful for
|
|
490
|
+
* Focuses the first focusable input element of a field. This is useful for
|
|
438
491
|
* programmatically setting focus to a specific field, such as after
|
|
439
492
|
* validation errors or user interactions.
|
|
440
493
|
*
|
|
441
494
|
* @param form The form store containing the field.
|
|
442
495
|
* @param config The focus field configuration.
|
|
443
496
|
*/
|
|
444
|
-
declare function focus<TSchema extends
|
|
497
|
+
declare function focus<TSchema extends FormSchema, TFieldPath extends RequiredPath>(form: BaseFormStore<TSchema>, config: FocusFieldConfig<TSchema, TFieldPath>): void;
|
|
445
498
|
//#endregion
|
|
446
499
|
//#region src/getAllErrors/getAllErrors.d.ts
|
|
447
500
|
/**
|
|
@@ -455,6 +508,93 @@ declare function focus<TSchema extends Schema, TFieldPath extends RequiredPath>(
|
|
|
455
508
|
*/
|
|
456
509
|
declare function getAllErrors(form: BaseFormStore): [string, ...string[]] | null;
|
|
457
510
|
//#endregion
|
|
511
|
+
//#region src/getDirtyInput/getDirtyInput.d.ts
|
|
512
|
+
/**
|
|
513
|
+
* Get form dirty input config interface.
|
|
514
|
+
*/
|
|
515
|
+
interface GetFormDirtyInputConfig {
|
|
516
|
+
/**
|
|
517
|
+
* The path to a field. Leave undefined to get the dirty input of the entire
|
|
518
|
+
* form.
|
|
519
|
+
*/
|
|
520
|
+
readonly path?: undefined;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Get field dirty input config interface.
|
|
524
|
+
*/
|
|
525
|
+
interface GetFieldDirtyInputConfig<TSchema extends FormSchema, TFieldPath extends RequiredPath> {
|
|
526
|
+
/**
|
|
527
|
+
* The path to the field to retrieve the dirty input from.
|
|
528
|
+
*/
|
|
529
|
+
readonly path: ValidPath<v.InferInput<TSchema>, TFieldPath>;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Retrieves only the dirty input values of a specific field or the entire
|
|
533
|
+
* form. Arrays are treated as atomic and returned in full if any item is
|
|
534
|
+
* dirty, while object keys without a dirty descendant are omitted. Returns
|
|
535
|
+
* `undefined` if no field in the inspected subtree is dirty.
|
|
536
|
+
*
|
|
537
|
+
* @param form The form store to retrieve dirty input from.
|
|
538
|
+
*
|
|
539
|
+
* @returns The dirty input of the form or specified field, or `undefined`.
|
|
540
|
+
*/
|
|
541
|
+
declare function getDirtyInput<TSchema extends FormSchema>(form: BaseFormStore<TSchema>): DeepPartial<v.InferInput<TSchema>> | undefined;
|
|
542
|
+
/**
|
|
543
|
+
* Retrieves only the dirty input values of a specific field or the entire
|
|
544
|
+
* form. Arrays are treated as atomic and returned in full if any item is
|
|
545
|
+
* dirty, while object keys without a dirty descendant are omitted. Returns
|
|
546
|
+
* `undefined` if no field in the inspected subtree is dirty.
|
|
547
|
+
*
|
|
548
|
+
* @param form The form store to retrieve dirty input from.
|
|
549
|
+
* @param config The get dirty input configuration.
|
|
550
|
+
*
|
|
551
|
+
* @returns The dirty input of the form or specified field, or `undefined`.
|
|
552
|
+
*/
|
|
553
|
+
declare function getDirtyInput<TSchema extends FormSchema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? GetFieldDirtyInputConfig<TSchema, TFieldPath> : GetFormDirtyInputConfig): DeepPartial<TFieldPath extends RequiredPath ? PathValue<v.InferInput<TSchema>, TFieldPath> : v.InferInput<TSchema>> | undefined;
|
|
554
|
+
//#endregion
|
|
555
|
+
//#region src/getDirtyPaths/getDirtyPaths.d.ts
|
|
556
|
+
/**
|
|
557
|
+
* Get form dirty paths config interface.
|
|
558
|
+
*/
|
|
559
|
+
interface GetFormDirtyPathsConfig {
|
|
560
|
+
/**
|
|
561
|
+
* The path to a field. Leave undefined to inspect the entire form.
|
|
562
|
+
*/
|
|
563
|
+
readonly path?: undefined;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Get field dirty paths config interface.
|
|
567
|
+
*/
|
|
568
|
+
interface GetFieldDirtyPathsConfig<TSchema extends FormSchema, TFieldPath extends RequiredPath> {
|
|
569
|
+
/**
|
|
570
|
+
* The path to the field to inspect.
|
|
571
|
+
*/
|
|
572
|
+
readonly path: ValidPath<v.InferInput<TSchema>, TFieldPath>;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Returns a list of paths to the dirty fields of a specific field or the
|
|
576
|
+
* entire form. Arrays are treated as atomic and contribute only their own
|
|
577
|
+
* path if any item is dirty, while object branches are recursed into. Returns
|
|
578
|
+
* an empty list if no field in the inspected subtree is dirty.
|
|
579
|
+
*
|
|
580
|
+
* @param form The form store to inspect.
|
|
581
|
+
*
|
|
582
|
+
* @returns The list of paths to the dirty fields.
|
|
583
|
+
*/
|
|
584
|
+
declare function getDirtyPaths<TSchema extends FormSchema>(form: BaseFormStore<TSchema>): DirtyPath<v.InferInput<TSchema>>[];
|
|
585
|
+
/**
|
|
586
|
+
* Returns a list of paths to the dirty fields of a specific field or the
|
|
587
|
+
* entire form. Arrays are treated as atomic and contribute only their own
|
|
588
|
+
* path if any item is dirty, while object branches are recursed into. Returns
|
|
589
|
+
* an empty list if no field in the inspected subtree is dirty.
|
|
590
|
+
*
|
|
591
|
+
* @param form The form store to inspect.
|
|
592
|
+
* @param config The get dirty paths configuration.
|
|
593
|
+
*
|
|
594
|
+
* @returns The list of paths to the dirty fields.
|
|
595
|
+
*/
|
|
596
|
+
declare function getDirtyPaths<TSchema extends FormSchema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? GetFieldDirtyPathsConfig<TSchema, TFieldPath> : GetFormDirtyPathsConfig): DirtyPath<v.InferInput<TSchema>>[];
|
|
597
|
+
//#endregion
|
|
458
598
|
//#region src/getErrors/getErrors.d.ts
|
|
459
599
|
/**
|
|
460
600
|
* Get form errors config interface.
|
|
@@ -468,7 +608,7 @@ interface GetFormErrorsConfig {
|
|
|
468
608
|
/**
|
|
469
609
|
* Get field errors config interface.
|
|
470
610
|
*/
|
|
471
|
-
interface GetFieldErrorsConfig<TSchema extends
|
|
611
|
+
interface GetFieldErrorsConfig<TSchema extends FormSchema, TFieldPath extends RequiredPath> {
|
|
472
612
|
/**
|
|
473
613
|
* The path to the field to retrieve errors from.
|
|
474
614
|
*/
|
|
@@ -483,7 +623,7 @@ interface GetFieldErrorsConfig<TSchema extends Schema, TFieldPath extends Requir
|
|
|
483
623
|
*
|
|
484
624
|
* @returns A non-empty array of error messages, or null if no errors exist.
|
|
485
625
|
*/
|
|
486
|
-
declare function getErrors<TSchema extends
|
|
626
|
+
declare function getErrors<TSchema extends FormSchema>(form: BaseFormStore<TSchema>): [string, ...string[]] | null;
|
|
487
627
|
/**
|
|
488
628
|
* Retrieves error messages from the form. When called without a config,
|
|
489
629
|
* returns form-level errors. When called with a path, returns errors for
|
|
@@ -494,7 +634,7 @@ declare function getErrors<TSchema extends Schema>(form: BaseFormStore<TSchema>)
|
|
|
494
634
|
*
|
|
495
635
|
* @returns A non-empty array of error messages, or null if no errors exist.
|
|
496
636
|
*/
|
|
497
|
-
declare function getErrors<TSchema extends
|
|
637
|
+
declare function getErrors<TSchema extends FormSchema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? GetFieldErrorsConfig<TSchema, TFieldPath> : GetFormErrorsConfig): [string, ...string[]] | null;
|
|
498
638
|
//#endregion
|
|
499
639
|
//#region src/getInput/getInput.d.ts
|
|
500
640
|
/**
|
|
@@ -509,7 +649,7 @@ interface GetFormInputConfig {
|
|
|
509
649
|
/**
|
|
510
650
|
* Get field input config interface.
|
|
511
651
|
*/
|
|
512
|
-
interface GetFieldInputConfig<TSchema extends
|
|
652
|
+
interface GetFieldInputConfig<TSchema extends FormSchema, TFieldPath extends RequiredPath> {
|
|
513
653
|
/**
|
|
514
654
|
* The path to the field to retrieve input from.
|
|
515
655
|
*/
|
|
@@ -523,7 +663,7 @@ interface GetFieldInputConfig<TSchema extends Schema, TFieldPath extends Require
|
|
|
523
663
|
*
|
|
524
664
|
* @returns The partial input values of the form or the specified field.
|
|
525
665
|
*/
|
|
526
|
-
declare function getInput<TSchema extends
|
|
666
|
+
declare function getInput<TSchema extends FormSchema>(form: BaseFormStore<TSchema>): PartialValues<v.InferInput<TSchema>>;
|
|
527
667
|
/**
|
|
528
668
|
* Retrieves the current input value of a specific field or the entire form.
|
|
529
669
|
* Returns a partial object as not all fields may have been set.
|
|
@@ -533,7 +673,7 @@ declare function getInput<TSchema extends Schema>(form: BaseFormStore<TSchema>):
|
|
|
533
673
|
*
|
|
534
674
|
* @returns The partial input values of the form or the specified field.
|
|
535
675
|
*/
|
|
536
|
-
declare function getInput<TSchema extends
|
|
676
|
+
declare function getInput<TSchema extends FormSchema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? GetFieldInputConfig<TSchema, TFieldPath> : GetFormInputConfig): PartialValues<TFieldPath extends RequiredPath ? PathValue<v.InferInput<TSchema>, TFieldPath> : v.InferInput<TSchema>>;
|
|
537
677
|
//#endregion
|
|
538
678
|
//#region src/handleSubmit/handleSubmit.d.ts
|
|
539
679
|
/**
|
|
@@ -546,7 +686,7 @@ declare function getInput<TSchema extends Schema, TFieldPath extends RequiredPat
|
|
|
546
686
|
*
|
|
547
687
|
* @returns A submit event handler function to attach to the form element.
|
|
548
688
|
*/
|
|
549
|
-
declare function handleSubmit<TSchema extends
|
|
689
|
+
declare function handleSubmit<TSchema extends FormSchema>(form: BaseFormStore<TSchema>, handler: SubmitHandler<TSchema>): () => Promise<void>;
|
|
550
690
|
/**
|
|
551
691
|
* Creates a submit event handler for the form that prevents default browser
|
|
552
692
|
* submission, validates the form input, and calls the provided handler if
|
|
@@ -557,13 +697,13 @@ declare function handleSubmit<TSchema extends Schema>(form: BaseFormStore<TSchem
|
|
|
557
697
|
*
|
|
558
698
|
* @returns A submit event handler function to attach to the form element.
|
|
559
699
|
*/
|
|
560
|
-
declare function handleSubmit<TSchema extends
|
|
700
|
+
declare function handleSubmit<TSchema extends FormSchema>(form: BaseFormStore<TSchema>, handler: SubmitEventHandler<TSchema>): (event: SubmitEvent) => Promise<void>;
|
|
561
701
|
//#endregion
|
|
562
702
|
//#region src/insert/insert.d.ts
|
|
563
703
|
/**
|
|
564
704
|
* Insert array field config interface.
|
|
565
705
|
*/
|
|
566
|
-
interface InsertConfig<TSchema extends
|
|
706
|
+
interface InsertConfig<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath> {
|
|
567
707
|
/**
|
|
568
708
|
* The path to the field array to insert into.
|
|
569
709
|
*/
|
|
@@ -584,13 +724,13 @@ interface InsertConfig<TSchema extends Schema, TFieldArrayPath extends RequiredP
|
|
|
584
724
|
* @param form The form store containing the field array.
|
|
585
725
|
* @param config The insert configuration specifying the path, index, and initial value.
|
|
586
726
|
*/
|
|
587
|
-
declare function insert<TSchema extends
|
|
727
|
+
declare function insert<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath>(form: BaseFormStore<TSchema>, config: InsertConfig<TSchema, TFieldArrayPath>): void;
|
|
588
728
|
//#endregion
|
|
589
729
|
//#region src/move/move.d.ts
|
|
590
730
|
/**
|
|
591
731
|
* Move array field config interface.
|
|
592
732
|
*/
|
|
593
|
-
interface MoveConfig<TSchema extends
|
|
733
|
+
interface MoveConfig<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath> {
|
|
594
734
|
/**
|
|
595
735
|
* The path to the field array to move an item within.
|
|
596
736
|
*/
|
|
@@ -611,13 +751,38 @@ interface MoveConfig<TSchema extends Schema, TFieldArrayPath extends RequiredPat
|
|
|
611
751
|
* @param form The form store containing the field array.
|
|
612
752
|
* @param config The move configuration specifying the path and source/destination indices.
|
|
613
753
|
*/
|
|
614
|
-
declare function move<TSchema extends
|
|
754
|
+
declare function move<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath>(form: BaseFormStore<TSchema>, config: MoveConfig<TSchema, TFieldArrayPath>): void;
|
|
755
|
+
//#endregion
|
|
756
|
+
//#region src/pickDirty/pickDirty.d.ts
|
|
757
|
+
/**
|
|
758
|
+
* Pick dirty config interface.
|
|
759
|
+
*/
|
|
760
|
+
interface PickDirtyConfig<TValue extends object> {
|
|
761
|
+
/**
|
|
762
|
+
* The value to filter down to its dirty parts. Must be structurally
|
|
763
|
+
* compatible with the form's schema.
|
|
764
|
+
*/
|
|
765
|
+
readonly from: TValue;
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Picks only the dirty parts of the given value, using the form's dirty fields
|
|
769
|
+
* as a structural mask. Arrays are treated as atomic and object keys without a
|
|
770
|
+
* dirty descendant are omitted. Returns `undefined` if no field is dirty.
|
|
771
|
+
* Useful for filtering a validated output down to its changed parts before
|
|
772
|
+
* submitting.
|
|
773
|
+
*
|
|
774
|
+
* @param form The form store providing the dirty mask.
|
|
775
|
+
* @param config The pick dirty configuration.
|
|
776
|
+
*
|
|
777
|
+
* @returns The dirty parts of the value, or `undefined`.
|
|
778
|
+
*/
|
|
779
|
+
declare function pickDirty<TSchema extends FormSchema, TValue extends object>(form: BaseFormStore<TSchema>, config: PickDirtyConfig<TValue>): DeepPartial<TValue> | undefined;
|
|
615
780
|
//#endregion
|
|
616
781
|
//#region src/remove/remove.d.ts
|
|
617
782
|
/**
|
|
618
783
|
* Remove array field config interface.
|
|
619
784
|
*/
|
|
620
|
-
interface RemoveConfig<TSchema extends
|
|
785
|
+
interface RemoveConfig<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath> {
|
|
621
786
|
/**
|
|
622
787
|
* The path to the field array to remove an item from.
|
|
623
788
|
*/
|
|
@@ -634,13 +799,13 @@ interface RemoveConfig<TSchema extends Schema, TFieldArrayPath extends RequiredP
|
|
|
634
799
|
* @param form The form store containing the field array.
|
|
635
800
|
* @param config The remove configuration specifying the path and index.
|
|
636
801
|
*/
|
|
637
|
-
declare function remove<TSchema extends
|
|
802
|
+
declare function remove<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath>(form: BaseFormStore<TSchema>, config: RemoveConfig<TSchema, TFieldArrayPath>): void;
|
|
638
803
|
//#endregion
|
|
639
804
|
//#region src/replace/replace.d.ts
|
|
640
805
|
/**
|
|
641
806
|
* Replace array field config interface.
|
|
642
807
|
*/
|
|
643
|
-
interface ReplaceConfig<TSchema extends
|
|
808
|
+
interface ReplaceConfig<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath> {
|
|
644
809
|
/**
|
|
645
810
|
* The path to the field array to replace an item within.
|
|
646
811
|
*/
|
|
@@ -660,7 +825,7 @@ interface ReplaceConfig<TSchema extends Schema, TFieldArrayPath extends Required
|
|
|
660
825
|
* @param form The form store containing the field array.
|
|
661
826
|
* @param config The replace configuration specifying the path, index, and initial input.
|
|
662
827
|
*/
|
|
663
|
-
declare function replace<TSchema extends
|
|
828
|
+
declare function replace<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath>(form: BaseFormStore<TSchema>, config: ReplaceConfig<TSchema, TFieldArrayPath>): void;
|
|
664
829
|
//#endregion
|
|
665
830
|
//#region src/reset/reset.d.ts
|
|
666
831
|
/**
|
|
@@ -683,7 +848,7 @@ interface ResetBaseConfig {
|
|
|
683
848
|
/**
|
|
684
849
|
* Reset form config interface.
|
|
685
850
|
*/
|
|
686
|
-
interface ResetFormConfig<TSchema extends
|
|
851
|
+
interface ResetFormConfig<TSchema extends FormSchema> extends ResetBaseConfig {
|
|
687
852
|
/**
|
|
688
853
|
* The path to a field. Leave undefined to reset the entire form.
|
|
689
854
|
*/
|
|
@@ -701,7 +866,7 @@ interface ResetFormConfig<TSchema extends Schema> extends ResetBaseConfig {
|
|
|
701
866
|
/**
|
|
702
867
|
* Reset field config interface.
|
|
703
868
|
*/
|
|
704
|
-
interface ResetFieldConfig<TSchema extends
|
|
869
|
+
interface ResetFieldConfig<TSchema extends FormSchema, TFieldPath extends RequiredPath> extends ResetBaseConfig {
|
|
705
870
|
/**
|
|
706
871
|
* The path to the field to reset.
|
|
707
872
|
*/
|
|
@@ -728,7 +893,7 @@ declare function reset(form: BaseFormStore): void;
|
|
|
728
893
|
* @param form The form store to reset.
|
|
729
894
|
* @param config The reset configuration specifying what to reset and what to keep.
|
|
730
895
|
*/
|
|
731
|
-
declare function reset<TSchema extends
|
|
896
|
+
declare function reset<TSchema extends FormSchema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? ResetFieldConfig<TSchema, TFieldPath> : ResetFormConfig<TSchema>): void;
|
|
732
897
|
//#endregion
|
|
733
898
|
//#region src/setErrors/setErrors.d.ts
|
|
734
899
|
/**
|
|
@@ -747,7 +912,7 @@ interface SetFormErrorsConfig {
|
|
|
747
912
|
/**
|
|
748
913
|
* Set field errors config interface.
|
|
749
914
|
*/
|
|
750
|
-
interface SetFieldErrorsConfig<TSchema extends
|
|
915
|
+
interface SetFieldErrorsConfig<TSchema extends FormSchema, TFieldPath extends RequiredPath> {
|
|
751
916
|
/**
|
|
752
917
|
* The path to the field to set errors on.
|
|
753
918
|
*/
|
|
@@ -765,13 +930,13 @@ interface SetFieldErrorsConfig<TSchema extends Schema, TFieldPath extends Requir
|
|
|
765
930
|
* @param form The form store to set errors on.
|
|
766
931
|
* @param config The set errors configuration specifying the path and error messages.
|
|
767
932
|
*/
|
|
768
|
-
declare function setErrors<TSchema extends
|
|
933
|
+
declare function setErrors<TSchema extends FormSchema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? SetFieldErrorsConfig<TSchema, TFieldPath> : SetFormErrorsConfig): void;
|
|
769
934
|
//#endregion
|
|
770
935
|
//#region src/setInput/setInput.d.ts
|
|
771
936
|
/**
|
|
772
937
|
* Set form input config interface.
|
|
773
938
|
*/
|
|
774
|
-
interface SetFormInputConfig<TSchema extends
|
|
939
|
+
interface SetFormInputConfig<TSchema extends FormSchema> {
|
|
775
940
|
/**
|
|
776
941
|
* The path to a field. Leave undefined to set the entire form input.
|
|
777
942
|
*/
|
|
@@ -784,7 +949,7 @@ interface SetFormInputConfig<TSchema extends Schema> {
|
|
|
784
949
|
/**
|
|
785
950
|
* Set field input config interface.
|
|
786
951
|
*/
|
|
787
|
-
interface SetFieldInputConfig<TSchema extends
|
|
952
|
+
interface SetFieldInputConfig<TSchema extends FormSchema, TFieldPath extends RequiredPath> {
|
|
788
953
|
/**
|
|
789
954
|
* The path to the field to set input on.
|
|
790
955
|
*/
|
|
@@ -802,7 +967,7 @@ interface SetFieldInputConfig<TSchema extends Schema, TFieldPath extends Require
|
|
|
802
967
|
* @param form The form store to set input on.
|
|
803
968
|
* @param config The set form input configuration specifying the new input values.
|
|
804
969
|
*/
|
|
805
|
-
declare function setInput<TSchema extends
|
|
970
|
+
declare function setInput<TSchema extends FormSchema>(form: BaseFormStore<TSchema>, config: SetFormInputConfig<TSchema>): void;
|
|
806
971
|
/**
|
|
807
972
|
* Sets the input value of a specific field or the entire form. This updates
|
|
808
973
|
* the field value(s) and triggers validation if required by the form's
|
|
@@ -811,7 +976,7 @@ declare function setInput<TSchema extends Schema>(form: BaseFormStore<TSchema>,
|
|
|
811
976
|
* @param form The form store to set input on.
|
|
812
977
|
* @param config The set input configuration specifying the path and new value.
|
|
813
978
|
*/
|
|
814
|
-
declare function setInput<TSchema extends
|
|
979
|
+
declare function setInput<TSchema extends FormSchema, TFieldPath extends RequiredPath | undefined = undefined>(form: BaseFormStore<TSchema>, config: TFieldPath extends RequiredPath ? SetFieldInputConfig<TSchema, TFieldPath> : SetFormInputConfig<TSchema>): void;
|
|
815
980
|
//#endregion
|
|
816
981
|
//#region src/submit/submit.d.ts
|
|
817
982
|
/**
|
|
@@ -826,7 +991,7 @@ declare function submit(form: BaseFormStore): void;
|
|
|
826
991
|
/**
|
|
827
992
|
* Swap array field config interface.
|
|
828
993
|
*/
|
|
829
|
-
interface SwapConfig<TSchema extends
|
|
994
|
+
interface SwapConfig<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath> {
|
|
830
995
|
/**
|
|
831
996
|
* The path to the field array to swap items within.
|
|
832
997
|
*/
|
|
@@ -846,7 +1011,7 @@ interface SwapConfig<TSchema extends Schema, TFieldArrayPath extends RequiredPat
|
|
|
846
1011
|
* @param form The form store containing the field array.
|
|
847
1012
|
* @param config The swap configuration specifying the path and indices to swap.
|
|
848
1013
|
*/
|
|
849
|
-
declare function swap<TSchema extends
|
|
1014
|
+
declare function swap<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath>(form: BaseFormStore<TSchema>, config: SwapConfig<TSchema, TFieldArrayPath>): void;
|
|
850
1015
|
//#endregion
|
|
851
1016
|
//#region src/validate/validate.d.ts
|
|
852
1017
|
/**
|
|
@@ -868,7 +1033,7 @@ interface ValidateFormConfig {
|
|
|
868
1033
|
*
|
|
869
1034
|
* @returns A promise resolving to the validation result.
|
|
870
1035
|
*/
|
|
871
|
-
declare function validate<TSchema extends
|
|
1036
|
+
declare function validate<TSchema extends FormSchema>(form: BaseFormStore<TSchema>, config?: ValidateFormConfig): Promise<v.SafeParseResult<TSchema>>;
|
|
872
1037
|
//#endregion
|
|
873
1038
|
//#endregion
|
|
874
1039
|
//#region src/types/field.d.ts
|
|
@@ -908,7 +1073,7 @@ interface FieldElementProps {
|
|
|
908
1073
|
/**
|
|
909
1074
|
* Field store interface.
|
|
910
1075
|
*/
|
|
911
|
-
interface FieldStore<TSchema extends
|
|
1076
|
+
interface FieldStore<TSchema extends FormSchema = FormSchema, TFieldPath extends RequiredPath = RequiredPath> {
|
|
912
1077
|
/**
|
|
913
1078
|
* The path to the field within the form.
|
|
914
1079
|
*/
|
|
@@ -945,7 +1110,7 @@ interface FieldStore<TSchema extends Schema = Schema, TFieldPath extends Require
|
|
|
945
1110
|
/**
|
|
946
1111
|
* Field array store interface.
|
|
947
1112
|
*/
|
|
948
|
-
interface FieldArrayStore<TSchema extends
|
|
1113
|
+
interface FieldArrayStore<TSchema extends FormSchema = FormSchema, TFieldArrayPath extends RequiredPath = RequiredPath> {
|
|
949
1114
|
/**
|
|
950
1115
|
* The path to the array field within the form.
|
|
951
1116
|
*/
|
|
@@ -976,7 +1141,7 @@ interface FieldArrayStore<TSchema extends Schema = Schema, TFieldArrayPath exten
|
|
|
976
1141
|
/**
|
|
977
1142
|
* Form store interface.
|
|
978
1143
|
*/
|
|
979
|
-
interface FormStore<TSchema extends
|
|
1144
|
+
interface FormStore<TSchema extends FormSchema = FormSchema> extends BaseFormStore<TSchema> {
|
|
980
1145
|
/**
|
|
981
1146
|
* Whether the form is currently submitting.
|
|
982
1147
|
*/
|
|
@@ -1014,7 +1179,7 @@ interface FormStore<TSchema extends Schema = Schema> extends BaseFormStore<TSche
|
|
|
1014
1179
|
/**
|
|
1015
1180
|
* Field component props interface.
|
|
1016
1181
|
*/
|
|
1017
|
-
interface FieldProps<TSchema extends
|
|
1182
|
+
interface FieldProps<TSchema extends FormSchema = FormSchema, TFieldPath extends RequiredPath = RequiredPath> {
|
|
1018
1183
|
/**
|
|
1019
1184
|
* The form store to which the field belongs.
|
|
1020
1185
|
*/
|
|
@@ -1035,13 +1200,13 @@ interface FieldProps<TSchema extends Schema = Schema, TFieldPath extends Require
|
|
|
1035
1200
|
*
|
|
1036
1201
|
* @returns The UI of the field to be rendered.
|
|
1037
1202
|
*/
|
|
1038
|
-
declare const Field: <TSchema extends
|
|
1203
|
+
declare const Field: <TSchema extends FormSchema, TFieldPath extends RequiredPath>(props: _qwik_dev_core_internal0.PublicProps<FieldProps<TSchema, TFieldPath>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal0.DevJSX) => JSXOutput;
|
|
1039
1204
|
//#endregion
|
|
1040
1205
|
//#region src/components/FieldArray/FieldArray.d.ts
|
|
1041
1206
|
/**
|
|
1042
1207
|
* FieldArray component props interface.
|
|
1043
1208
|
*/
|
|
1044
|
-
interface FieldArrayProps<TSchema extends
|
|
1209
|
+
interface FieldArrayProps<TSchema extends FormSchema = FormSchema, TFieldArrayPath extends RequiredPath = RequiredPath> {
|
|
1045
1210
|
/**
|
|
1046
1211
|
* The form store to which the field array belongs.
|
|
1047
1212
|
*/
|
|
@@ -1063,13 +1228,13 @@ interface FieldArrayProps<TSchema extends Schema = Schema, TFieldArrayPath exten
|
|
|
1063
1228
|
*
|
|
1064
1229
|
* @returns The UI of the field array to be rendered.
|
|
1065
1230
|
*/
|
|
1066
|
-
declare const FieldArray: <TSchema extends
|
|
1231
|
+
declare const FieldArray: <TSchema extends FormSchema, TFieldArrayPath extends RequiredPath>(props: _qwik_dev_core_internal0.PublicProps<FieldArrayProps<TSchema, TFieldArrayPath>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal0.DevJSX) => JSXOutput;
|
|
1067
1232
|
//#endregion
|
|
1068
1233
|
//#region src/components/Form/Form.d.ts
|
|
1069
1234
|
/**
|
|
1070
1235
|
* Form component props type.
|
|
1071
1236
|
*/
|
|
1072
|
-
type FormProps<TSchema extends
|
|
1237
|
+
type FormProps<TSchema extends FormSchema = FormSchema> = Omit<PropsOf<'form'>, 'onSubmit$' | 'noValidate'> & {
|
|
1073
1238
|
/**
|
|
1074
1239
|
* The form store instance.
|
|
1075
1240
|
*/
|
|
@@ -1085,13 +1250,13 @@ type FormProps<TSchema extends Schema = Schema> = Omit<PropsOf<'form'>, 'onSubmi
|
|
|
1085
1250
|
*
|
|
1086
1251
|
* @returns The a native form element.
|
|
1087
1252
|
*/
|
|
1088
|
-
declare const Form: <TSchema extends
|
|
1253
|
+
declare const Form: <TSchema extends FormSchema>(props: _qwik_dev_core_internal0.PublicProps<FormProps<TSchema>>, key: string | null, flags: number, dev?: _qwik_dev_core_internal0.DevJSX) => JSXOutput;
|
|
1089
1254
|
//#endregion
|
|
1090
1255
|
//#region src/hooks/useField/useField.d.ts
|
|
1091
1256
|
/**
|
|
1092
1257
|
* Use field config interface.
|
|
1093
1258
|
*/
|
|
1094
|
-
interface UseFieldConfig<TSchema extends
|
|
1259
|
+
interface UseFieldConfig<TSchema extends FormSchema = FormSchema, TFieldPath extends RequiredPath = RequiredPath> {
|
|
1095
1260
|
/**
|
|
1096
1261
|
* The path to the field within the form schema.
|
|
1097
1262
|
*/
|
|
@@ -1105,13 +1270,13 @@ interface UseFieldConfig<TSchema extends Schema = Schema, TFieldPath extends Req
|
|
|
1105
1270
|
*
|
|
1106
1271
|
* @returns The field store with reactive properties and element props.
|
|
1107
1272
|
*/
|
|
1108
|
-
declare function useField<TSchema extends
|
|
1273
|
+
declare function useField<TSchema extends FormSchema, TFieldPath extends RequiredPath>(form: FormStore<TSchema>, config: UseFieldConfig<TSchema, TFieldPath>): FieldStore<TSchema, TFieldPath>;
|
|
1109
1274
|
//#endregion
|
|
1110
1275
|
//#region src/hooks/useFieldArray/useFieldArray.d.ts
|
|
1111
1276
|
/**
|
|
1112
1277
|
* Use field array config interface.
|
|
1113
1278
|
*/
|
|
1114
|
-
interface UseFieldArrayConfig<TSchema extends
|
|
1279
|
+
interface UseFieldArrayConfig<TSchema extends FormSchema = FormSchema, TFieldArrayPath extends RequiredPath = RequiredPath> {
|
|
1115
1280
|
/**
|
|
1116
1281
|
* The path to the field array within the form schema.
|
|
1117
1282
|
*/
|
|
@@ -1125,7 +1290,7 @@ interface UseFieldArrayConfig<TSchema extends Schema = Schema, TFieldArrayPath e
|
|
|
1125
1290
|
*
|
|
1126
1291
|
* @returns The field array store with reactive properties for array management.
|
|
1127
1292
|
*/
|
|
1128
|
-
declare function useFieldArray<TSchema extends
|
|
1293
|
+
declare function useFieldArray<TSchema extends FormSchema, TFieldArrayPath extends RequiredPath>(form: FormStore<TSchema>, config: UseFieldArrayConfig<TSchema, TFieldArrayPath>): FieldArrayStore<TSchema, TFieldArrayPath>;
|
|
1129
1294
|
//#endregion
|
|
1130
1295
|
//#region src/hooks/useForm$/useForm$.d.ts
|
|
1131
1296
|
/**
|
|
@@ -1136,7 +1301,7 @@ declare function useFieldArray<TSchema extends Schema, TFieldArrayPath extends R
|
|
|
1136
1301
|
*
|
|
1137
1302
|
* @returns The form store with reactive properties.
|
|
1138
1303
|
*/
|
|
1139
|
-
declare function useFormQrl<TSchema extends
|
|
1304
|
+
declare function useFormQrl<TSchema extends FormSchema>(configQrl: QRL<() => FormConfig<TSchema>>): FormStore<TSchema>;
|
|
1140
1305
|
/**
|
|
1141
1306
|
* Creates a reactive form store from a form configuration. The form store
|
|
1142
1307
|
* manages form state and provides reactive properties.
|
|
@@ -1145,6 +1310,6 @@ declare function useFormQrl<TSchema extends Schema>(configQrl: QRL<() => FormCon
|
|
|
1145
1310
|
*
|
|
1146
1311
|
* @returns The form store with reactive properties.
|
|
1147
1312
|
*/
|
|
1148
|
-
declare const useForm$: <TSchema extends
|
|
1313
|
+
declare const useForm$: <TSchema extends FormSchema>(qrl: () => FormConfig<TSchema>) => FormStore<TSchema>;
|
|
1149
1314
|
//#endregion
|
|
1150
|
-
export { type DeepPartial, Field, FieldArray, FieldArrayProps, FieldArrayStore, type FieldElement, FieldElementProps, FieldProps, FieldStore, FocusFieldConfig, Form, type FormConfig, FormProps, FormStore, GetFieldErrorsConfig, GetFieldInputConfig, GetFormErrorsConfig, GetFormInputConfig, InsertConfig, MoveConfig, type PartialValues, type PathValue, RemoveConfig, ReplaceConfig, type RequiredPath, ResetFieldConfig, ResetFormConfig, type Schema, SetFieldErrorsConfig, SetFieldInputConfig, SetFormErrorsConfig, SetFormInputConfig, type SubmitEventHandler, type SubmitHandler, SwapConfig, UseFieldArrayConfig, UseFieldConfig, type ValidArrayPath, type ValidPath, ValidateFormConfig, type ValidationMode, focus, getAllErrors, getErrors, getInput, handleSubmit, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
|
1315
|
+
export { type DeepPartial, Field, FieldArray, FieldArrayProps, FieldArrayStore, type FieldElement, FieldElementProps, FieldProps, FieldStore, FocusFieldConfig, Form, type FormConfig, FormProps, type FormSchema, FormStore, GetFieldDirtyInputConfig, GetFieldDirtyPathsConfig, GetFieldErrorsConfig, GetFieldInputConfig, GetFormDirtyInputConfig, GetFormDirtyPathsConfig, GetFormErrorsConfig, GetFormInputConfig, InsertConfig, MoveConfig, type PartialValues, type PathValue, PickDirtyConfig, RemoveConfig, ReplaceConfig, type RequiredPath, ResetFieldConfig, ResetFormConfig, type Schema, SetFieldErrorsConfig, SetFieldInputConfig, SetFormErrorsConfig, SetFormInputConfig, type SubmitEventHandler, type SubmitHandler, SwapConfig, UseFieldArrayConfig, UseFieldConfig, type ValidArrayPath, type ValidPath, ValidateFormConfig, type ValidationMode, focus, getAllErrors, getDirtyInput, getDirtyPaths, getErrors, getInput, handleSubmit, insert, move, pickDirty, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
package/dist/index.qwik.js
CHANGED
|
@@ -152,31 +152,45 @@ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
|
|
|
152
152
|
* form reset functionality.
|
|
153
153
|
*
|
|
154
154
|
* @param internalFieldStore The field store to reset.
|
|
155
|
-
* @param
|
|
155
|
+
* @param input The new input value (can be any type including array or object).
|
|
156
|
+
* @param keepStart Whether to keep `startInput` and `startItems` as the dirty
|
|
157
|
+
* baseline instead of resetting them to the new input. Used when a field store
|
|
158
|
+
* is reused for an in-place edit so its dirty state is detected correctly.
|
|
156
159
|
*/
|
|
157
|
-
function resetItemState(internalFieldStore,
|
|
160
|
+
function resetItemState(internalFieldStore, input, keepStart = false) {
|
|
158
161
|
batch(() => {
|
|
159
|
-
|
|
162
|
+
const elements = [];
|
|
163
|
+
if (internalFieldStore.elements === internalFieldStore.initialElements) internalFieldStore.initialElements = elements;
|
|
164
|
+
internalFieldStore.elements = elements;
|
|
160
165
|
internalFieldStore.errors.value = null;
|
|
161
166
|
internalFieldStore.isTouched.value = false;
|
|
162
167
|
internalFieldStore.isDirty.value = false;
|
|
163
168
|
if (internalFieldStore.kind === "array" || internalFieldStore.kind === "object") {
|
|
164
|
-
const objectInput =
|
|
165
|
-
internalFieldStore.startInput.value = objectInput;
|
|
169
|
+
const objectInput = input == null ? input : true;
|
|
170
|
+
if (!keepStart) internalFieldStore.startInput.value = objectInput;
|
|
166
171
|
internalFieldStore.input.value = objectInput;
|
|
167
|
-
if (internalFieldStore.kind === "array") if (
|
|
168
|
-
const
|
|
169
|
-
|
|
172
|
+
if (internalFieldStore.kind === "array") if (input) {
|
|
173
|
+
const length = internalFieldStore.schema.type === "array" ? input.length : internalFieldStore.children.length;
|
|
174
|
+
const newItems = Array.from({ length }, createId);
|
|
175
|
+
if (!keepStart) internalFieldStore.startItems.value = newItems;
|
|
170
176
|
internalFieldStore.items.value = newItems;
|
|
171
|
-
|
|
177
|
+
let path;
|
|
178
|
+
for (let index = 0; index < length; index++) if (internalFieldStore.children[index]) resetItemState(internalFieldStore.children[index], input[index], keepStart);
|
|
179
|
+
else {
|
|
180
|
+
path ??= JSON.parse(internalFieldStore.name);
|
|
181
|
+
internalFieldStore.children[index] = {};
|
|
182
|
+
path.push(index);
|
|
183
|
+
initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, input[index], path);
|
|
184
|
+
path.pop();
|
|
185
|
+
}
|
|
172
186
|
} else {
|
|
173
|
-
internalFieldStore.startItems.value = [];
|
|
187
|
+
if (!keepStart) internalFieldStore.startItems.value = [];
|
|
174
188
|
internalFieldStore.items.value = [];
|
|
175
189
|
}
|
|
176
|
-
else for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key],
|
|
190
|
+
else for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], input?.[key], keepStart);
|
|
177
191
|
} else {
|
|
178
|
-
internalFieldStore.startInput.value =
|
|
179
|
-
internalFieldStore.input.value =
|
|
192
|
+
if (!keepStart) internalFieldStore.startInput.value = input;
|
|
193
|
+
internalFieldStore.input.value = input;
|
|
180
194
|
}
|
|
181
195
|
});
|
|
182
196
|
}
|
|
@@ -243,6 +257,85 @@ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
|
|
|
243
257
|
});
|
|
244
258
|
}
|
|
245
259
|
/**
|
|
260
|
+
* Focuses the first focusable element of a field store. The elements are tried
|
|
261
|
+
* in order and the first one that actually receives focus wins, so detached,
|
|
262
|
+
* disabled or hidden elements are skipped. The browser decides focusability,
|
|
263
|
+
* which is read back via the element's root `activeElement` so elements in a
|
|
264
|
+
* shadow root or another document are handled correctly.
|
|
265
|
+
*
|
|
266
|
+
* Hint: A `display: none` or `hidden` element is correctly skipped in real
|
|
267
|
+
* browsers, but jsdom has no layout and focuses it anyway, so that case cannot
|
|
268
|
+
* be covered by unit tests.
|
|
269
|
+
*
|
|
270
|
+
* @param internalFieldStore The field store to focus.
|
|
271
|
+
*
|
|
272
|
+
* @returns Whether an element was focused.
|
|
273
|
+
*/
|
|
274
|
+
function focusFieldElement(internalFieldStore) {
|
|
275
|
+
for (const element of internalFieldStore.elements) {
|
|
276
|
+
element.focus();
|
|
277
|
+
if (element.getRootNode().activeElement === element) return true;
|
|
278
|
+
}
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Returns whether the specified boolean property is true for the field store
|
|
283
|
+
* or any of its nested children. Recursively checks arrays and objects.
|
|
284
|
+
*
|
|
285
|
+
* @param internalFieldStore The field store to check.
|
|
286
|
+
* @param type The boolean property type to check.
|
|
287
|
+
*
|
|
288
|
+
* @returns Whether the property is true.
|
|
289
|
+
*/
|
|
290
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
291
|
+
function getFieldBool(internalFieldStore, type) {
|
|
292
|
+
if (internalFieldStore[type].value) return true;
|
|
293
|
+
if (internalFieldStore.kind === "array") {
|
|
294
|
+
for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
if (internalFieldStore.kind == "object") {
|
|
298
|
+
for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Returns only the dirty input of the field store. Arrays are treated as
|
|
305
|
+
* atomic and returned in full if any item is dirty, while object keys without
|
|
306
|
+
* a dirty descendant are omitted. Returns `undefined` if no descendant is
|
|
307
|
+
* dirty.
|
|
308
|
+
*
|
|
309
|
+
* @param internalFieldStore The field store to get dirty input from.
|
|
310
|
+
* @param dirtyOnly Whether to only include dirty fields. Defaults to `true`.
|
|
311
|
+
*
|
|
312
|
+
* @returns The dirty input, or `undefined` if no descendant is dirty.
|
|
313
|
+
*/
|
|
314
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
315
|
+
function getDirtyFieldInput(internalFieldStore, dirtyOnly = true) {
|
|
316
|
+
if (dirtyOnly && !/* @__PURE__ */ getFieldBool(internalFieldStore, "isDirty")) return;
|
|
317
|
+
if (internalFieldStore.kind === "array") {
|
|
318
|
+
if (internalFieldStore.input.value) {
|
|
319
|
+
const value = [];
|
|
320
|
+
for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = /* @__PURE__ */ getDirtyFieldInput(internalFieldStore.children[index], false);
|
|
321
|
+
return value;
|
|
322
|
+
}
|
|
323
|
+
return internalFieldStore.input.value;
|
|
324
|
+
}
|
|
325
|
+
if (internalFieldStore.kind === "object") {
|
|
326
|
+
if (internalFieldStore.input.value) {
|
|
327
|
+
const value = {};
|
|
328
|
+
for (const key in internalFieldStore.children) {
|
|
329
|
+
const child = internalFieldStore.children[key];
|
|
330
|
+
if (!dirtyOnly || /* @__PURE__ */ getFieldBool(child, "isDirty")) value[key] = /* @__PURE__ */ getDirtyFieldInput(child, dirtyOnly);
|
|
331
|
+
}
|
|
332
|
+
return value;
|
|
333
|
+
}
|
|
334
|
+
return internalFieldStore.input.value;
|
|
335
|
+
}
|
|
336
|
+
return internalFieldStore.input.value;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
246
339
|
* Returns the current input of the field store. For arrays and objects,
|
|
247
340
|
* recursively collects input from all children. Returns `null` or `undefined`
|
|
248
341
|
* for nullish array/object inputs, or the primitive value for value fields.
|
|
@@ -299,28 +392,6 @@ function getElementInput(element, internalFieldStore) {
|
|
|
299
392
|
return element.value;
|
|
300
393
|
}
|
|
301
394
|
/**
|
|
302
|
-
* Returns whether the specified boolean property is true for the field store
|
|
303
|
-
* or any of its nested children. Recursively checks arrays and objects.
|
|
304
|
-
*
|
|
305
|
-
* @param internalFieldStore The field store to check.
|
|
306
|
-
* @param type The boolean property type to check.
|
|
307
|
-
*
|
|
308
|
-
* @returns Whether the property is true.
|
|
309
|
-
*/
|
|
310
|
-
/* @__NO_SIDE_EFFECTS__ */
|
|
311
|
-
function getFieldBool(internalFieldStore, type) {
|
|
312
|
-
if (internalFieldStore[type].value) return true;
|
|
313
|
-
if (internalFieldStore.kind === "array") {
|
|
314
|
-
for (let index = 0; index < internalFieldStore.items.value.length; index++) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[index], type)) return true;
|
|
315
|
-
return false;
|
|
316
|
-
}
|
|
317
|
-
if (internalFieldStore.kind == "object") {
|
|
318
|
-
for (const key in internalFieldStore.children) if (/* @__PURE__ */ getFieldBool(internalFieldStore.children[key], type)) return true;
|
|
319
|
-
return false;
|
|
320
|
-
}
|
|
321
|
-
return false;
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
395
|
* Returns the field store at the specified path by traversing the form store's
|
|
325
396
|
* children hierarchy.
|
|
326
397
|
*
|
|
@@ -345,11 +416,9 @@ function getFieldStore(internalFormStore, path) {
|
|
|
345
416
|
*/
|
|
346
417
|
function setFieldBool(internalFieldStore, type, bool) {
|
|
347
418
|
batch(() => {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
} else if (internalFieldStore.kind == "object") for (const key in internalFieldStore.children) setFieldBool(internalFieldStore.children[key], type, bool);
|
|
352
|
-
else internalFieldStore[type].value = bool;
|
|
419
|
+
internalFieldStore[type].value = bool;
|
|
420
|
+
if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) setFieldBool(internalFieldStore.children[index], type, bool);
|
|
421
|
+
else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setFieldBool(internalFieldStore.children[key], type, bool);
|
|
353
422
|
});
|
|
354
423
|
}
|
|
355
424
|
/**
|
|
@@ -364,20 +433,20 @@ function setNestedInput(internalFieldStore, input) {
|
|
|
364
433
|
if (internalFieldStore.kind === "array") {
|
|
365
434
|
const arrayInput = input ?? [];
|
|
366
435
|
const items = internalFieldStore.items.value;
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
436
|
+
const length = internalFieldStore.schema.type === "array" ? arrayInput.length : internalFieldStore.children.length;
|
|
437
|
+
if (length < items.length) internalFieldStore.items.value = items.slice(0, length);
|
|
438
|
+
else if (length > items.length) {
|
|
439
|
+
const path = JSON.parse(internalFieldStore.name);
|
|
440
|
+
for (let index = items.length; index < length; index++) if (internalFieldStore.children[index]) resetItemState(internalFieldStore.children[index], arrayInput[index], true);
|
|
441
|
+
else {
|
|
442
|
+
internalFieldStore.children[index] = {};
|
|
443
|
+
path.push(index);
|
|
444
|
+
initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, arrayInput[index], path);
|
|
445
|
+
path.pop();
|
|
377
446
|
}
|
|
378
|
-
internalFieldStore.items.value = [...items, ...
|
|
447
|
+
internalFieldStore.items.value = [...items, ...Array.from({ length: length - items.length }, createId)];
|
|
379
448
|
}
|
|
380
|
-
for (let index = 0; index <
|
|
449
|
+
for (let index = 0; index < length; index++) setNestedInput(internalFieldStore.children[index], arrayInput[index]);
|
|
381
450
|
internalFieldStore.input.value = input == null ? input : true;
|
|
382
451
|
internalFieldStore.isDirty.value = internalFieldStore.startInput.value !== internalFieldStore.input.value || internalFieldStore.startItems.value.length !== internalFieldStore.items.value.length;
|
|
383
452
|
} else if (internalFieldStore.kind === "object") {
|
|
@@ -421,21 +490,22 @@ function setFieldInput(internalFormStore, path, input) {
|
|
|
421
490
|
function setInitialFieldInput(internalFieldStore, initialInput) {
|
|
422
491
|
batch(() => {
|
|
423
492
|
if (internalFieldStore.kind === "array") {
|
|
424
|
-
internalFieldStore.
|
|
493
|
+
internalFieldStore.initialInput.value = initialInput == null ? initialInput : true;
|
|
425
494
|
const initialArrayInput = initialInput ?? [];
|
|
426
|
-
|
|
495
|
+
const length = internalFieldStore.schema.type === "array" ? initialArrayInput.length : internalFieldStore.children.length;
|
|
496
|
+
if (length > internalFieldStore.children.length) {
|
|
427
497
|
const path = JSON.parse(internalFieldStore.name);
|
|
428
|
-
for (let index = internalFieldStore.children.length; index <
|
|
498
|
+
for (let index = internalFieldStore.children.length; index < length; index++) {
|
|
429
499
|
internalFieldStore.children[index] = {};
|
|
430
500
|
path.push(index);
|
|
431
501
|
initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, initialArrayInput[index], path);
|
|
432
502
|
path.pop();
|
|
433
503
|
}
|
|
434
504
|
}
|
|
435
|
-
internalFieldStore.initialItems.value =
|
|
505
|
+
internalFieldStore.initialItems.value = Array.from({ length }, createId);
|
|
436
506
|
for (let index = 0; index < internalFieldStore.children.length; index++) setInitialFieldInput(internalFieldStore.children[index], initialArrayInput[index]);
|
|
437
507
|
} else if (internalFieldStore.kind === "object") {
|
|
438
|
-
internalFieldStore.
|
|
508
|
+
internalFieldStore.initialInput.value = initialInput == null ? initialInput : true;
|
|
439
509
|
for (const key in internalFieldStore.children) setInitialFieldInput(internalFieldStore.children[key], initialInput?.[key]);
|
|
440
510
|
} else internalFieldStore.initialInput.value = initialInput;
|
|
441
511
|
});
|
|
@@ -487,44 +557,49 @@ function createFormStore(config, parse) {
|
|
|
487
557
|
async function validateFormInput(internalFormStore, config) {
|
|
488
558
|
internalFormStore.validators++;
|
|
489
559
|
internalFormStore.isValidating.value = true;
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
const path
|
|
497
|
-
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
const name = JSON.stringify(path);
|
|
505
|
-
const fieldErrors = nestedErrors[name];
|
|
506
|
-
if (fieldErrors) fieldErrors.push(issue.message);
|
|
507
|
-
else nestedErrors[name] = [issue.message];
|
|
508
|
-
} else if (rootErrors) rootErrors.push(issue.message);
|
|
509
|
-
else rootErrors = [issue.message];
|
|
510
|
-
}
|
|
511
|
-
let shouldFocus = config?.shouldFocus ?? false;
|
|
512
|
-
batch(() => {
|
|
513
|
-
walkFieldStore(internalFormStore, (internalFieldStore) => {
|
|
514
|
-
if (internalFieldStore.name === "[]") internalFieldStore.errors.value = rootErrors ?? null;
|
|
515
|
-
else {
|
|
516
|
-
const fieldErrors = nestedErrors?.[internalFieldStore.name] ?? null;
|
|
517
|
-
internalFieldStore.errors.value = fieldErrors;
|
|
518
|
-
if (shouldFocus && fieldErrors) {
|
|
519
|
-
internalFieldStore.elements[0]?.focus();
|
|
520
|
-
shouldFocus = false;
|
|
560
|
+
try {
|
|
561
|
+
const result = await internalFormStore.parse(untrack(() => /* @__PURE__ */ getFieldInput(internalFormStore)));
|
|
562
|
+
let rootErrors;
|
|
563
|
+
let nestedErrors;
|
|
564
|
+
if (result.issues) {
|
|
565
|
+
nestedErrors = {};
|
|
566
|
+
for (const issue of result.issues) if (issue.path) {
|
|
567
|
+
const path = [];
|
|
568
|
+
for (const pathItem of issue.path) {
|
|
569
|
+
const key = pathItem.key;
|
|
570
|
+
const keyType = typeof key;
|
|
571
|
+
const itemType = pathItem.type;
|
|
572
|
+
if (keyType !== "string" && keyType !== "number" || itemType === "map" || itemType === "set") break;
|
|
573
|
+
path.push(key);
|
|
521
574
|
}
|
|
522
|
-
|
|
575
|
+
const name = JSON.stringify(path);
|
|
576
|
+
const fieldErrors = nestedErrors[name];
|
|
577
|
+
if (fieldErrors) fieldErrors.push(issue.message);
|
|
578
|
+
else nestedErrors[name] = [issue.message];
|
|
579
|
+
} else if (rootErrors) rootErrors.push(issue.message);
|
|
580
|
+
else rootErrors = [issue.message];
|
|
581
|
+
}
|
|
582
|
+
let shouldFocus = config?.shouldFocus ?? false;
|
|
583
|
+
batch(() => {
|
|
584
|
+
walkFieldStore(internalFormStore, (internalFieldStore) => {
|
|
585
|
+
if (internalFieldStore.name === "[]") internalFieldStore.errors.value = rootErrors ?? null;
|
|
586
|
+
else {
|
|
587
|
+
const fieldErrors = nestedErrors?.[internalFieldStore.name] ?? null;
|
|
588
|
+
internalFieldStore.errors.value = fieldErrors;
|
|
589
|
+
if (shouldFocus && fieldErrors && focusFieldElement(internalFieldStore)) shouldFocus = false;
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
internalFormStore.validators--;
|
|
593
|
+
internalFormStore.isValidating.value = internalFormStore.validators > 0;
|
|
523
594
|
});
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
595
|
+
return result;
|
|
596
|
+
} catch (error) {
|
|
597
|
+
batch(() => {
|
|
598
|
+
internalFormStore.validators--;
|
|
599
|
+
internalFormStore.isValidating.value = internalFormStore.validators > 0;
|
|
600
|
+
});
|
|
601
|
+
throw error;
|
|
602
|
+
}
|
|
528
603
|
}
|
|
529
604
|
/**
|
|
530
605
|
* Validates the form input if required based on the validation mode and form
|
|
@@ -546,7 +621,7 @@ const INTERNAL = "~internal";
|
|
|
546
621
|
//#endregion
|
|
547
622
|
//#region ../../packages/methods/dist/index.qwik.js
|
|
548
623
|
/**
|
|
549
|
-
* Focuses the first input element of a field. This is useful for
|
|
624
|
+
* Focuses the first focusable input element of a field. This is useful for
|
|
550
625
|
* programmatically setting focus to a specific field, such as after
|
|
551
626
|
* validation errors or user interactions.
|
|
552
627
|
*
|
|
@@ -554,7 +629,7 @@ const INTERNAL = "~internal";
|
|
|
554
629
|
* @param config The focus field configuration.
|
|
555
630
|
*/
|
|
556
631
|
function focus(form, config) {
|
|
557
|
-
getFieldStore(form[INTERNAL], config.path)
|
|
632
|
+
focusFieldElement(getFieldStore(form[INTERNAL], config.path));
|
|
558
633
|
}
|
|
559
634
|
/**
|
|
560
635
|
* Retrieves all error messages from all fields in the form by walking through
|
|
@@ -577,6 +652,17 @@ function getAllErrors(form) {
|
|
|
577
652
|
return allErrors;
|
|
578
653
|
}
|
|
579
654
|
/* @__NO_SIDE_EFFECTS__ */
|
|
655
|
+
function getDirtyInput(form, config) {
|
|
656
|
+
return getDirtyFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
|
|
657
|
+
}
|
|
658
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
659
|
+
function getDirtyPaths(form, config) {
|
|
660
|
+
config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL];
|
|
661
|
+
const paths = [];
|
|
662
|
+
config?.path && [...config.path];
|
|
663
|
+
return paths;
|
|
664
|
+
}
|
|
665
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
580
666
|
function getErrors(form, config) {
|
|
581
667
|
return (config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]).errors.value;
|
|
582
668
|
}
|
|
@@ -670,6 +756,48 @@ function move(form, config) {
|
|
|
670
756
|
});
|
|
671
757
|
}
|
|
672
758
|
/**
|
|
759
|
+
* Picks only the dirty parts of the given value, using the form's dirty fields
|
|
760
|
+
* as a structural mask. Arrays are treated as atomic and object keys without a
|
|
761
|
+
* dirty descendant are omitted. Returns `undefined` if no field is dirty.
|
|
762
|
+
* Useful for filtering a validated output down to its changed parts before
|
|
763
|
+
* submitting.
|
|
764
|
+
*
|
|
765
|
+
* @param form The form store providing the dirty mask.
|
|
766
|
+
* @param config The pick dirty configuration.
|
|
767
|
+
*
|
|
768
|
+
* @returns The dirty parts of the value, or `undefined`.
|
|
769
|
+
*/
|
|
770
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
771
|
+
function pickDirty(form, config) {
|
|
772
|
+
if (!getFieldBool(form[INTERNAL], "isDirty")) return;
|
|
773
|
+
const result = /* @__PURE__ */ pickFieldValue(form[INTERNAL], config.from);
|
|
774
|
+
return Object.keys(result).length ? result : void 0;
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Recursively picks the dirty parts of a value using the field store as a
|
|
778
|
+
* structural mask, reading from the supplied value rather than the form's own
|
|
779
|
+
* input. Objects with non-nullish input recurse into their dirty children that
|
|
780
|
+
* are present in the value, while arrays, primitives, nullish-cleared fields
|
|
781
|
+
* and shape-diverging values are returned as-is.
|
|
782
|
+
*
|
|
783
|
+
* @param internalFieldStore The field store used as the dirty mask.
|
|
784
|
+
* @param value The value to pick the dirty parts from.
|
|
785
|
+
*
|
|
786
|
+
* @returns The dirty parts of the value.
|
|
787
|
+
*/
|
|
788
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
789
|
+
function pickFieldValue(internalFieldStore, value) {
|
|
790
|
+
if (internalFieldStore.kind === "object" && internalFieldStore.input.value && value && typeof value === "object" && !Array.isArray(value)) {
|
|
791
|
+
const result = {};
|
|
792
|
+
for (const key in internalFieldStore.children) {
|
|
793
|
+
const child = internalFieldStore.children[key];
|
|
794
|
+
if (getFieldBool(child, "isDirty") && key in value) result[key] = /* @__PURE__ */ pickFieldValue(child, value[key]);
|
|
795
|
+
}
|
|
796
|
+
return result;
|
|
797
|
+
}
|
|
798
|
+
return value;
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
673
801
|
* Removes an item from a field array at the specified index. All items after
|
|
674
802
|
* the removed item are shifted down by one index.
|
|
675
803
|
*
|
|
@@ -829,7 +957,10 @@ function useField(form, config) {
|
|
|
829
957
|
useTask$(({ track, cleanup }) => {
|
|
830
958
|
track(internalFieldStore);
|
|
831
959
|
cleanup(() => {
|
|
832
|
-
|
|
960
|
+
const internalFieldStoreValue = internalFieldStore.value;
|
|
961
|
+
const elements = internalFieldStoreValue.elements.filter((element) => element.isConnected);
|
|
962
|
+
if (internalFieldStoreValue.elements === internalFieldStoreValue.initialElements) internalFieldStoreValue.initialElements = elements;
|
|
963
|
+
internalFieldStoreValue.elements = elements;
|
|
833
964
|
});
|
|
834
965
|
});
|
|
835
966
|
return useConstant(() => ({
|
|
@@ -996,4 +1127,4 @@ const Form = component$(({ of, onSubmit$,...other }) => {
|
|
|
996
1127
|
});
|
|
997
1128
|
|
|
998
1129
|
//#endregion
|
|
999
|
-
export { Field, FieldArray, Form, focus, getAllErrors, getErrors, getInput, handleSubmit, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
|
1130
|
+
export { Field, FieldArray, Form, focus, getAllErrors, getDirtyInput, getDirtyPaths, getErrors, getInput, handleSubmit, insert, move, pickDirty, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formisch/qwik",
|
|
3
3
|
"description": "The lightweight, schema-first, and fully type-safe form library for Qwik",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.12.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Fabian Hiller",
|
|
7
7
|
"homepage": "https://formisch.dev",
|
|
@@ -55,14 +55,14 @@
|
|
|
55
55
|
"prettier": "3.6.2",
|
|
56
56
|
"tsdown": "0.12.9",
|
|
57
57
|
"typescript": "5.8.3",
|
|
58
|
-
"valibot": "^1.
|
|
58
|
+
"valibot": "^1.4.1",
|
|
59
59
|
"vite": "7.0.4",
|
|
60
60
|
"vite-tsconfig-paths": "^5.1.4"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"@qwik.dev/core": ">=2",
|
|
64
64
|
"typescript": ">=5",
|
|
65
|
-
"valibot": "^1.
|
|
65
|
+
"valibot": "^1.4.1"
|
|
66
66
|
},
|
|
67
67
|
"peerDependenciesMeta": {
|
|
68
68
|
"typescript": {
|