@conform-to/react 1.15.1 → 1.17.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 +1 -1
- package/dist/context.js +1 -0
- package/dist/context.mjs +1 -0
- package/dist/future/dom.d.ts +10 -0
- package/dist/future/dom.js +126 -0
- package/dist/future/dom.mjs +125 -1
- package/dist/future/forms.d.ts +43 -0
- package/dist/future/forms.js +323 -0
- package/dist/future/forms.mjs +319 -0
- package/dist/future/hooks.d.ts +44 -4
- package/dist/future/hooks.js +96 -34
- package/dist/future/hooks.mjs +100 -39
- package/dist/future/index.d.ts +4 -2
- package/dist/future/index.js +5 -0
- package/dist/future/index.mjs +3 -1
- package/dist/future/intent.d.ts +13 -6
- package/dist/future/intent.js +175 -68
- package/dist/future/intent.mjs +175 -69
- package/dist/future/state.d.ts +30 -14
- package/dist/future/state.js +44 -38
- package/dist/future/state.mjs +46 -40
- package/dist/future/types.d.ts +310 -36
- package/dist/future/util.d.ts +44 -1
- package/dist/future/util.js +67 -5
- package/dist/future/util.mjs +64 -6
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +2 -1
- package/dist/helpers.mjs +2 -1
- package/dist/integrations.d.ts +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
Version 1.
|
|
10
|
+
Version 1.17.0 / License MIT / Copyright (c) 2025 Edmund Hung
|
|
11
11
|
|
|
12
12
|
Progressively enhance HTML forms with React. Build resilient, type-safe forms with no hassle using web standards.
|
|
13
13
|
|
package/dist/context.js
CHANGED
|
@@ -189,6 +189,7 @@ function getFieldMetadata(context, subjectRef, stateSnapshot) {
|
|
|
189
189
|
case 'pattern':
|
|
190
190
|
case 'step':
|
|
191
191
|
case 'multiple':
|
|
192
|
+
case 'accept':
|
|
192
193
|
return (_state$constraint$nam = state.constraint[name]) === null || _state$constraint$nam === void 0 ? void 0 : _state$constraint$nam[key];
|
|
193
194
|
case 'getFieldList':
|
|
194
195
|
{
|
package/dist/context.mjs
CHANGED
|
@@ -185,6 +185,7 @@ function getFieldMetadata(context, subjectRef, stateSnapshot) {
|
|
|
185
185
|
case 'pattern':
|
|
186
186
|
case 'step':
|
|
187
187
|
case 'multiple':
|
|
188
|
+
case 'accept':
|
|
188
189
|
return (_state$constraint$nam = state.constraint[name]) === null || _state$constraint$nam === void 0 ? void 0 : _state$constraint$nam[key];
|
|
189
190
|
case 'getFieldList':
|
|
190
191
|
{
|
package/dist/future/dom.d.ts
CHANGED
|
@@ -34,4 +34,14 @@ export declare function resetFormValue(form: HTMLFormElement, defaultValue: Reco
|
|
|
34
34
|
* Each property access returns a function that submits the intent to the form.
|
|
35
35
|
*/
|
|
36
36
|
export declare function createIntentDispatcher<FormShape extends Record<string, any>>(formElement: HTMLFormElement | (() => HTMLFormElement | null), intentName: string): IntentDispatcher<FormShape>;
|
|
37
|
+
/**
|
|
38
|
+
* Restores values from preserved inputs and removes them.
|
|
39
|
+
* Called when PreserveBoundary mounts.
|
|
40
|
+
*/
|
|
41
|
+
export declare function cleanupPreservedInputs(boundary: HTMLElement, form: HTMLFormElement, name?: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Clones inputs as hidden elements to preserve their values.
|
|
44
|
+
* Called when PreserveBoundary unmounts.
|
|
45
|
+
*/
|
|
46
|
+
export declare function preserveInputs(inputs: Iterable<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>, form: HTMLFormElement, name?: string): void;
|
|
37
47
|
//# sourceMappingURL=dom.d.ts.map
|
package/dist/future/dom.js
CHANGED
|
@@ -237,7 +237,132 @@ function createIntentDispatcher(formElement, intentName) {
|
|
|
237
237
|
}
|
|
238
238
|
});
|
|
239
239
|
}
|
|
240
|
+
var PERSIST_ATTR = 'data-conform-persist';
|
|
241
|
+
var containerCache = new WeakMap();
|
|
240
242
|
|
|
243
|
+
/**
|
|
244
|
+
* Gets or creates a hidden container for persisted inputs.
|
|
245
|
+
* Using a container div instead of appending directly to <form> provides ~10x
|
|
246
|
+
* better performance (form.elements bookkeeping is expensive at scale).
|
|
247
|
+
*/
|
|
248
|
+
function getPersistContainer(form) {
|
|
249
|
+
var container = containerCache.get(form);
|
|
250
|
+
|
|
251
|
+
// Verify container is still attached to the form
|
|
252
|
+
if (container && container.parentNode !== form) {
|
|
253
|
+
container = undefined;
|
|
254
|
+
}
|
|
255
|
+
if (!container) {
|
|
256
|
+
container = form.ownerDocument.createElement('div');
|
|
257
|
+
container.setAttribute(PERSIST_ATTR, '');
|
|
258
|
+
container.hidden = true;
|
|
259
|
+
form.appendChild(container);
|
|
260
|
+
containerCache.set(form, container);
|
|
261
|
+
}
|
|
262
|
+
return container;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Restores values from preserved inputs and removes them.
|
|
267
|
+
* Called when PreserveBoundary mounts.
|
|
268
|
+
*/
|
|
269
|
+
function cleanupPreservedInputs(boundary, form, name) {
|
|
270
|
+
var inputs = boundary.querySelectorAll('input,select,textarea');
|
|
271
|
+
var container = getPersistContainer(form);
|
|
272
|
+
for (var input of inputs) {
|
|
273
|
+
if (!future.isFieldElement(input) || !input.name) {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// For checkbox/radio, match by field name + value (+ boundary name if provided)
|
|
278
|
+
// For other inputs, match by field name only (+ boundary name if provided)
|
|
279
|
+
var isCheckboxOrRadio = input.type === 'checkbox' || input.type === 'radio';
|
|
280
|
+
|
|
281
|
+
// Query the persist container, not the whole form
|
|
282
|
+
var boundarySelector = name ? "[".concat(PERSIST_ATTR, "=\"").concat(name, "\"]") : '';
|
|
283
|
+
var selector = isCheckboxOrRadio ? "".concat(boundarySelector, "[name=\"").concat(input.name, "\"][value=\"").concat(input.value, "\"]") : "".concat(boundarySelector, "[name=\"").concat(input.name, "\"]");
|
|
284
|
+
var persisted = container.querySelector(selector);
|
|
285
|
+
if (persisted) {
|
|
286
|
+
if (input instanceof HTMLInputElement && persisted instanceof HTMLInputElement) {
|
|
287
|
+
if (isCheckboxOrRadio) {
|
|
288
|
+
input.checked = persisted.checked;
|
|
289
|
+
} else if (input.type === 'file') {
|
|
290
|
+
// Restore files from the persisted input (may be empty)
|
|
291
|
+
input.files = persisted.files;
|
|
292
|
+
} else {
|
|
293
|
+
input.value = persisted.value;
|
|
294
|
+
}
|
|
295
|
+
} else if (input instanceof HTMLSelectElement && persisted instanceof HTMLSelectElement) {
|
|
296
|
+
var _loop = function _loop(option) {
|
|
297
|
+
var _persistedOption$sele;
|
|
298
|
+
var persistedOption = Array.from(persisted.options).find(o => o.value === option.value);
|
|
299
|
+
option.selected = (_persistedOption$sele = persistedOption === null || persistedOption === void 0 ? void 0 : persistedOption.selected) !== null && _persistedOption$sele !== void 0 ? _persistedOption$sele : false;
|
|
300
|
+
};
|
|
301
|
+
for (var option of input.options) {
|
|
302
|
+
_loop(option);
|
|
303
|
+
}
|
|
304
|
+
} else if (input instanceof HTMLTextAreaElement && persisted instanceof HTMLTextAreaElement) {
|
|
305
|
+
input.value = persisted.value;
|
|
306
|
+
}
|
|
307
|
+
persisted.remove();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// If name is provided, remove any remaining persisted inputs with this name
|
|
312
|
+
// (handles the case where inputs were removed from the boundary)
|
|
313
|
+
if (name) {
|
|
314
|
+
var remainingPersisted = container.querySelectorAll("[".concat(PERSIST_ATTR, "=\"").concat(name, "\"]"));
|
|
315
|
+
remainingPersisted.forEach(el => el.remove());
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Clones inputs as hidden elements to preserve their values.
|
|
321
|
+
* Called when PreserveBoundary unmounts.
|
|
322
|
+
*/
|
|
323
|
+
function preserveInputs(inputs, form, name) {
|
|
324
|
+
// Get the persist container once, outside the loop
|
|
325
|
+
var container = getPersistContainer(form);
|
|
326
|
+
for (var input of inputs) {
|
|
327
|
+
if (!future.isFieldElement(input) || !input.name) {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Skip unchecked checkbox/radio (they don't contribute to FormData)
|
|
332
|
+
if (input instanceof HTMLInputElement && (input.type === 'checkbox' || input.type === 'radio') && !input.checked) {
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Clone the input element
|
|
337
|
+
var clone = input.cloneNode(true);
|
|
338
|
+
|
|
339
|
+
// Mark with name if provided, and hide it
|
|
340
|
+
if (name) {
|
|
341
|
+
clone.setAttribute(PERSIST_ATTR, name);
|
|
342
|
+
}
|
|
343
|
+
clone.hidden = true;
|
|
344
|
+
|
|
345
|
+
// Copy dynamic state that cloneNode doesn't preserve
|
|
346
|
+
if (input instanceof HTMLSelectElement) {
|
|
347
|
+
// cloneNode doesn't copy selected state for options
|
|
348
|
+
for (var i = 0; i < input.options.length; i++) {
|
|
349
|
+
var inputOption = input.options[i];
|
|
350
|
+
var cloneOption = clone.options[i];
|
|
351
|
+
if (inputOption && cloneOption) {
|
|
352
|
+
cloneOption.selected = inputOption.selected;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
} else if (input instanceof HTMLInputElement && input.type === 'file') {
|
|
356
|
+
// cloneNode doesn't copy files
|
|
357
|
+
clone.files = input.files;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Append to persist container (faster than appending directly to form)
|
|
361
|
+
container.appendChild(clone);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
exports.cleanupPreservedInputs = cleanupPreservedInputs;
|
|
241
366
|
exports.createDefaultSnapshot = createDefaultSnapshot;
|
|
242
367
|
exports.createIntentDispatcher = createIntentDispatcher;
|
|
243
368
|
exports.focusFirstInvalidField = focusFirstInvalidField;
|
|
@@ -248,5 +373,6 @@ exports.getRadioGroupValue = getRadioGroupValue;
|
|
|
248
373
|
exports.getSubmitEvent = getSubmitEvent;
|
|
249
374
|
exports.initializeField = initializeField;
|
|
250
375
|
exports.makeInputFocusable = makeInputFocusable;
|
|
376
|
+
exports.preserveInputs = preserveInputs;
|
|
251
377
|
exports.resetFormValue = resetFormValue;
|
|
252
378
|
exports.updateFormValue = updateFormValue;
|
package/dist/future/dom.mjs
CHANGED
|
@@ -233,5 +233,129 @@ function createIntentDispatcher(formElement, intentName) {
|
|
|
233
233
|
}
|
|
234
234
|
});
|
|
235
235
|
}
|
|
236
|
+
var PERSIST_ATTR = 'data-conform-persist';
|
|
237
|
+
var containerCache = new WeakMap();
|
|
236
238
|
|
|
237
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Gets or creates a hidden container for persisted inputs.
|
|
241
|
+
* Using a container div instead of appending directly to <form> provides ~10x
|
|
242
|
+
* better performance (form.elements bookkeeping is expensive at scale).
|
|
243
|
+
*/
|
|
244
|
+
function getPersistContainer(form) {
|
|
245
|
+
var container = containerCache.get(form);
|
|
246
|
+
|
|
247
|
+
// Verify container is still attached to the form
|
|
248
|
+
if (container && container.parentNode !== form) {
|
|
249
|
+
container = undefined;
|
|
250
|
+
}
|
|
251
|
+
if (!container) {
|
|
252
|
+
container = form.ownerDocument.createElement('div');
|
|
253
|
+
container.setAttribute(PERSIST_ATTR, '');
|
|
254
|
+
container.hidden = true;
|
|
255
|
+
form.appendChild(container);
|
|
256
|
+
containerCache.set(form, container);
|
|
257
|
+
}
|
|
258
|
+
return container;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Restores values from preserved inputs and removes them.
|
|
263
|
+
* Called when PreserveBoundary mounts.
|
|
264
|
+
*/
|
|
265
|
+
function cleanupPreservedInputs(boundary, form, name) {
|
|
266
|
+
var inputs = boundary.querySelectorAll('input,select,textarea');
|
|
267
|
+
var container = getPersistContainer(form);
|
|
268
|
+
for (var input of inputs) {
|
|
269
|
+
if (!isFieldElement(input) || !input.name) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// For checkbox/radio, match by field name + value (+ boundary name if provided)
|
|
274
|
+
// For other inputs, match by field name only (+ boundary name if provided)
|
|
275
|
+
var isCheckboxOrRadio = input.type === 'checkbox' || input.type === 'radio';
|
|
276
|
+
|
|
277
|
+
// Query the persist container, not the whole form
|
|
278
|
+
var boundarySelector = name ? "[".concat(PERSIST_ATTR, "=\"").concat(name, "\"]") : '';
|
|
279
|
+
var selector = isCheckboxOrRadio ? "".concat(boundarySelector, "[name=\"").concat(input.name, "\"][value=\"").concat(input.value, "\"]") : "".concat(boundarySelector, "[name=\"").concat(input.name, "\"]");
|
|
280
|
+
var persisted = container.querySelector(selector);
|
|
281
|
+
if (persisted) {
|
|
282
|
+
if (input instanceof HTMLInputElement && persisted instanceof HTMLInputElement) {
|
|
283
|
+
if (isCheckboxOrRadio) {
|
|
284
|
+
input.checked = persisted.checked;
|
|
285
|
+
} else if (input.type === 'file') {
|
|
286
|
+
// Restore files from the persisted input (may be empty)
|
|
287
|
+
input.files = persisted.files;
|
|
288
|
+
} else {
|
|
289
|
+
input.value = persisted.value;
|
|
290
|
+
}
|
|
291
|
+
} else if (input instanceof HTMLSelectElement && persisted instanceof HTMLSelectElement) {
|
|
292
|
+
var _loop = function _loop(option) {
|
|
293
|
+
var _persistedOption$sele;
|
|
294
|
+
var persistedOption = Array.from(persisted.options).find(o => o.value === option.value);
|
|
295
|
+
option.selected = (_persistedOption$sele = persistedOption === null || persistedOption === void 0 ? void 0 : persistedOption.selected) !== null && _persistedOption$sele !== void 0 ? _persistedOption$sele : false;
|
|
296
|
+
};
|
|
297
|
+
for (var option of input.options) {
|
|
298
|
+
_loop(option);
|
|
299
|
+
}
|
|
300
|
+
} else if (input instanceof HTMLTextAreaElement && persisted instanceof HTMLTextAreaElement) {
|
|
301
|
+
input.value = persisted.value;
|
|
302
|
+
}
|
|
303
|
+
persisted.remove();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// If name is provided, remove any remaining persisted inputs with this name
|
|
308
|
+
// (handles the case where inputs were removed from the boundary)
|
|
309
|
+
if (name) {
|
|
310
|
+
var remainingPersisted = container.querySelectorAll("[".concat(PERSIST_ATTR, "=\"").concat(name, "\"]"));
|
|
311
|
+
remainingPersisted.forEach(el => el.remove());
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Clones inputs as hidden elements to preserve their values.
|
|
317
|
+
* Called when PreserveBoundary unmounts.
|
|
318
|
+
*/
|
|
319
|
+
function preserveInputs(inputs, form, name) {
|
|
320
|
+
// Get the persist container once, outside the loop
|
|
321
|
+
var container = getPersistContainer(form);
|
|
322
|
+
for (var input of inputs) {
|
|
323
|
+
if (!isFieldElement(input) || !input.name) {
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Skip unchecked checkbox/radio (they don't contribute to FormData)
|
|
328
|
+
if (input instanceof HTMLInputElement && (input.type === 'checkbox' || input.type === 'radio') && !input.checked) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Clone the input element
|
|
333
|
+
var clone = input.cloneNode(true);
|
|
334
|
+
|
|
335
|
+
// Mark with name if provided, and hide it
|
|
336
|
+
if (name) {
|
|
337
|
+
clone.setAttribute(PERSIST_ATTR, name);
|
|
338
|
+
}
|
|
339
|
+
clone.hidden = true;
|
|
340
|
+
|
|
341
|
+
// Copy dynamic state that cloneNode doesn't preserve
|
|
342
|
+
if (input instanceof HTMLSelectElement) {
|
|
343
|
+
// cloneNode doesn't copy selected state for options
|
|
344
|
+
for (var i = 0; i < input.options.length; i++) {
|
|
345
|
+
var inputOption = input.options[i];
|
|
346
|
+
var cloneOption = clone.options[i];
|
|
347
|
+
if (inputOption && cloneOption) {
|
|
348
|
+
cloneOption.selected = inputOption.selected;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
} else if (input instanceof HTMLInputElement && input.type === 'file') {
|
|
352
|
+
// cloneNode doesn't copy files
|
|
353
|
+
clone.files = input.files;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Append to persist container (faster than appending directly to form)
|
|
357
|
+
container.appendChild(clone);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export { cleanupPreservedInputs, createDefaultSnapshot, createIntentDispatcher, focusFirstInvalidField, getCheckboxGroupValue, getFormElement, getInputSnapshot, getRadioGroupValue, getSubmitEvent, initializeField, makeInputFocusable, preserveInputs, resetFormValue, updateFormValue };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FieldName } from '@conform-to/dom';
|
|
2
|
+
import { StandardSchemaV1 } from './standard-schema';
|
|
3
|
+
import { FormRef, FormsConfig, FormContext, FormMetadata, FormOptions, Fieldset, FieldMetadata, InferOutput, InferInput, IntentDispatcher } from './types';
|
|
4
|
+
export declare function configureForms<BaseErrorShape = string, BaseSchema = StandardSchemaV1, CustomFormMetadata extends Record<string, unknown> = {}, CustomFieldMetadata extends Record<string, unknown> = {}>(config?: Partial<FormsConfig<BaseErrorShape, BaseSchema, CustomFormMetadata, CustomFieldMetadata>>): {
|
|
5
|
+
FormProvider: (props: {
|
|
6
|
+
context: FormContext<BaseErrorShape>;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}) => React.ReactElement;
|
|
9
|
+
useForm: {
|
|
10
|
+
<Schema extends BaseSchema, ErrorShape extends BaseErrorShape = BaseErrorShape, Value = InferOutput<Schema>>(schema: Schema, options: FormOptions<InferInput<Schema> extends Record<string, any> ? InferInput<Schema> : never, ErrorShape, Value, Schema, string extends ErrorShape ? never : "onValidate">): {
|
|
11
|
+
form: FormMetadata<ErrorShape, CustomFormMetadata, CustomFieldMetadata>;
|
|
12
|
+
fields: Fieldset<InferInput<Schema>, ErrorShape, CustomFieldMetadata>;
|
|
13
|
+
intent: IntentDispatcher<InferInput<Schema> extends Record<string, any> ? InferInput<Schema> : never>;
|
|
14
|
+
};
|
|
15
|
+
<FormShape extends Record<string, any> = Record<string, any>, ErrorShape extends BaseErrorShape = BaseErrorShape, Value = undefined>(options: FormOptions<FormShape, ErrorShape, Value, undefined, undefined extends Value ? "onValidate" : never> & {
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Use `useForm(schema, options)` instead for better type inference.
|
|
18
|
+
*
|
|
19
|
+
* Optional standard schema for validation (e.g., Zod, Valibot, Yup).
|
|
20
|
+
* Removes the need for manual onValidate setup.
|
|
21
|
+
*/
|
|
22
|
+
schema: StandardSchemaV1<FormShape, Value>;
|
|
23
|
+
}): {
|
|
24
|
+
form: FormMetadata<ErrorShape, CustomFormMetadata, CustomFieldMetadata>;
|
|
25
|
+
fields: Fieldset<FormShape, ErrorShape, CustomFieldMetadata>;
|
|
26
|
+
intent: IntentDispatcher<FormShape>;
|
|
27
|
+
};
|
|
28
|
+
<FormShape extends Record<string, any> = Record<string, any>, ErrorShape extends BaseErrorShape = BaseErrorShape, Value = undefined>(options: FormOptions<FormShape, ErrorShape, Value, undefined, "onValidate">): {
|
|
29
|
+
form: FormMetadata<ErrorShape, CustomFormMetadata, CustomFieldMetadata>;
|
|
30
|
+
fields: Fieldset<FormShape, ErrorShape, CustomFieldMetadata>;
|
|
31
|
+
intent: IntentDispatcher<FormShape>;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
useFormMetadata: (options?: {
|
|
35
|
+
formId?: string;
|
|
36
|
+
}) => FormMetadata<BaseErrorShape, CustomFormMetadata, CustomFieldMetadata>;
|
|
37
|
+
useField: <FieldShape = any>(name: FieldName<FieldShape>, options?: {
|
|
38
|
+
formId?: string;
|
|
39
|
+
}) => FieldMetadata<FieldShape, BaseErrorShape, CustomFieldMetadata>;
|
|
40
|
+
useIntent: <FormShape extends Record<string, any>>(formRef: FormRef) => IntentDispatcher<FormShape>;
|
|
41
|
+
config: FormsConfig<BaseErrorShape, BaseSchema, CustomFormMetadata, CustomFieldMetadata>;
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=forms.d.ts.map
|