remix-validated-form 5.1.4 → 5.1.6
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/.turbo/turbo-build.log +10 -10
- package/dist/index.cjs.js +4 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +4 -1
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -4
- package/.turbo/turbo-dev.log +0 -0
- package/.turbo/turbo-typecheck.log +0 -1
- package/browser/ValidatedForm.d.ts +0 -50
- package/browser/ValidatedForm.js +0 -210
- package/browser/hooks.d.ts +0 -67
- package/browser/hooks.js +0 -84
- package/browser/index.d.ts +0 -7
- package/browser/index.js +0 -7
- package/browser/internal/MultiValueMap.d.ts +0 -11
- package/browser/internal/MultiValueMap.js +0 -43
- package/browser/internal/constants.d.ts +0 -3
- package/browser/internal/constants.js +0 -3
- package/browser/internal/flatten.d.ts +0 -1
- package/browser/internal/flatten.js +0 -7
- package/browser/internal/formContext.d.ts +0 -12
- package/browser/internal/formContext.js +0 -2
- package/browser/internal/getInputProps.d.ts +0 -29
- package/browser/internal/getInputProps.js +0 -51
- package/browser/internal/hooks.d.ts +0 -35
- package/browser/internal/hooks.js +0 -118
- package/browser/internal/hydratable.d.ts +0 -14
- package/browser/internal/hydratable.js +0 -14
- package/browser/internal/logic/getCheckboxChecked.d.ts +0 -1
- package/browser/internal/logic/getCheckboxChecked.js +0 -9
- package/browser/internal/logic/getRadioChecked.d.ts +0 -1
- package/browser/internal/logic/getRadioChecked.js +0 -15
- package/browser/internal/logic/nestedObjectToPathObject.d.ts +0 -1
- package/browser/internal/logic/nestedObjectToPathObject.js +0 -47
- package/browser/internal/logic/requestSubmit.d.ts +0 -5
- package/browser/internal/logic/requestSubmit.js +0 -66
- package/browser/internal/reset.d.ts +0 -28
- package/browser/internal/reset.js +0 -13
- package/browser/internal/state/arrayUtil.d.ts +0 -12
- package/browser/internal/state/arrayUtil.js +0 -350
- package/browser/internal/state/atomUtils.d.ts +0 -38
- package/browser/internal/state/atomUtils.js +0 -5
- package/browser/internal/state/cleanup.d.ts +0 -2
- package/browser/internal/state/cleanup.js +0 -6
- package/browser/internal/state/controlledFieldStore.d.ts +0 -26
- package/browser/internal/state/controlledFieldStore.js +0 -70
- package/browser/internal/state/controlledFields.d.ts +0 -7
- package/browser/internal/state/controlledFields.js +0 -36
- package/browser/internal/state/createFormStore.d.ts +0 -79
- package/browser/internal/state/createFormStore.js +0 -306
- package/browser/internal/state/fieldArray.d.ts +0 -28
- package/browser/internal/state/fieldArray.js +0 -74
- package/browser/internal/state/storeFamily.d.ts +0 -9
- package/browser/internal/state/storeFamily.js +0 -18
- package/browser/internal/state/storeHooks.d.ts +0 -3
- package/browser/internal/state/storeHooks.js +0 -4
- package/browser/internal/state/types.d.ts +0 -1
- package/browser/internal/state/types.js +0 -1
- package/browser/internal/state.d.ts +0 -343
- package/browser/internal/state.js +0 -64
- package/browser/internal/submissionCallbacks.d.ts +0 -1
- package/browser/internal/submissionCallbacks.js +0 -13
- package/browser/internal/util.d.ts +0 -5
- package/browser/internal/util.js +0 -32
- package/browser/server.d.ts +0 -21
- package/browser/server.js +0 -27
- package/browser/unreleased/formStateHooks.d.ts +0 -64
- package/browser/unreleased/formStateHooks.js +0 -76
- package/browser/userFacingFormContext.d.ts +0 -85
- package/browser/userFacingFormContext.js +0 -41
- package/browser/validation/createValidator.d.ts +0 -7
- package/browser/validation/createValidator.js +0 -43
- package/browser/validation/types.d.ts +0 -58
- package/browser/validation/types.js +0 -1
- package/stats.html +0 -4044
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
import { getPath, setPath } from "set-get";
|
|
2
|
-
import invariant from "tiny-invariant";
|
|
3
|
-
import create from "zustand";
|
|
4
|
-
import { immer } from "zustand/middleware/immer";
|
|
5
|
-
import { requestSubmit } from "../logic/requestSubmit";
|
|
6
|
-
import * as arrayUtil from "./arrayUtil";
|
|
7
|
-
const noOp = () => { };
|
|
8
|
-
const defaultFormState = {
|
|
9
|
-
isHydrated: false,
|
|
10
|
-
isSubmitting: false,
|
|
11
|
-
hasBeenSubmitted: false,
|
|
12
|
-
touchedFields: {},
|
|
13
|
-
fieldErrors: {},
|
|
14
|
-
formElement: null,
|
|
15
|
-
isValid: () => true,
|
|
16
|
-
startSubmit: noOp,
|
|
17
|
-
endSubmit: noOp,
|
|
18
|
-
setTouched: noOp,
|
|
19
|
-
setFieldError: noOp,
|
|
20
|
-
setFieldErrors: noOp,
|
|
21
|
-
clearFieldError: noOp,
|
|
22
|
-
currentDefaultValues: {},
|
|
23
|
-
reset: () => noOp,
|
|
24
|
-
syncFormProps: noOp,
|
|
25
|
-
setFormElement: noOp,
|
|
26
|
-
validateField: async () => null,
|
|
27
|
-
validate: async () => {
|
|
28
|
-
throw new Error("Validate called before form was initialized.");
|
|
29
|
-
},
|
|
30
|
-
submit: async () => {
|
|
31
|
-
throw new Error("Submit called before form was initialized.");
|
|
32
|
-
},
|
|
33
|
-
resetFormElement: noOp,
|
|
34
|
-
getValues: () => new FormData(),
|
|
35
|
-
controlledFields: {
|
|
36
|
-
values: {},
|
|
37
|
-
refCounts: {},
|
|
38
|
-
valueUpdatePromises: {},
|
|
39
|
-
valueUpdateResolvers: {},
|
|
40
|
-
register: noOp,
|
|
41
|
-
unregister: noOp,
|
|
42
|
-
setValue: noOp,
|
|
43
|
-
getValue: noOp,
|
|
44
|
-
kickoffValueUpdate: noOp,
|
|
45
|
-
awaitValueUpdate: async () => {
|
|
46
|
-
throw new Error("AwaitValueUpdate called before form was initialized.");
|
|
47
|
-
},
|
|
48
|
-
array: {
|
|
49
|
-
push: noOp,
|
|
50
|
-
swap: noOp,
|
|
51
|
-
move: noOp,
|
|
52
|
-
insert: noOp,
|
|
53
|
-
unshift: noOp,
|
|
54
|
-
remove: noOp,
|
|
55
|
-
pop: noOp,
|
|
56
|
-
replace: noOp,
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
const createFormState = (set, get) => ({
|
|
61
|
-
// It's not "hydrated" until the form props are synced
|
|
62
|
-
isHydrated: false,
|
|
63
|
-
isSubmitting: false,
|
|
64
|
-
hasBeenSubmitted: false,
|
|
65
|
-
touchedFields: {},
|
|
66
|
-
fieldErrors: {},
|
|
67
|
-
formElement: null,
|
|
68
|
-
currentDefaultValues: {},
|
|
69
|
-
isValid: () => Object.keys(get().fieldErrors).length === 0,
|
|
70
|
-
startSubmit: () => set((state) => {
|
|
71
|
-
state.isSubmitting = true;
|
|
72
|
-
state.hasBeenSubmitted = true;
|
|
73
|
-
}),
|
|
74
|
-
endSubmit: () => set((state) => {
|
|
75
|
-
state.isSubmitting = false;
|
|
76
|
-
}),
|
|
77
|
-
setTouched: (fieldName, touched) => set((state) => {
|
|
78
|
-
state.touchedFields[fieldName] = touched;
|
|
79
|
-
}),
|
|
80
|
-
setFieldError: (fieldName, error) => set((state) => {
|
|
81
|
-
state.fieldErrors[fieldName] = error;
|
|
82
|
-
}),
|
|
83
|
-
setFieldErrors: (errors) => set((state) => {
|
|
84
|
-
state.fieldErrors = errors;
|
|
85
|
-
}),
|
|
86
|
-
clearFieldError: (fieldName) => set((state) => {
|
|
87
|
-
delete state.fieldErrors[fieldName];
|
|
88
|
-
}),
|
|
89
|
-
reset: () => set((state) => {
|
|
90
|
-
var _a, _b;
|
|
91
|
-
state.fieldErrors = {};
|
|
92
|
-
state.touchedFields = {};
|
|
93
|
-
state.hasBeenSubmitted = false;
|
|
94
|
-
const nextDefaults = (_b = (_a = state.formProps) === null || _a === void 0 ? void 0 : _a.defaultValues) !== null && _b !== void 0 ? _b : {};
|
|
95
|
-
state.controlledFields.values = nextDefaults;
|
|
96
|
-
state.currentDefaultValues = nextDefaults;
|
|
97
|
-
}),
|
|
98
|
-
syncFormProps: (props) => set((state) => {
|
|
99
|
-
if (!state.isHydrated) {
|
|
100
|
-
state.controlledFields.values = props.defaultValues;
|
|
101
|
-
state.currentDefaultValues = props.defaultValues;
|
|
102
|
-
}
|
|
103
|
-
state.formProps = props;
|
|
104
|
-
state.isHydrated = true;
|
|
105
|
-
}),
|
|
106
|
-
setFormElement: (formElement) => {
|
|
107
|
-
// This gets called frequently, so we want to avoid calling set() every time
|
|
108
|
-
// Or else we wind up with an infinite loop
|
|
109
|
-
if (get().formElement === formElement)
|
|
110
|
-
return;
|
|
111
|
-
set((state) => {
|
|
112
|
-
// weird type issue here
|
|
113
|
-
// seems to be because formElement is a writable draft
|
|
114
|
-
state.formElement = formElement;
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
validateField: async (field) => {
|
|
118
|
-
var _a, _b, _c;
|
|
119
|
-
const formElement = get().formElement;
|
|
120
|
-
invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
|
|
121
|
-
const validator = (_a = get().formProps) === null || _a === void 0 ? void 0 : _a.validator;
|
|
122
|
-
invariant(validator, "Cannot validator. This is probably a bug in remix-validated-form.");
|
|
123
|
-
await ((_c = (_b = get().controlledFields).awaitValueUpdate) === null || _c === void 0 ? void 0 : _c.call(_b, field));
|
|
124
|
-
const { error } = await validator.validateField(new FormData(formElement), field);
|
|
125
|
-
if (error) {
|
|
126
|
-
get().setFieldError(field, error);
|
|
127
|
-
return error;
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
get().clearFieldError(field);
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
validate: async () => {
|
|
135
|
-
var _a;
|
|
136
|
-
const formElement = get().formElement;
|
|
137
|
-
invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
|
|
138
|
-
const validator = (_a = get().formProps) === null || _a === void 0 ? void 0 : _a.validator;
|
|
139
|
-
invariant(validator, "Cannot validator. This is probably a bug in remix-validated-form.");
|
|
140
|
-
const result = await validator.validate(new FormData(formElement));
|
|
141
|
-
if (result.error)
|
|
142
|
-
get().setFieldErrors(result.error.fieldErrors);
|
|
143
|
-
return result;
|
|
144
|
-
},
|
|
145
|
-
submit: () => {
|
|
146
|
-
const formElement = get().formElement;
|
|
147
|
-
invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
|
|
148
|
-
requestSubmit(formElement);
|
|
149
|
-
},
|
|
150
|
-
getValues: () => { var _a; return new FormData((_a = get().formElement) !== null && _a !== void 0 ? _a : undefined); },
|
|
151
|
-
resetFormElement: () => { var _a; return (_a = get().formElement) === null || _a === void 0 ? void 0 : _a.reset(); },
|
|
152
|
-
controlledFields: {
|
|
153
|
-
values: {},
|
|
154
|
-
refCounts: {},
|
|
155
|
-
valueUpdatePromises: {},
|
|
156
|
-
valueUpdateResolvers: {},
|
|
157
|
-
register: (fieldName) => {
|
|
158
|
-
set((state) => {
|
|
159
|
-
var _a;
|
|
160
|
-
const current = (_a = state.controlledFields.refCounts[fieldName]) !== null && _a !== void 0 ? _a : 0;
|
|
161
|
-
state.controlledFields.refCounts[fieldName] = current + 1;
|
|
162
|
-
});
|
|
163
|
-
},
|
|
164
|
-
unregister: (fieldName) => {
|
|
165
|
-
// For this helper in particular, we may run into a case where state is undefined.
|
|
166
|
-
// When the whole form unmounts, the form state may be cleaned up before the fields are.
|
|
167
|
-
if (get() === null || get() === undefined)
|
|
168
|
-
return;
|
|
169
|
-
set((state) => {
|
|
170
|
-
var _a, _b, _c;
|
|
171
|
-
const current = (_a = state.controlledFields.refCounts[fieldName]) !== null && _a !== void 0 ? _a : 0;
|
|
172
|
-
if (current > 1) {
|
|
173
|
-
state.controlledFields.refCounts[fieldName] = current - 1;
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
const isNested = Object.keys(state.controlledFields.refCounts).some((key) => fieldName.startsWith(key) && key !== fieldName);
|
|
177
|
-
// When nested within a field array, we should leave resetting up to the field array
|
|
178
|
-
if (!isNested) {
|
|
179
|
-
setPath(state.controlledFields.values, fieldName, getPath((_b = state.formProps) === null || _b === void 0 ? void 0 : _b.defaultValues, fieldName));
|
|
180
|
-
setPath(state.currentDefaultValues, fieldName, getPath((_c = state.formProps) === null || _c === void 0 ? void 0 : _c.defaultValues, fieldName));
|
|
181
|
-
}
|
|
182
|
-
delete state.controlledFields.refCounts[fieldName];
|
|
183
|
-
});
|
|
184
|
-
},
|
|
185
|
-
getValue: (fieldName) => getPath(get().controlledFields.values, fieldName),
|
|
186
|
-
setValue: (fieldName, value) => {
|
|
187
|
-
set((state) => {
|
|
188
|
-
setPath(state.controlledFields.values, fieldName, value);
|
|
189
|
-
});
|
|
190
|
-
get().controlledFields.kickoffValueUpdate(fieldName);
|
|
191
|
-
},
|
|
192
|
-
kickoffValueUpdate: (fieldName) => {
|
|
193
|
-
const clear = () => set((state) => {
|
|
194
|
-
delete state.controlledFields.valueUpdateResolvers[fieldName];
|
|
195
|
-
delete state.controlledFields.valueUpdatePromises[fieldName];
|
|
196
|
-
});
|
|
197
|
-
set((state) => {
|
|
198
|
-
const promise = new Promise((resolve) => {
|
|
199
|
-
state.controlledFields.valueUpdateResolvers[fieldName] = resolve;
|
|
200
|
-
}).then(clear);
|
|
201
|
-
state.controlledFields.valueUpdatePromises[fieldName] = promise;
|
|
202
|
-
});
|
|
203
|
-
},
|
|
204
|
-
awaitValueUpdate: async (fieldName) => {
|
|
205
|
-
await get().controlledFields.valueUpdatePromises[fieldName];
|
|
206
|
-
},
|
|
207
|
-
array: {
|
|
208
|
-
push: (fieldName, item) => {
|
|
209
|
-
set((state) => {
|
|
210
|
-
arrayUtil
|
|
211
|
-
.getArray(state.controlledFields.values, fieldName)
|
|
212
|
-
.push(item);
|
|
213
|
-
arrayUtil.getArray(state.currentDefaultValues, fieldName).push(item);
|
|
214
|
-
// New item added to the end, no need to update touched or error
|
|
215
|
-
});
|
|
216
|
-
get().controlledFields.kickoffValueUpdate(fieldName);
|
|
217
|
-
},
|
|
218
|
-
swap: (fieldName, indexA, indexB) => {
|
|
219
|
-
set((state) => {
|
|
220
|
-
arrayUtil.swap(arrayUtil.getArray(state.controlledFields.values, fieldName), indexA, indexB);
|
|
221
|
-
arrayUtil.swap(arrayUtil.getArray(state.currentDefaultValues, fieldName), indexA, indexB);
|
|
222
|
-
arrayUtil.mutateAsArray(fieldName, state.touchedFields, (array) => arrayUtil.swap(array, indexA, indexB));
|
|
223
|
-
arrayUtil.mutateAsArray(fieldName, state.fieldErrors, (array) => arrayUtil.swap(array, indexA, indexB));
|
|
224
|
-
});
|
|
225
|
-
get().controlledFields.kickoffValueUpdate(fieldName);
|
|
226
|
-
},
|
|
227
|
-
move: (fieldName, from, to) => {
|
|
228
|
-
set((state) => {
|
|
229
|
-
arrayUtil.move(arrayUtil.getArray(state.controlledFields.values, fieldName), from, to);
|
|
230
|
-
arrayUtil.move(arrayUtil.getArray(state.currentDefaultValues, fieldName), from, to);
|
|
231
|
-
arrayUtil.mutateAsArray(fieldName, state.touchedFields, (array) => arrayUtil.move(array, from, to));
|
|
232
|
-
arrayUtil.mutateAsArray(fieldName, state.fieldErrors, (array) => arrayUtil.move(array, from, to));
|
|
233
|
-
});
|
|
234
|
-
get().controlledFields.kickoffValueUpdate(fieldName);
|
|
235
|
-
},
|
|
236
|
-
insert: (fieldName, index, item) => {
|
|
237
|
-
set((state) => {
|
|
238
|
-
arrayUtil.insert(arrayUtil.getArray(state.controlledFields.values, fieldName), index, item);
|
|
239
|
-
arrayUtil.insert(arrayUtil.getArray(state.currentDefaultValues, fieldName), index, item);
|
|
240
|
-
// Even though this is a new item, we need to push around other items.
|
|
241
|
-
arrayUtil.mutateAsArray(fieldName, state.touchedFields, (array) => arrayUtil.insert(array, index, false));
|
|
242
|
-
arrayUtil.mutateAsArray(fieldName, state.fieldErrors, (array) => arrayUtil.insert(array, index, undefined));
|
|
243
|
-
});
|
|
244
|
-
get().controlledFields.kickoffValueUpdate(fieldName);
|
|
245
|
-
},
|
|
246
|
-
remove: (fieldName, index) => {
|
|
247
|
-
set((state) => {
|
|
248
|
-
arrayUtil.remove(arrayUtil.getArray(state.controlledFields.values, fieldName), index);
|
|
249
|
-
arrayUtil.remove(arrayUtil.getArray(state.currentDefaultValues, fieldName), index);
|
|
250
|
-
arrayUtil.mutateAsArray(fieldName, state.touchedFields, (array) => arrayUtil.remove(array, index));
|
|
251
|
-
arrayUtil.mutateAsArray(fieldName, state.fieldErrors, (array) => arrayUtil.remove(array, index));
|
|
252
|
-
});
|
|
253
|
-
get().controlledFields.kickoffValueUpdate(fieldName);
|
|
254
|
-
},
|
|
255
|
-
pop: (fieldName) => {
|
|
256
|
-
set((state) => {
|
|
257
|
-
arrayUtil.getArray(state.controlledFields.values, fieldName).pop();
|
|
258
|
-
arrayUtil.getArray(state.currentDefaultValues, fieldName).pop();
|
|
259
|
-
arrayUtil.mutateAsArray(fieldName, state.touchedFields, (array) => array.pop());
|
|
260
|
-
arrayUtil.mutateAsArray(fieldName, state.fieldErrors, (array) => array.pop());
|
|
261
|
-
});
|
|
262
|
-
get().controlledFields.kickoffValueUpdate(fieldName);
|
|
263
|
-
},
|
|
264
|
-
unshift: (fieldName, value) => {
|
|
265
|
-
set((state) => {
|
|
266
|
-
arrayUtil
|
|
267
|
-
.getArray(state.controlledFields.values, fieldName)
|
|
268
|
-
.unshift(value);
|
|
269
|
-
arrayUtil
|
|
270
|
-
.getArray(state.currentDefaultValues, fieldName)
|
|
271
|
-
.unshift(value);
|
|
272
|
-
arrayUtil.mutateAsArray(fieldName, state.touchedFields, (array) => array.unshift(false));
|
|
273
|
-
arrayUtil.mutateAsArray(fieldName, state.fieldErrors, (array) => array.unshift(undefined));
|
|
274
|
-
});
|
|
275
|
-
},
|
|
276
|
-
replace: (fieldName, index, item) => {
|
|
277
|
-
set((state) => {
|
|
278
|
-
arrayUtil.replace(arrayUtil.getArray(state.controlledFields.values, fieldName), index, item);
|
|
279
|
-
arrayUtil.replace(arrayUtil.getArray(state.currentDefaultValues, fieldName), index, item);
|
|
280
|
-
arrayUtil.mutateAsArray(fieldName, state.touchedFields, (array) => arrayUtil.replace(array, index, item));
|
|
281
|
-
arrayUtil.mutateAsArray(fieldName, state.fieldErrors, (array) => arrayUtil.replace(array, index, item));
|
|
282
|
-
});
|
|
283
|
-
get().controlledFields.kickoffValueUpdate(fieldName);
|
|
284
|
-
},
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
});
|
|
288
|
-
export const useRootFormStore = create()(immer((set, get) => ({
|
|
289
|
-
forms: {},
|
|
290
|
-
form: (formId) => {
|
|
291
|
-
var _a;
|
|
292
|
-
return (_a = get().forms[formId]) !== null && _a !== void 0 ? _a : defaultFormState;
|
|
293
|
-
},
|
|
294
|
-
cleanupForm: (formId) => {
|
|
295
|
-
set((state) => {
|
|
296
|
-
delete state.forms[formId];
|
|
297
|
-
});
|
|
298
|
-
},
|
|
299
|
-
registerForm: (formId) => {
|
|
300
|
-
if (get().forms[formId])
|
|
301
|
-
return;
|
|
302
|
-
set((state) => {
|
|
303
|
-
state.forms[formId] = createFormState((setter) => set((state) => setter(state.forms[formId])), () => get().forms[formId]);
|
|
304
|
-
});
|
|
305
|
-
},
|
|
306
|
-
})));
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
export type FieldArrayValidationBehavior = "onChange" | "onSubmit";
|
|
3
|
-
export type FieldArrayValidationBehaviorOptions = {
|
|
4
|
-
initial: FieldArrayValidationBehavior;
|
|
5
|
-
whenSubmitted: FieldArrayValidationBehavior;
|
|
6
|
-
};
|
|
7
|
-
export type FieldArrayHelpers<Item = any> = {
|
|
8
|
-
push: (item: Item) => void;
|
|
9
|
-
swap: (indexA: number, indexB: number) => void;
|
|
10
|
-
move: (from: number, to: number) => void;
|
|
11
|
-
insert: (index: number, value: Item) => void;
|
|
12
|
-
unshift: (value: Item) => void;
|
|
13
|
-
remove: (index: number) => void;
|
|
14
|
-
pop: () => void;
|
|
15
|
-
replace: (index: number, value: Item) => void;
|
|
16
|
-
};
|
|
17
|
-
export type UseFieldArrayOptions = {
|
|
18
|
-
formId?: string;
|
|
19
|
-
validationBehavior?: Partial<FieldArrayValidationBehaviorOptions>;
|
|
20
|
-
};
|
|
21
|
-
export declare function useFieldArray<Item = any>(name: string, { formId, validationBehavior }?: UseFieldArrayOptions): [itemDefaults: Item[], helpers: FieldArrayHelpers<any>, error: string | undefined];
|
|
22
|
-
export type FieldArrayProps = {
|
|
23
|
-
name: string;
|
|
24
|
-
children: (itemDefaults: any[], helpers: FieldArrayHelpers, error: string | undefined) => React.ReactNode;
|
|
25
|
-
formId?: string;
|
|
26
|
-
validationBehavior?: FieldArrayValidationBehaviorOptions;
|
|
27
|
-
};
|
|
28
|
-
export declare const FieldArray: ({ name, children, formId, validationBehavior, }: FieldArrayProps) => JSX.Element;
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
import { useCallback } from "react";
|
|
4
|
-
import invariant from "tiny-invariant";
|
|
5
|
-
import { useFieldDefaultValue, useFieldError, useInternalFormContext, useInternalHasBeenSubmitted, useValidateField, } from "../hooks";
|
|
6
|
-
import { useRegisterControlledField } from "./controlledFields";
|
|
7
|
-
import { useFormStore } from "./storeHooks";
|
|
8
|
-
const useInternalFieldArray = (context, field, validationBehavior) => {
|
|
9
|
-
const value = useFieldDefaultValue(field, context);
|
|
10
|
-
useRegisterControlledField(context, field);
|
|
11
|
-
const hasBeenSubmitted = useInternalHasBeenSubmitted(context.formId);
|
|
12
|
-
const validateField = useValidateField(context.formId);
|
|
13
|
-
const error = useFieldError(field, context);
|
|
14
|
-
const resolvedValidationBehavior = {
|
|
15
|
-
initial: "onSubmit",
|
|
16
|
-
whenSubmitted: "onChange",
|
|
17
|
-
...validationBehavior,
|
|
18
|
-
};
|
|
19
|
-
const behavior = hasBeenSubmitted
|
|
20
|
-
? resolvedValidationBehavior.whenSubmitted
|
|
21
|
-
: resolvedValidationBehavior.initial;
|
|
22
|
-
const maybeValidate = useCallback(() => {
|
|
23
|
-
if (behavior === "onChange") {
|
|
24
|
-
validateField(field);
|
|
25
|
-
}
|
|
26
|
-
}, [behavior, field, validateField]);
|
|
27
|
-
invariant(value === undefined || value === null || Array.isArray(value), `FieldArray: defaultValue value for ${field} must be an array, null, or undefined`);
|
|
28
|
-
const arr = useFormStore(context.formId, (state) => state.controlledFields.array);
|
|
29
|
-
const helpers = useMemo(() => ({
|
|
30
|
-
push: (item) => {
|
|
31
|
-
arr.push(field, item);
|
|
32
|
-
maybeValidate();
|
|
33
|
-
},
|
|
34
|
-
swap: (indexA, indexB) => {
|
|
35
|
-
arr.swap(field, indexA, indexB);
|
|
36
|
-
maybeValidate();
|
|
37
|
-
},
|
|
38
|
-
move: (from, to) => {
|
|
39
|
-
arr.move(field, from, to);
|
|
40
|
-
maybeValidate();
|
|
41
|
-
},
|
|
42
|
-
insert: (index, value) => {
|
|
43
|
-
arr.insert(field, index, value);
|
|
44
|
-
maybeValidate();
|
|
45
|
-
},
|
|
46
|
-
unshift: (value) => {
|
|
47
|
-
arr.unshift(field, value);
|
|
48
|
-
maybeValidate();
|
|
49
|
-
},
|
|
50
|
-
remove: (index) => {
|
|
51
|
-
arr.remove(field, index);
|
|
52
|
-
maybeValidate();
|
|
53
|
-
},
|
|
54
|
-
pop: () => {
|
|
55
|
-
arr.pop(field);
|
|
56
|
-
maybeValidate();
|
|
57
|
-
},
|
|
58
|
-
replace: (index, value) => {
|
|
59
|
-
arr.replace(field, index, value);
|
|
60
|
-
maybeValidate();
|
|
61
|
-
},
|
|
62
|
-
}), [arr, field, maybeValidate]);
|
|
63
|
-
const arrayValue = useMemo(() => value !== null && value !== void 0 ? value : [], [value]);
|
|
64
|
-
return [arrayValue, helpers, error];
|
|
65
|
-
};
|
|
66
|
-
export function useFieldArray(name, { formId, validationBehavior } = {}) {
|
|
67
|
-
const context = useInternalFormContext(formId, "FieldArray");
|
|
68
|
-
return useInternalFieldArray(context, name, validationBehavior);
|
|
69
|
-
}
|
|
70
|
-
export const FieldArray = ({ name, children, formId, validationBehavior, }) => {
|
|
71
|
-
const context = useInternalFormContext(formId, "FieldArray");
|
|
72
|
-
const [value, helpers, error] = useInternalFieldArray(context, name, validationBehavior);
|
|
73
|
-
return _jsx(_Fragment, { children: children(value, helpers, error) });
|
|
74
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is basically what `atomFamily` from jotai does,
|
|
3
|
-
* but it doesn't make sense to include the entire jotai library just for that api.
|
|
4
|
-
*/
|
|
5
|
-
export declare type InternalFormId = string | symbol;
|
|
6
|
-
export declare const storeFamily: <T>(create: (formId: InternalFormId) => T) => {
|
|
7
|
-
(formId: InternalFormId): T;
|
|
8
|
-
remove(formId: InternalFormId): void;
|
|
9
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is basically what `atomFamily` from jotai does,
|
|
3
|
-
* but it doesn't make sense to include the entire jotai library just for that api.
|
|
4
|
-
*/
|
|
5
|
-
export const storeFamily = (create) => {
|
|
6
|
-
const stores = new Map();
|
|
7
|
-
const family = (formId) => {
|
|
8
|
-
if (stores.has(formId))
|
|
9
|
-
return stores.get(formId);
|
|
10
|
-
const store = create(formId);
|
|
11
|
-
stores.set(formId, store);
|
|
12
|
-
return store;
|
|
13
|
-
};
|
|
14
|
-
family.remove = (formId) => {
|
|
15
|
-
stores.delete(formId);
|
|
16
|
-
};
|
|
17
|
-
return family;
|
|
18
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type InternalFormId = string | symbol;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|