@juantroconisf/lib 8.0.0 → 9.0.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.mts +46 -33
- package/dist/index.d.ts +46 -33
- package/dist/index.js +120 -55
- package/dist/index.mjs +120 -55
- package/package.json +45 -45
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SelectProps, AutocompleteProps } from '@heroui/react';
|
|
1
|
+
import { SelectProps, AutocompleteProps, FormProps } from '@heroui/react';
|
|
2
2
|
import { SingleSelection } from '@react-types/shared';
|
|
3
3
|
import { Schema, InferType } from 'yup';
|
|
4
4
|
|
|
@@ -37,7 +37,22 @@ interface FormOptions<O extends StateType> {
|
|
|
37
37
|
* Custom property names used as unique identifiers for items in specific arrays.
|
|
38
38
|
* Default is "id".
|
|
39
39
|
*/
|
|
40
|
-
arrayIdentifiers?:
|
|
40
|
+
arrayIdentifiers?: {
|
|
41
|
+
[K in ArrayPaths<O>]?: NestedFieldValue<O, K> extends (infer E)[] ? E extends object ? ScalarKeys<E> : never : never;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Optional submit handler that is called when the form is submitted and validation passes.
|
|
45
|
+
*/
|
|
46
|
+
onFormSubmit?: FormSubmitHandler<O>;
|
|
47
|
+
/**
|
|
48
|
+
* Whether to automatically reset the form after a successful submission.
|
|
49
|
+
* @default false
|
|
50
|
+
*/
|
|
51
|
+
resetOnSubmit?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Keys to preserve when resetting the form.
|
|
54
|
+
*/
|
|
55
|
+
keepValues?: (keyof O)[];
|
|
41
56
|
}
|
|
42
57
|
type FieldMetadata = {
|
|
43
58
|
isTouched: boolean;
|
|
@@ -45,10 +60,9 @@ type FieldMetadata = {
|
|
|
45
60
|
errorMessage: string;
|
|
46
61
|
};
|
|
47
62
|
type MetadataType = Map<string, FieldMetadata>;
|
|
48
|
-
type
|
|
49
|
-
interface
|
|
50
|
-
|
|
51
|
-
preserveTouched?: boolean;
|
|
63
|
+
type FormSubmitHandler<O extends StateType> = (data: O, e: React.FormEvent) => void;
|
|
64
|
+
interface FormResetOptions<O> {
|
|
65
|
+
keepValues?: (keyof O)[];
|
|
52
66
|
}
|
|
53
67
|
type ValueChangeFunc<O extends StateType, K extends keyof O> = (id: K, value: O[K]) => void;
|
|
54
68
|
type BlurFunc<O extends StateType> = (id: keyof O) => void;
|
|
@@ -81,28 +95,25 @@ interface OnMethods<O extends StateType> {
|
|
|
81
95
|
input<P extends AllPaths<O>>(id: P): ItemInputProps<NestedFieldValue<O, P & string>>;
|
|
82
96
|
/** Registers an array element — adapts to primitive arrays (by index) or object arrays (by ID + field). */
|
|
83
97
|
/** Registers an array element — adapts to primitive arrays (by index). */
|
|
84
|
-
input<K extends
|
|
98
|
+
input<K extends ArrayPaths<O>>(arrayKey: K, index: number): ItemInputProps<any>;
|
|
85
99
|
/** Registers an object array element's field using composite syntax "array.field". */
|
|
86
|
-
input<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId:
|
|
100
|
+
input<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId: string | number): ItemInputProps<any>;
|
|
87
101
|
/** Registers a scalar or nested object field. */
|
|
88
102
|
select<P extends AllPaths<O>>(id: P): ItemSelectProps;
|
|
89
103
|
/** Registers a complete array field for multi-selection. */
|
|
90
|
-
select<K extends
|
|
104
|
+
select<K extends ArrayPaths<O>>(arrayKey: K): ItemSelectProps;
|
|
91
105
|
/** Registers an array element — adapts to primitive arrays (by index) or object arrays (by ID + field). */
|
|
92
|
-
select<K extends
|
|
106
|
+
select<K extends ArrayPaths<O>>(arrayKey: K, index: number): ItemSelectProps;
|
|
93
107
|
/** Registers an object array element's field using composite syntax "array.field". */
|
|
94
|
-
select<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId:
|
|
108
|
+
select<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId: string | number): ItemSelectProps;
|
|
95
109
|
/** Registers a scalar or nested object field. */
|
|
96
110
|
autocomplete<P extends AllPaths<O>>(id: P): ItemAutocompleteProps;
|
|
97
111
|
/** Registers an array element — adapts to primitive arrays (by index) or object arrays (by ID + field). */
|
|
98
112
|
/** Registers an array element — adapts to primitive arrays (by index). */
|
|
99
|
-
autocomplete<K extends
|
|
113
|
+
autocomplete<K extends ArrayPaths<O>>(arrayKey: K, index: number): ItemAutocompleteProps;
|
|
100
114
|
/** Registers an object array element's field using composite syntax "array.field". */
|
|
101
|
-
autocomplete<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId:
|
|
115
|
+
autocomplete<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId: string | number): ItemAutocompleteProps;
|
|
102
116
|
}
|
|
103
|
-
type ArrayKeys<O extends StateType> = {
|
|
104
|
-
[K in keyof O]: O[K] extends any[] ? K : never;
|
|
105
|
-
}[keyof O];
|
|
106
117
|
/**
|
|
107
118
|
* Recursive type to find all paths to arrays in the state.
|
|
108
119
|
*/
|
|
@@ -120,14 +131,10 @@ type ObjectArrayKeys<O extends StateType> = {
|
|
|
120
131
|
type ObjectArrayFieldPaths<O extends StateType> = {
|
|
121
132
|
[K in keyof O]: O[K] extends Record<string, any>[] ? `${K & string}.${FieldPaths<ArrayElement<O[K]>>}` : never;
|
|
122
133
|
}[keyof O];
|
|
123
|
-
/**
|
|
124
|
-
* Helper to extract the array key from a path string like "arrayKey.field".
|
|
125
|
-
*/
|
|
126
|
-
type GetArrayKeyFromPath<O extends StateType, P extends string> = P extends `${infer K}.${string}` ? K extends keyof O ? O[K] extends any[] ? K : never : never : never;
|
|
127
134
|
type ArrayElement<T> = T extends (infer E)[] ? E : never;
|
|
128
135
|
/** Resolves the type of the identifier field for an array element (defaults to "id"). */
|
|
129
136
|
type ItemIdType<O extends StateType, K extends keyof O> = "id" extends keyof ArrayElement<O[K]> ? ArrayElement<O[K]>["id"] : string | number;
|
|
130
|
-
type NestedFieldValue<T, F extends string> = F extends `${infer First}.${infer Rest}` ? First extends keyof T ? NestedFieldValue<T[First]
|
|
137
|
+
type NestedFieldValue<T, F extends string> = F extends `${infer First}.${infer Rest}` ? First extends keyof T ? NestedFieldValue<NonNullable<T[First]>, Rest> : NonNullable<T> extends (infer U)[] ? NestedFieldValue<U, F> : any : F extends keyof T ? NonNullable<T[F]> : NonNullable<T> extends (infer U)[] ? F extends keyof U ? NonNullable<U[F]> : any : any;
|
|
131
138
|
type FieldPaths<T> = T extends Record<string, any> ? {
|
|
132
139
|
[K in keyof T & string]: T[K] extends any[] ? K : T[K] extends Record<string, any> ? `${K}.${FieldPaths<T[K]>}` : K;
|
|
133
140
|
}[keyof T & string] : never;
|
|
@@ -144,19 +151,19 @@ type AllPaths<O extends StateType> = ScalarKeys<O> | NestedObjectPaths<O>;
|
|
|
144
151
|
*/
|
|
145
152
|
interface HelpersFunc<O extends StateType> {
|
|
146
153
|
/** Adds a new item to an array. */
|
|
147
|
-
addItem: <K extends
|
|
154
|
+
addItem: <K extends ArrayPaths<O>>(arrayKey: K, item: NestedFieldValue<O, K> extends (infer E)[] ? E : never, index?: number) => void;
|
|
148
155
|
/** Removes an item from an array by its index. */
|
|
149
|
-
removeItem: <K extends
|
|
156
|
+
removeItem: <K extends ArrayPaths<O>>(arrayKey: K, index: number) => void;
|
|
150
157
|
/** Removes an item from an array by its unique identifier. */
|
|
151
|
-
removeById: <K extends
|
|
158
|
+
removeById: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => void;
|
|
152
159
|
/** Replaces an item in an array at the given index. */
|
|
153
|
-
updateItem: <K extends
|
|
160
|
+
updateItem: <K extends ArrayPaths<O>>(arrayKey: K, index: number, value: NestedFieldValue<O, K> extends (infer E)[] ? E : never) => void;
|
|
154
161
|
/** Moves an item within an array using indices. */
|
|
155
|
-
moveItem: <K extends
|
|
162
|
+
moveItem: <K extends ArrayPaths<O>>(arrayKey: K, from: number, to: number) => void;
|
|
156
163
|
/** Moves an item within an array using unique identifiers. */
|
|
157
|
-
moveById: <K extends
|
|
164
|
+
moveById: <K extends ArrayPaths<O>>(arrayKey: K, fromId: string | number, toId: string | number) => void;
|
|
158
165
|
/** Gets an item from an array by its unique identifier (O(1) via indexMap). */
|
|
159
|
-
getItem: <K extends
|
|
166
|
+
getItem: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => (NestedFieldValue<O, K> extends (infer E)[] ? E : never) | undefined;
|
|
160
167
|
}
|
|
161
168
|
/**
|
|
162
169
|
* The response object from the useForm hook.
|
|
@@ -179,17 +186,23 @@ interface UseFormResponse<O extends StateType> {
|
|
|
179
186
|
isDirty: boolean;
|
|
180
187
|
/**
|
|
181
188
|
* Resets the form state and metadata.
|
|
182
|
-
* @param options Configuration for the reset (
|
|
189
|
+
* @param options Configuration for the reset (e.g., keys to keep).
|
|
183
190
|
*/
|
|
184
|
-
|
|
191
|
+
onFormReset: (options?: FormResetOptions<O>) => void;
|
|
185
192
|
/**
|
|
186
193
|
* Wraps a form submission handler to automatically validate the form.
|
|
187
194
|
* If validation fails, identifying errors and touching fields.
|
|
188
195
|
* If validation succeeds, calls the provided handler with the current state.
|
|
189
196
|
*/
|
|
190
|
-
|
|
197
|
+
onFormSubmit: (fn: FormSubmitHandler<O>) => (e: React.FormEvent) => void;
|
|
198
|
+
/**
|
|
199
|
+
* A controlled form component that handles submission and validation.
|
|
200
|
+
*/
|
|
201
|
+
ControlledForm: React.ComponentType<Omit<FormProps, "onSubmit"> & {
|
|
202
|
+
onSubmit?: (data: O, e: React.FormEvent<HTMLFormElement>) => void;
|
|
203
|
+
}>;
|
|
191
204
|
}
|
|
192
205
|
|
|
193
|
-
declare function useForm<S extends Record<string, ConfigType>>(schema: S, { arrayIdentifiers }?: FormOptions<InferState<S>>): UseFormResponse<InferState<S>>;
|
|
206
|
+
declare function useForm<S extends Record<string, ConfigType>>(schema: S, { arrayIdentifiers, onFormSubmit: onFormSubmitProp, resetOnSubmit, keepValues: keepValuesProp, }?: FormOptions<InferState<S>>): UseFormResponse<InferState<S>>;
|
|
194
207
|
|
|
195
|
-
export { type BlurFunc, type ConfigType, type FieldMetadata, type FormOptions, type HelpersFunc, type InferState, type MetadataType, type NestedChangeProps, NextUIError, type OnMethods, type StateType, type
|
|
208
|
+
export { type BlurFunc, type ConfigType, type FieldMetadata, type FormOptions, type FormSubmitHandler, type HelpersFunc, type InferState, type MetadataType, type NestedChangeProps, NextUIError, type OnMethods, type StateType, type UseFormResponse, type ValueChangeFunc, useForm };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SelectProps, AutocompleteProps } from '@heroui/react';
|
|
1
|
+
import { SelectProps, AutocompleteProps, FormProps } from '@heroui/react';
|
|
2
2
|
import { SingleSelection } from '@react-types/shared';
|
|
3
3
|
import { Schema, InferType } from 'yup';
|
|
4
4
|
|
|
@@ -37,7 +37,22 @@ interface FormOptions<O extends StateType> {
|
|
|
37
37
|
* Custom property names used as unique identifiers for items in specific arrays.
|
|
38
38
|
* Default is "id".
|
|
39
39
|
*/
|
|
40
|
-
arrayIdentifiers?:
|
|
40
|
+
arrayIdentifiers?: {
|
|
41
|
+
[K in ArrayPaths<O>]?: NestedFieldValue<O, K> extends (infer E)[] ? E extends object ? ScalarKeys<E> : never : never;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Optional submit handler that is called when the form is submitted and validation passes.
|
|
45
|
+
*/
|
|
46
|
+
onFormSubmit?: FormSubmitHandler<O>;
|
|
47
|
+
/**
|
|
48
|
+
* Whether to automatically reset the form after a successful submission.
|
|
49
|
+
* @default false
|
|
50
|
+
*/
|
|
51
|
+
resetOnSubmit?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Keys to preserve when resetting the form.
|
|
54
|
+
*/
|
|
55
|
+
keepValues?: (keyof O)[];
|
|
41
56
|
}
|
|
42
57
|
type FieldMetadata = {
|
|
43
58
|
isTouched: boolean;
|
|
@@ -45,10 +60,9 @@ type FieldMetadata = {
|
|
|
45
60
|
errorMessage: string;
|
|
46
61
|
};
|
|
47
62
|
type MetadataType = Map<string, FieldMetadata>;
|
|
48
|
-
type
|
|
49
|
-
interface
|
|
50
|
-
|
|
51
|
-
preserveTouched?: boolean;
|
|
63
|
+
type FormSubmitHandler<O extends StateType> = (data: O, e: React.FormEvent) => void;
|
|
64
|
+
interface FormResetOptions<O> {
|
|
65
|
+
keepValues?: (keyof O)[];
|
|
52
66
|
}
|
|
53
67
|
type ValueChangeFunc<O extends StateType, K extends keyof O> = (id: K, value: O[K]) => void;
|
|
54
68
|
type BlurFunc<O extends StateType> = (id: keyof O) => void;
|
|
@@ -81,28 +95,25 @@ interface OnMethods<O extends StateType> {
|
|
|
81
95
|
input<P extends AllPaths<O>>(id: P): ItemInputProps<NestedFieldValue<O, P & string>>;
|
|
82
96
|
/** Registers an array element — adapts to primitive arrays (by index) or object arrays (by ID + field). */
|
|
83
97
|
/** Registers an array element — adapts to primitive arrays (by index). */
|
|
84
|
-
input<K extends
|
|
98
|
+
input<K extends ArrayPaths<O>>(arrayKey: K, index: number): ItemInputProps<any>;
|
|
85
99
|
/** Registers an object array element's field using composite syntax "array.field". */
|
|
86
|
-
input<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId:
|
|
100
|
+
input<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId: string | number): ItemInputProps<any>;
|
|
87
101
|
/** Registers a scalar or nested object field. */
|
|
88
102
|
select<P extends AllPaths<O>>(id: P): ItemSelectProps;
|
|
89
103
|
/** Registers a complete array field for multi-selection. */
|
|
90
|
-
select<K extends
|
|
104
|
+
select<K extends ArrayPaths<O>>(arrayKey: K): ItemSelectProps;
|
|
91
105
|
/** Registers an array element — adapts to primitive arrays (by index) or object arrays (by ID + field). */
|
|
92
|
-
select<K extends
|
|
106
|
+
select<K extends ArrayPaths<O>>(arrayKey: K, index: number): ItemSelectProps;
|
|
93
107
|
/** Registers an object array element's field using composite syntax "array.field". */
|
|
94
|
-
select<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId:
|
|
108
|
+
select<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId: string | number): ItemSelectProps;
|
|
95
109
|
/** Registers a scalar or nested object field. */
|
|
96
110
|
autocomplete<P extends AllPaths<O>>(id: P): ItemAutocompleteProps;
|
|
97
111
|
/** Registers an array element — adapts to primitive arrays (by index) or object arrays (by ID + field). */
|
|
98
112
|
/** Registers an array element — adapts to primitive arrays (by index). */
|
|
99
|
-
autocomplete<K extends
|
|
113
|
+
autocomplete<K extends ArrayPaths<O>>(arrayKey: K, index: number): ItemAutocompleteProps;
|
|
100
114
|
/** Registers an object array element's field using composite syntax "array.field". */
|
|
101
|
-
autocomplete<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId:
|
|
115
|
+
autocomplete<P extends ObjectArrayFieldPaths<O>>(compositePath: P, itemId: string | number): ItemAutocompleteProps;
|
|
102
116
|
}
|
|
103
|
-
type ArrayKeys<O extends StateType> = {
|
|
104
|
-
[K in keyof O]: O[K] extends any[] ? K : never;
|
|
105
|
-
}[keyof O];
|
|
106
117
|
/**
|
|
107
118
|
* Recursive type to find all paths to arrays in the state.
|
|
108
119
|
*/
|
|
@@ -120,14 +131,10 @@ type ObjectArrayKeys<O extends StateType> = {
|
|
|
120
131
|
type ObjectArrayFieldPaths<O extends StateType> = {
|
|
121
132
|
[K in keyof O]: O[K] extends Record<string, any>[] ? `${K & string}.${FieldPaths<ArrayElement<O[K]>>}` : never;
|
|
122
133
|
}[keyof O];
|
|
123
|
-
/**
|
|
124
|
-
* Helper to extract the array key from a path string like "arrayKey.field".
|
|
125
|
-
*/
|
|
126
|
-
type GetArrayKeyFromPath<O extends StateType, P extends string> = P extends `${infer K}.${string}` ? K extends keyof O ? O[K] extends any[] ? K : never : never : never;
|
|
127
134
|
type ArrayElement<T> = T extends (infer E)[] ? E : never;
|
|
128
135
|
/** Resolves the type of the identifier field for an array element (defaults to "id"). */
|
|
129
136
|
type ItemIdType<O extends StateType, K extends keyof O> = "id" extends keyof ArrayElement<O[K]> ? ArrayElement<O[K]>["id"] : string | number;
|
|
130
|
-
type NestedFieldValue<T, F extends string> = F extends `${infer First}.${infer Rest}` ? First extends keyof T ? NestedFieldValue<T[First]
|
|
137
|
+
type NestedFieldValue<T, F extends string> = F extends `${infer First}.${infer Rest}` ? First extends keyof T ? NestedFieldValue<NonNullable<T[First]>, Rest> : NonNullable<T> extends (infer U)[] ? NestedFieldValue<U, F> : any : F extends keyof T ? NonNullable<T[F]> : NonNullable<T> extends (infer U)[] ? F extends keyof U ? NonNullable<U[F]> : any : any;
|
|
131
138
|
type FieldPaths<T> = T extends Record<string, any> ? {
|
|
132
139
|
[K in keyof T & string]: T[K] extends any[] ? K : T[K] extends Record<string, any> ? `${K}.${FieldPaths<T[K]>}` : K;
|
|
133
140
|
}[keyof T & string] : never;
|
|
@@ -144,19 +151,19 @@ type AllPaths<O extends StateType> = ScalarKeys<O> | NestedObjectPaths<O>;
|
|
|
144
151
|
*/
|
|
145
152
|
interface HelpersFunc<O extends StateType> {
|
|
146
153
|
/** Adds a new item to an array. */
|
|
147
|
-
addItem: <K extends
|
|
154
|
+
addItem: <K extends ArrayPaths<O>>(arrayKey: K, item: NestedFieldValue<O, K> extends (infer E)[] ? E : never, index?: number) => void;
|
|
148
155
|
/** Removes an item from an array by its index. */
|
|
149
|
-
removeItem: <K extends
|
|
156
|
+
removeItem: <K extends ArrayPaths<O>>(arrayKey: K, index: number) => void;
|
|
150
157
|
/** Removes an item from an array by its unique identifier. */
|
|
151
|
-
removeById: <K extends
|
|
158
|
+
removeById: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => void;
|
|
152
159
|
/** Replaces an item in an array at the given index. */
|
|
153
|
-
updateItem: <K extends
|
|
160
|
+
updateItem: <K extends ArrayPaths<O>>(arrayKey: K, index: number, value: NestedFieldValue<O, K> extends (infer E)[] ? E : never) => void;
|
|
154
161
|
/** Moves an item within an array using indices. */
|
|
155
|
-
moveItem: <K extends
|
|
162
|
+
moveItem: <K extends ArrayPaths<O>>(arrayKey: K, from: number, to: number) => void;
|
|
156
163
|
/** Moves an item within an array using unique identifiers. */
|
|
157
|
-
moveById: <K extends
|
|
164
|
+
moveById: <K extends ArrayPaths<O>>(arrayKey: K, fromId: string | number, toId: string | number) => void;
|
|
158
165
|
/** Gets an item from an array by its unique identifier (O(1) via indexMap). */
|
|
159
|
-
getItem: <K extends
|
|
166
|
+
getItem: <K extends ArrayPaths<O>>(arrayKey: K, itemId: string | number) => (NestedFieldValue<O, K> extends (infer E)[] ? E : never) | undefined;
|
|
160
167
|
}
|
|
161
168
|
/**
|
|
162
169
|
* The response object from the useForm hook.
|
|
@@ -179,17 +186,23 @@ interface UseFormResponse<O extends StateType> {
|
|
|
179
186
|
isDirty: boolean;
|
|
180
187
|
/**
|
|
181
188
|
* Resets the form state and metadata.
|
|
182
|
-
* @param options Configuration for the reset (
|
|
189
|
+
* @param options Configuration for the reset (e.g., keys to keep).
|
|
183
190
|
*/
|
|
184
|
-
|
|
191
|
+
onFormReset: (options?: FormResetOptions<O>) => void;
|
|
185
192
|
/**
|
|
186
193
|
* Wraps a form submission handler to automatically validate the form.
|
|
187
194
|
* If validation fails, identifying errors and touching fields.
|
|
188
195
|
* If validation succeeds, calls the provided handler with the current state.
|
|
189
196
|
*/
|
|
190
|
-
|
|
197
|
+
onFormSubmit: (fn: FormSubmitHandler<O>) => (e: React.FormEvent) => void;
|
|
198
|
+
/**
|
|
199
|
+
* A controlled form component that handles submission and validation.
|
|
200
|
+
*/
|
|
201
|
+
ControlledForm: React.ComponentType<Omit<FormProps, "onSubmit"> & {
|
|
202
|
+
onSubmit?: (data: O, e: React.FormEvent<HTMLFormElement>) => void;
|
|
203
|
+
}>;
|
|
191
204
|
}
|
|
192
205
|
|
|
193
|
-
declare function useForm<S extends Record<string, ConfigType>>(schema: S, { arrayIdentifiers }?: FormOptions<InferState<S>>): UseFormResponse<InferState<S>>;
|
|
206
|
+
declare function useForm<S extends Record<string, ConfigType>>(schema: S, { arrayIdentifiers, onFormSubmit: onFormSubmitProp, resetOnSubmit, keepValues: keepValuesProp, }?: FormOptions<InferState<S>>): UseFormResponse<InferState<S>>;
|
|
194
207
|
|
|
195
|
-
export { type BlurFunc, type ConfigType, type FieldMetadata, type FormOptions, type HelpersFunc, type InferState, type MetadataType, type NestedChangeProps, NextUIError, type OnMethods, type StateType, type
|
|
208
|
+
export { type BlurFunc, type ConfigType, type FieldMetadata, type FormOptions, type FormSubmitHandler, type HelpersFunc, type InferState, type MetadataType, type NestedChangeProps, NextUIError, type OnMethods, type StateType, type UseFormResponse, type ValueChangeFunc, useForm };
|
package/dist/index.js
CHANGED
|
@@ -49,7 +49,11 @@ function handleNestedChange({
|
|
|
49
49
|
let current = newValues;
|
|
50
50
|
for (let i = 0; i < propertyDepth.length - 1; i++) {
|
|
51
51
|
const key = propertyDepth[i];
|
|
52
|
-
current[key]
|
|
52
|
+
if (Array.isArray(current[key])) {
|
|
53
|
+
current[key] = [...current[key]];
|
|
54
|
+
} else {
|
|
55
|
+
current[key] = { ...current[key] };
|
|
56
|
+
}
|
|
53
57
|
current = current[key];
|
|
54
58
|
}
|
|
55
59
|
current[propertyDepth[propertyDepth.length - 1]] = value;
|
|
@@ -70,7 +74,11 @@ function handleArrayItemChange({
|
|
|
70
74
|
} else {
|
|
71
75
|
let current = item;
|
|
72
76
|
for (let i = 0; i < fieldDepth.length - 1; i++) {
|
|
73
|
-
current[fieldDepth[i]]
|
|
77
|
+
if (Array.isArray(current[fieldDepth[i]])) {
|
|
78
|
+
current[fieldDepth[i]] = [...current[fieldDepth[i]]];
|
|
79
|
+
} else {
|
|
80
|
+
current[fieldDepth[i]] = { ...current[fieldDepth[i]] };
|
|
81
|
+
}
|
|
74
82
|
current = current[fieldDepth[i]];
|
|
75
83
|
}
|
|
76
84
|
current[fieldDepth[fieldDepth.length - 1]] = value;
|
|
@@ -91,6 +99,9 @@ function removeCompositeKeysByPrefix(map, prefix) {
|
|
|
91
99
|
return result;
|
|
92
100
|
}
|
|
93
101
|
|
|
102
|
+
// src/hooks/useForm.tsx
|
|
103
|
+
var import_react3 = require("@heroui/react");
|
|
104
|
+
|
|
94
105
|
// src/hooks/useComponentLang.tsx
|
|
95
106
|
var import_yup = require("yup");
|
|
96
107
|
var import_react = require("react");
|
|
@@ -249,7 +260,7 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
|
|
|
249
260
|
}
|
|
250
261
|
const arrayKey = arg0;
|
|
251
262
|
const index = arg1;
|
|
252
|
-
const arr = state
|
|
263
|
+
const arr = getNestedValue2(state, arrayKey);
|
|
253
264
|
return {
|
|
254
265
|
type: "primitiveArray" /* PrimitiveArray */,
|
|
255
266
|
compositeKey: `${arrayKey}.@${index}`,
|
|
@@ -304,15 +315,21 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
|
|
|
304
315
|
|
|
305
316
|
// src/hooks/useForm.tsx
|
|
306
317
|
var import_yup2 = require("yup");
|
|
318
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
307
319
|
var DEFAULT_OPTIONS = {};
|
|
308
|
-
function useForm(schema, {
|
|
320
|
+
function useForm(schema, {
|
|
321
|
+
arrayIdentifiers,
|
|
322
|
+
onFormSubmit: onFormSubmitProp,
|
|
323
|
+
resetOnSubmit = false,
|
|
324
|
+
keepValues: keepValuesProp
|
|
325
|
+
} = DEFAULT_OPTIONS) {
|
|
309
326
|
const { initialState, validationSchema } = (0, import_react2.useMemo)(() => {
|
|
310
327
|
const state2 = {};
|
|
311
328
|
const extractedRules = {};
|
|
312
329
|
Object.entries(schema).forEach(([key, value]) => {
|
|
313
330
|
if ((0, import_yup2.isSchema)(value)) {
|
|
314
331
|
try {
|
|
315
|
-
state2[key] = value.
|
|
332
|
+
state2[key] = value.cast(void 0);
|
|
316
333
|
} catch {
|
|
317
334
|
state2[key] = void 0;
|
|
318
335
|
}
|
|
@@ -524,9 +541,12 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
524
541
|
});
|
|
525
542
|
}
|
|
526
543
|
if (type === "primitiveArray" /* PrimitiveArray */) {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
544
|
+
return handleNestedChange({
|
|
545
|
+
state: prev,
|
|
546
|
+
id: `${arrayKey}.${index}`,
|
|
547
|
+
value: finalValue,
|
|
548
|
+
hasNestedValues: true
|
|
549
|
+
});
|
|
530
550
|
}
|
|
531
551
|
if (type === "objectArray" /* ObjectArray */) {
|
|
532
552
|
return handleArrayItemChange({
|
|
@@ -640,21 +660,31 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
640
660
|
() => ({
|
|
641
661
|
addItem: (arrayKey, item, index) => {
|
|
642
662
|
setState((prev) => {
|
|
643
|
-
const arr = [...prev[
|
|
663
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
644
664
|
if (index === void 0) arr.push(item);
|
|
645
665
|
else arr.splice(index, 0, item);
|
|
646
|
-
return {
|
|
666
|
+
return handleNestedChange({
|
|
667
|
+
state: prev,
|
|
668
|
+
id: arrayKey,
|
|
669
|
+
value: arr,
|
|
670
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
671
|
+
});
|
|
647
672
|
});
|
|
648
673
|
},
|
|
649
674
|
removeItem: (arrayKey, index) => {
|
|
650
|
-
const currentArr = stateRef.current[
|
|
675
|
+
const currentArr = getNestedValue(stateRef.current, arrayKey) || [];
|
|
651
676
|
const item = currentArr[index];
|
|
652
677
|
const idKey = arrayIdentifiers?.[arrayKey] || "id";
|
|
653
678
|
const itemId = item?.[idKey];
|
|
654
679
|
setState((prev) => {
|
|
655
|
-
const arr = [...prev[
|
|
680
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
656
681
|
arr.splice(index, 1);
|
|
657
|
-
return {
|
|
682
|
+
return handleNestedChange({
|
|
683
|
+
state: prev,
|
|
684
|
+
id: arrayKey,
|
|
685
|
+
value: arr,
|
|
686
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
687
|
+
});
|
|
658
688
|
});
|
|
659
689
|
if (itemId !== void 0) {
|
|
660
690
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
@@ -665,9 +695,14 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
665
695
|
const index = getIndex(arrayKey, itemId);
|
|
666
696
|
if (index !== void 0) {
|
|
667
697
|
setState((prev) => {
|
|
668
|
-
const arr = [...prev[
|
|
698
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
669
699
|
arr.splice(index, 1);
|
|
670
|
-
return {
|
|
700
|
+
return handleNestedChange({
|
|
701
|
+
state: prev,
|
|
702
|
+
id: arrayKey,
|
|
703
|
+
value: arr,
|
|
704
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
705
|
+
});
|
|
671
706
|
});
|
|
672
707
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
673
708
|
setMetadata((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
@@ -675,17 +710,27 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
675
710
|
},
|
|
676
711
|
updateItem: (arrayKey, index, value) => {
|
|
677
712
|
setState((prev) => {
|
|
678
|
-
const arr = [...prev[
|
|
713
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
679
714
|
arr[index] = value;
|
|
680
|
-
return {
|
|
715
|
+
return handleNestedChange({
|
|
716
|
+
state: prev,
|
|
717
|
+
id: arrayKey,
|
|
718
|
+
value: arr,
|
|
719
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
720
|
+
});
|
|
681
721
|
});
|
|
682
722
|
},
|
|
683
723
|
moveItem: (arrayKey, from, to) => {
|
|
684
724
|
setState((prev) => {
|
|
685
|
-
const arr = [...prev[
|
|
725
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
686
726
|
const [item] = arr.splice(from, 1);
|
|
687
727
|
arr.splice(to, 0, item);
|
|
688
|
-
return {
|
|
728
|
+
return handleNestedChange({
|
|
729
|
+
state: prev,
|
|
730
|
+
id: arrayKey,
|
|
731
|
+
value: arr,
|
|
732
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
733
|
+
});
|
|
689
734
|
});
|
|
690
735
|
},
|
|
691
736
|
moveById: (arrayKey, fromId, toId) => {
|
|
@@ -693,17 +738,22 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
693
738
|
const toIndex = getIndex(arrayKey, toId);
|
|
694
739
|
if (fromIndex !== void 0 && toIndex !== void 0) {
|
|
695
740
|
setState((prev) => {
|
|
696
|
-
const arr = [...prev[
|
|
741
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
697
742
|
const [item] = arr.splice(fromIndex, 1);
|
|
698
743
|
arr.splice(toIndex, 0, item);
|
|
699
|
-
return {
|
|
744
|
+
return handleNestedChange({
|
|
745
|
+
state: prev,
|
|
746
|
+
id: arrayKey,
|
|
747
|
+
value: arr,
|
|
748
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
749
|
+
});
|
|
700
750
|
});
|
|
701
751
|
}
|
|
702
752
|
},
|
|
703
753
|
getItem: (arrayKey, itemId) => {
|
|
704
754
|
const index = getIndex(arrayKey, itemId);
|
|
705
755
|
if (index === void 0) return void 0;
|
|
706
|
-
return stateRef.current
|
|
756
|
+
return getNestedValue(stateRef.current, arrayKey)[index];
|
|
707
757
|
}
|
|
708
758
|
}),
|
|
709
759
|
[getIndex, arrayIdentifiers]
|
|
@@ -746,7 +796,7 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
746
796
|
},
|
|
747
797
|
[validateField]
|
|
748
798
|
);
|
|
749
|
-
const
|
|
799
|
+
const onFormSubmit = (0, import_react2.useCallback)(
|
|
750
800
|
(fn) => (e) => {
|
|
751
801
|
e.preventDefault();
|
|
752
802
|
if (validateAll()) return;
|
|
@@ -754,6 +804,48 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
754
804
|
},
|
|
755
805
|
[validateAll]
|
|
756
806
|
);
|
|
807
|
+
const onFormSubmitPropRef = (0, import_react2.useRef)(onFormSubmitProp);
|
|
808
|
+
onFormSubmitPropRef.current = onFormSubmitProp;
|
|
809
|
+
const resetOnSubmitRef = (0, import_react2.useRef)(resetOnSubmit);
|
|
810
|
+
resetOnSubmitRef.current = resetOnSubmit;
|
|
811
|
+
const keepValuesPropRef = (0, import_react2.useRef)(keepValuesProp);
|
|
812
|
+
keepValuesPropRef.current = keepValuesProp;
|
|
813
|
+
const handleReset = (0, import_react2.useCallback)(
|
|
814
|
+
(options) => {
|
|
815
|
+
const { keepValues } = options || {};
|
|
816
|
+
if (keepValues && keepValues.length > 0) {
|
|
817
|
+
const nextState = { ...initialState };
|
|
818
|
+
keepValues.forEach((k) => {
|
|
819
|
+
if (stateRef.current[k] !== void 0)
|
|
820
|
+
nextState[k] = stateRef.current[k];
|
|
821
|
+
});
|
|
822
|
+
setState(nextState);
|
|
823
|
+
} else {
|
|
824
|
+
setState(initialState);
|
|
825
|
+
}
|
|
826
|
+
setMetadata(/* @__PURE__ */ new Map());
|
|
827
|
+
},
|
|
828
|
+
[initialState]
|
|
829
|
+
);
|
|
830
|
+
const validateAllRef = (0, import_react2.useRef)(validateAll);
|
|
831
|
+
validateAllRef.current = validateAll;
|
|
832
|
+
const ControlledForm = (0, import_react2.useMemo)(() => {
|
|
833
|
+
return (props) => {
|
|
834
|
+
const { onSubmit, ...rest } = props;
|
|
835
|
+
const handleSubmit = (e) => {
|
|
836
|
+
e.preventDefault();
|
|
837
|
+
if (validateAllRef.current()) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
onFormSubmitPropRef.current?.(stateRef.current, e);
|
|
841
|
+
if (resetOnSubmitRef.current) {
|
|
842
|
+
handleReset({ keepValues: keepValuesPropRef.current });
|
|
843
|
+
}
|
|
844
|
+
onSubmit?.(stateRef.current, e);
|
|
845
|
+
};
|
|
846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react3.Form, { onSubmit: handleSubmit, ...rest });
|
|
847
|
+
};
|
|
848
|
+
}, []);
|
|
757
849
|
return (0, import_react2.useMemo)(
|
|
758
850
|
() => ({
|
|
759
851
|
state,
|
|
@@ -765,37 +857,9 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
765
857
|
onFieldBlur: onBlur,
|
|
766
858
|
onSelectionChange: polymorphicOnSelectionChange,
|
|
767
859
|
isDirty: Array.from(metadata.values()).some((m) => m.isTouched),
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
const nextState = { ...initialState };
|
|
772
|
-
preservedStateKeys.forEach((k) => {
|
|
773
|
-
if (stateRef.current[k] !== void 0)
|
|
774
|
-
nextState[k] = stateRef.current[k];
|
|
775
|
-
});
|
|
776
|
-
setState(nextState);
|
|
777
|
-
} else {
|
|
778
|
-
setState(initialState);
|
|
779
|
-
}
|
|
780
|
-
if (preserveTouched) {
|
|
781
|
-
setMetadata((prev) => {
|
|
782
|
-
const next = /* @__PURE__ */ new Map();
|
|
783
|
-
prev.forEach((v, k) => {
|
|
784
|
-
if (v.isTouched) {
|
|
785
|
-
next.set(k, {
|
|
786
|
-
isTouched: true,
|
|
787
|
-
isInvalid: false,
|
|
788
|
-
errorMessage: ""
|
|
789
|
-
});
|
|
790
|
-
}
|
|
791
|
-
});
|
|
792
|
-
return next;
|
|
793
|
-
});
|
|
794
|
-
} else {
|
|
795
|
-
setMetadata(/* @__PURE__ */ new Map());
|
|
796
|
-
}
|
|
797
|
-
},
|
|
798
|
-
onSubmit
|
|
860
|
+
onFormReset: handleReset,
|
|
861
|
+
onFormSubmit,
|
|
862
|
+
ControlledForm
|
|
799
863
|
}),
|
|
800
864
|
[
|
|
801
865
|
state,
|
|
@@ -807,7 +871,8 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
807
871
|
polymorphicOnValueChange,
|
|
808
872
|
polymorphicOnSelectionChange,
|
|
809
873
|
validateAll,
|
|
810
|
-
|
|
874
|
+
onFormSubmit,
|
|
875
|
+
ControlledForm,
|
|
811
876
|
initialState
|
|
812
877
|
]
|
|
813
878
|
);
|
package/dist/index.mjs
CHANGED
|
@@ -23,7 +23,11 @@ function handleNestedChange({
|
|
|
23
23
|
let current = newValues;
|
|
24
24
|
for (let i = 0; i < propertyDepth.length - 1; i++) {
|
|
25
25
|
const key = propertyDepth[i];
|
|
26
|
-
current[key]
|
|
26
|
+
if (Array.isArray(current[key])) {
|
|
27
|
+
current[key] = [...current[key]];
|
|
28
|
+
} else {
|
|
29
|
+
current[key] = { ...current[key] };
|
|
30
|
+
}
|
|
27
31
|
current = current[key];
|
|
28
32
|
}
|
|
29
33
|
current[propertyDepth[propertyDepth.length - 1]] = value;
|
|
@@ -44,7 +48,11 @@ function handleArrayItemChange({
|
|
|
44
48
|
} else {
|
|
45
49
|
let current = item;
|
|
46
50
|
for (let i = 0; i < fieldDepth.length - 1; i++) {
|
|
47
|
-
current[fieldDepth[i]]
|
|
51
|
+
if (Array.isArray(current[fieldDepth[i]])) {
|
|
52
|
+
current[fieldDepth[i]] = [...current[fieldDepth[i]]];
|
|
53
|
+
} else {
|
|
54
|
+
current[fieldDepth[i]] = { ...current[fieldDepth[i]] };
|
|
55
|
+
}
|
|
48
56
|
current = current[fieldDepth[i]];
|
|
49
57
|
}
|
|
50
58
|
current[fieldDepth[fieldDepth.length - 1]] = value;
|
|
@@ -65,6 +73,9 @@ function removeCompositeKeysByPrefix(map, prefix) {
|
|
|
65
73
|
return result;
|
|
66
74
|
}
|
|
67
75
|
|
|
76
|
+
// src/hooks/useForm.tsx
|
|
77
|
+
import { Form } from "@heroui/react";
|
|
78
|
+
|
|
68
79
|
// src/hooks/useComponentLang.tsx
|
|
69
80
|
import { setLocale } from "yup";
|
|
70
81
|
import { useEffect } from "react";
|
|
@@ -223,7 +234,7 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
|
|
|
223
234
|
}
|
|
224
235
|
const arrayKey = arg0;
|
|
225
236
|
const index = arg1;
|
|
226
|
-
const arr = state
|
|
237
|
+
const arr = getNestedValue2(state, arrayKey);
|
|
227
238
|
return {
|
|
228
239
|
type: "primitiveArray" /* PrimitiveArray */,
|
|
229
240
|
compositeKey: `${arrayKey}.@${index}`,
|
|
@@ -278,15 +289,21 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
|
|
|
278
289
|
|
|
279
290
|
// src/hooks/useForm.tsx
|
|
280
291
|
import { isSchema, object, reach } from "yup";
|
|
292
|
+
import { jsx } from "react/jsx-runtime";
|
|
281
293
|
var DEFAULT_OPTIONS = {};
|
|
282
|
-
function useForm(schema, {
|
|
294
|
+
function useForm(schema, {
|
|
295
|
+
arrayIdentifiers,
|
|
296
|
+
onFormSubmit: onFormSubmitProp,
|
|
297
|
+
resetOnSubmit = false,
|
|
298
|
+
keepValues: keepValuesProp
|
|
299
|
+
} = DEFAULT_OPTIONS) {
|
|
283
300
|
const { initialState, validationSchema } = useMemo(() => {
|
|
284
301
|
const state2 = {};
|
|
285
302
|
const extractedRules = {};
|
|
286
303
|
Object.entries(schema).forEach(([key, value]) => {
|
|
287
304
|
if (isSchema(value)) {
|
|
288
305
|
try {
|
|
289
|
-
state2[key] = value.
|
|
306
|
+
state2[key] = value.cast(void 0);
|
|
290
307
|
} catch {
|
|
291
308
|
state2[key] = void 0;
|
|
292
309
|
}
|
|
@@ -498,9 +515,12 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
498
515
|
});
|
|
499
516
|
}
|
|
500
517
|
if (type === "primitiveArray" /* PrimitiveArray */) {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
518
|
+
return handleNestedChange({
|
|
519
|
+
state: prev,
|
|
520
|
+
id: `${arrayKey}.${index}`,
|
|
521
|
+
value: finalValue,
|
|
522
|
+
hasNestedValues: true
|
|
523
|
+
});
|
|
504
524
|
}
|
|
505
525
|
if (type === "objectArray" /* ObjectArray */) {
|
|
506
526
|
return handleArrayItemChange({
|
|
@@ -614,21 +634,31 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
614
634
|
() => ({
|
|
615
635
|
addItem: (arrayKey, item, index) => {
|
|
616
636
|
setState((prev) => {
|
|
617
|
-
const arr = [...prev[
|
|
637
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
618
638
|
if (index === void 0) arr.push(item);
|
|
619
639
|
else arr.splice(index, 0, item);
|
|
620
|
-
return {
|
|
640
|
+
return handleNestedChange({
|
|
641
|
+
state: prev,
|
|
642
|
+
id: arrayKey,
|
|
643
|
+
value: arr,
|
|
644
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
645
|
+
});
|
|
621
646
|
});
|
|
622
647
|
},
|
|
623
648
|
removeItem: (arrayKey, index) => {
|
|
624
|
-
const currentArr = stateRef.current[
|
|
649
|
+
const currentArr = getNestedValue(stateRef.current, arrayKey) || [];
|
|
625
650
|
const item = currentArr[index];
|
|
626
651
|
const idKey = arrayIdentifiers?.[arrayKey] || "id";
|
|
627
652
|
const itemId = item?.[idKey];
|
|
628
653
|
setState((prev) => {
|
|
629
|
-
const arr = [...prev[
|
|
654
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
630
655
|
arr.splice(index, 1);
|
|
631
|
-
return {
|
|
656
|
+
return handleNestedChange({
|
|
657
|
+
state: prev,
|
|
658
|
+
id: arrayKey,
|
|
659
|
+
value: arr,
|
|
660
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
661
|
+
});
|
|
632
662
|
});
|
|
633
663
|
if (itemId !== void 0) {
|
|
634
664
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
@@ -639,9 +669,14 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
639
669
|
const index = getIndex(arrayKey, itemId);
|
|
640
670
|
if (index !== void 0) {
|
|
641
671
|
setState((prev) => {
|
|
642
|
-
const arr = [...prev[
|
|
672
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
643
673
|
arr.splice(index, 1);
|
|
644
|
-
return {
|
|
674
|
+
return handleNestedChange({
|
|
675
|
+
state: prev,
|
|
676
|
+
id: arrayKey,
|
|
677
|
+
value: arr,
|
|
678
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
679
|
+
});
|
|
645
680
|
});
|
|
646
681
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
647
682
|
setMetadata((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
@@ -649,17 +684,27 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
649
684
|
},
|
|
650
685
|
updateItem: (arrayKey, index, value) => {
|
|
651
686
|
setState((prev) => {
|
|
652
|
-
const arr = [...prev[
|
|
687
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
653
688
|
arr[index] = value;
|
|
654
|
-
return {
|
|
689
|
+
return handleNestedChange({
|
|
690
|
+
state: prev,
|
|
691
|
+
id: arrayKey,
|
|
692
|
+
value: arr,
|
|
693
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
694
|
+
});
|
|
655
695
|
});
|
|
656
696
|
},
|
|
657
697
|
moveItem: (arrayKey, from, to) => {
|
|
658
698
|
setState((prev) => {
|
|
659
|
-
const arr = [...prev[
|
|
699
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
660
700
|
const [item] = arr.splice(from, 1);
|
|
661
701
|
arr.splice(to, 0, item);
|
|
662
|
-
return {
|
|
702
|
+
return handleNestedChange({
|
|
703
|
+
state: prev,
|
|
704
|
+
id: arrayKey,
|
|
705
|
+
value: arr,
|
|
706
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
707
|
+
});
|
|
663
708
|
});
|
|
664
709
|
},
|
|
665
710
|
moveById: (arrayKey, fromId, toId) => {
|
|
@@ -667,17 +712,22 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
667
712
|
const toIndex = getIndex(arrayKey, toId);
|
|
668
713
|
if (fromIndex !== void 0 && toIndex !== void 0) {
|
|
669
714
|
setState((prev) => {
|
|
670
|
-
const arr = [...prev[
|
|
715
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
671
716
|
const [item] = arr.splice(fromIndex, 1);
|
|
672
717
|
arr.splice(toIndex, 0, item);
|
|
673
|
-
return {
|
|
718
|
+
return handleNestedChange({
|
|
719
|
+
state: prev,
|
|
720
|
+
id: arrayKey,
|
|
721
|
+
value: arr,
|
|
722
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
723
|
+
});
|
|
674
724
|
});
|
|
675
725
|
}
|
|
676
726
|
},
|
|
677
727
|
getItem: (arrayKey, itemId) => {
|
|
678
728
|
const index = getIndex(arrayKey, itemId);
|
|
679
729
|
if (index === void 0) return void 0;
|
|
680
|
-
return stateRef.current
|
|
730
|
+
return getNestedValue(stateRef.current, arrayKey)[index];
|
|
681
731
|
}
|
|
682
732
|
}),
|
|
683
733
|
[getIndex, arrayIdentifiers]
|
|
@@ -720,7 +770,7 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
720
770
|
},
|
|
721
771
|
[validateField]
|
|
722
772
|
);
|
|
723
|
-
const
|
|
773
|
+
const onFormSubmit = useCallback(
|
|
724
774
|
(fn) => (e) => {
|
|
725
775
|
e.preventDefault();
|
|
726
776
|
if (validateAll()) return;
|
|
@@ -728,6 +778,48 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
728
778
|
},
|
|
729
779
|
[validateAll]
|
|
730
780
|
);
|
|
781
|
+
const onFormSubmitPropRef = useRef(onFormSubmitProp);
|
|
782
|
+
onFormSubmitPropRef.current = onFormSubmitProp;
|
|
783
|
+
const resetOnSubmitRef = useRef(resetOnSubmit);
|
|
784
|
+
resetOnSubmitRef.current = resetOnSubmit;
|
|
785
|
+
const keepValuesPropRef = useRef(keepValuesProp);
|
|
786
|
+
keepValuesPropRef.current = keepValuesProp;
|
|
787
|
+
const handleReset = useCallback(
|
|
788
|
+
(options) => {
|
|
789
|
+
const { keepValues } = options || {};
|
|
790
|
+
if (keepValues && keepValues.length > 0) {
|
|
791
|
+
const nextState = { ...initialState };
|
|
792
|
+
keepValues.forEach((k) => {
|
|
793
|
+
if (stateRef.current[k] !== void 0)
|
|
794
|
+
nextState[k] = stateRef.current[k];
|
|
795
|
+
});
|
|
796
|
+
setState(nextState);
|
|
797
|
+
} else {
|
|
798
|
+
setState(initialState);
|
|
799
|
+
}
|
|
800
|
+
setMetadata(/* @__PURE__ */ new Map());
|
|
801
|
+
},
|
|
802
|
+
[initialState]
|
|
803
|
+
);
|
|
804
|
+
const validateAllRef = useRef(validateAll);
|
|
805
|
+
validateAllRef.current = validateAll;
|
|
806
|
+
const ControlledForm = useMemo(() => {
|
|
807
|
+
return (props) => {
|
|
808
|
+
const { onSubmit, ...rest } = props;
|
|
809
|
+
const handleSubmit = (e) => {
|
|
810
|
+
e.preventDefault();
|
|
811
|
+
if (validateAllRef.current()) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
onFormSubmitPropRef.current?.(stateRef.current, e);
|
|
815
|
+
if (resetOnSubmitRef.current) {
|
|
816
|
+
handleReset({ keepValues: keepValuesPropRef.current });
|
|
817
|
+
}
|
|
818
|
+
onSubmit?.(stateRef.current, e);
|
|
819
|
+
};
|
|
820
|
+
return /* @__PURE__ */ jsx(Form, { onSubmit: handleSubmit, ...rest });
|
|
821
|
+
};
|
|
822
|
+
}, []);
|
|
731
823
|
return useMemo(
|
|
732
824
|
() => ({
|
|
733
825
|
state,
|
|
@@ -739,37 +831,9 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
739
831
|
onFieldBlur: onBlur,
|
|
740
832
|
onSelectionChange: polymorphicOnSelectionChange,
|
|
741
833
|
isDirty: Array.from(metadata.values()).some((m) => m.isTouched),
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
const nextState = { ...initialState };
|
|
746
|
-
preservedStateKeys.forEach((k) => {
|
|
747
|
-
if (stateRef.current[k] !== void 0)
|
|
748
|
-
nextState[k] = stateRef.current[k];
|
|
749
|
-
});
|
|
750
|
-
setState(nextState);
|
|
751
|
-
} else {
|
|
752
|
-
setState(initialState);
|
|
753
|
-
}
|
|
754
|
-
if (preserveTouched) {
|
|
755
|
-
setMetadata((prev) => {
|
|
756
|
-
const next = /* @__PURE__ */ new Map();
|
|
757
|
-
prev.forEach((v, k) => {
|
|
758
|
-
if (v.isTouched) {
|
|
759
|
-
next.set(k, {
|
|
760
|
-
isTouched: true,
|
|
761
|
-
isInvalid: false,
|
|
762
|
-
errorMessage: ""
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
});
|
|
766
|
-
return next;
|
|
767
|
-
});
|
|
768
|
-
} else {
|
|
769
|
-
setMetadata(/* @__PURE__ */ new Map());
|
|
770
|
-
}
|
|
771
|
-
},
|
|
772
|
-
onSubmit
|
|
834
|
+
onFormReset: handleReset,
|
|
835
|
+
onFormSubmit,
|
|
836
|
+
ControlledForm
|
|
773
837
|
}),
|
|
774
838
|
[
|
|
775
839
|
state,
|
|
@@ -781,7 +845,8 @@ function useForm(schema, { arrayIdentifiers } = DEFAULT_OPTIONS) {
|
|
|
781
845
|
polymorphicOnValueChange,
|
|
782
846
|
polymorphicOnSelectionChange,
|
|
783
847
|
validateAll,
|
|
784
|
-
|
|
848
|
+
onFormSubmit,
|
|
849
|
+
ControlledForm,
|
|
785
850
|
initialState
|
|
786
851
|
]
|
|
787
852
|
);
|
package/package.json
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@juantroconisf/lib",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A form validation library for HeroUI.",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.mjs",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"files": [
|
|
9
|
-
"dist",
|
|
10
|
-
"README.md"
|
|
11
|
-
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"test": "vitest run",
|
|
14
|
-
"build": "pnpm test && tsup src/index.ts --format cjs,esm --dts",
|
|
15
|
-
"lint": "tsc",
|
|
16
|
-
"prepublishOnly": "pnpm run build"
|
|
17
|
-
},
|
|
18
|
-
"author": "Juan T",
|
|
19
|
-
"license": "ISC",
|
|
20
|
-
"bugs": {
|
|
21
|
-
"url": "https://github.com/juandiegotroconis/lib/issues"
|
|
22
|
-
},
|
|
23
|
-
"typings": "dist/index.d.ts",
|
|
24
|
-
"homepage": "https://github.com/juandiegotroconis/lib#readme",
|
|
25
|
-
"devDependencies": {
|
|
26
|
-
"@heroui/react": "^2.8.5",
|
|
27
|
-
"@react-types/shared": "^3.32.1",
|
|
28
|
-
"@testing-library/jest-dom": "^6.9.1",
|
|
29
|
-
"@testing-library/react": "^16.3.2",
|
|
30
|
-
"@types/node": "^24.7.1",
|
|
31
|
-
"@types/react": "^19.2.2",
|
|
32
|
-
"jsdom": "^28.1.0",
|
|
33
|
-
"react": "^19.2.0",
|
|
34
|
-
"tsup": "^8.5.0",
|
|
35
|
-
"typescript": "^5.9.3",
|
|
36
|
-
"vitest": "^4.0.18"
|
|
37
|
-
},
|
|
38
|
-
"peerDependencies": {
|
|
39
|
-
"@heroui/react": ">=2.0.0",
|
|
40
|
-
"react": ">=18.0.0"
|
|
41
|
-
},
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"yup": "^1.7.1"
|
|
44
|
-
}
|
|
45
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@juantroconisf/lib",
|
|
3
|
+
"version": "9.0.0",
|
|
4
|
+
"description": "A form validation library for HeroUI.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"build": "pnpm test && tsup src/index.ts --format cjs,esm --dts",
|
|
15
|
+
"lint": "tsc",
|
|
16
|
+
"prepublishOnly": "pnpm run build"
|
|
17
|
+
},
|
|
18
|
+
"author": "Juan T",
|
|
19
|
+
"license": "ISC",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/juandiegotroconis/lib/issues"
|
|
22
|
+
},
|
|
23
|
+
"typings": "dist/index.d.ts",
|
|
24
|
+
"homepage": "https://github.com/juandiegotroconis/lib#readme",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@heroui/react": "^2.8.5",
|
|
27
|
+
"@react-types/shared": "^3.32.1",
|
|
28
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
29
|
+
"@testing-library/react": "^16.3.2",
|
|
30
|
+
"@types/node": "^24.7.1",
|
|
31
|
+
"@types/react": "^19.2.2",
|
|
32
|
+
"jsdom": "^28.1.0",
|
|
33
|
+
"react": "^19.2.0",
|
|
34
|
+
"tsup": "^8.5.0",
|
|
35
|
+
"typescript": "^5.9.3",
|
|
36
|
+
"vitest": "^4.0.18"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@heroui/react": ">=2.0.0",
|
|
40
|
+
"react": ">=18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"yup": "^1.7.1"
|
|
44
|
+
}
|
|
45
|
+
}
|