@conform-to/react 1.18.0 → 1.19.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/future/dom.js +6 -2
- package/dist/future/dom.mjs +6 -2
- package/dist/future/forms.d.ts +1157 -26
- package/dist/future/forms.js +152 -23
- package/dist/future/forms.mjs +150 -26
- package/dist/future/hooks.d.ts +25 -164
- package/dist/future/hooks.js +34 -355
- package/dist/future/hooks.mjs +39 -352
- package/dist/future/index.d.ts +3 -3
- package/dist/future/index.js +5 -6
- package/dist/future/index.mjs +2 -2
- package/dist/future/intent.js +24 -12
- package/dist/future/intent.mjs +24 -12
- package/dist/future/memoize.d.ts +1 -1
- package/dist/future/memoize.js +1 -1
- package/dist/future/memoize.mjs +1 -1
- package/dist/future/state.d.ts +8 -12
- package/dist/future/state.js +24 -27
- package/dist/future/state.mjs +25 -28
- package/dist/future/types.d.ts +66 -111
- package/dist/future/util.d.ts +6 -10
- package/dist/future/util.js +17 -20
- package/dist/future/util.mjs +16 -19
- package/dist/helpers.d.ts +14 -10
- package/dist/helpers.js +14 -10
- package/dist/helpers.mjs +14 -10
- package/package.json +2 -2
package/dist/future/forms.js
CHANGED
|
@@ -14,14 +14,18 @@ var util = require('./util.js');
|
|
|
14
14
|
var jsxRuntime = require('react/jsx-runtime');
|
|
15
15
|
|
|
16
16
|
function configureForms() {
|
|
17
|
-
var _config$intentName, _config$
|
|
17
|
+
var _config$intentName, _config$shouldValidat, _ref, _config$shouldRevalid, _config$isSchema, _config$validateSchem;
|
|
18
18
|
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
19
|
+
/**
|
|
20
|
+
* Global serializer that composes the user-provided serializer with the default serializer.
|
|
21
|
+
*/
|
|
22
|
+
var globalSerialize = util.resolveSerialize(config.serialize, future.defaultSerialize);
|
|
23
|
+
|
|
19
24
|
/**
|
|
20
25
|
* Global configuration with defaults applied
|
|
21
26
|
*/
|
|
22
27
|
var globalConfig = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, config), {}, {
|
|
23
28
|
intentName: (_config$intentName = config.intentName) !== null && _config$intentName !== void 0 ? _config$intentName : future.DEFAULT_INTENT_NAME,
|
|
24
|
-
serialize: (_config$serialize = config.serialize) !== null && _config$serialize !== void 0 ? _config$serialize : future.serialize,
|
|
25
29
|
shouldValidate: (_config$shouldValidat = config.shouldValidate) !== null && _config$shouldValidat !== void 0 ? _config$shouldValidat : 'onSubmit',
|
|
26
30
|
shouldRevalidate: (_ref = (_config$shouldRevalid = config.shouldRevalidate) !== null && _config$shouldRevalid !== void 0 ? _config$shouldRevalid : config.shouldValidate) !== null && _ref !== void 0 ? _ref : 'onSubmit',
|
|
27
31
|
isSchema: (_config$isSchema = config.isSchema) !== null && _config$isSchema !== void 0 ? _config$isSchema : util.isStandardSchemaV1,
|
|
@@ -64,8 +68,9 @@ function configureForms() {
|
|
|
64
68
|
* - **Schema first**: Pass a schema as the first argument for automatic validation with type inference
|
|
65
69
|
* - **Manual configuration**: Pass options with custom `onValidate` handler for manual validation
|
|
66
70
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
71
|
+
* See https://conform.guide/api/react/future/useForm
|
|
72
|
+
*
|
|
73
|
+
* **Schema first setup with zod:**
|
|
69
74
|
*
|
|
70
75
|
* ```tsx
|
|
71
76
|
* const { form, fields } = useForm(zodSchema, {
|
|
@@ -81,13 +86,13 @@ function configureForms() {
|
|
|
81
86
|
* );
|
|
82
87
|
* ```
|
|
83
88
|
*
|
|
84
|
-
*
|
|
89
|
+
* **Manual configuration setup with custom validation:**
|
|
85
90
|
*
|
|
86
91
|
* ```tsx
|
|
87
92
|
* const { form, fields } = useForm({
|
|
88
|
-
*
|
|
93
|
+
* onValidate({ payload, error }) {
|
|
89
94
|
* if (!payload.email) {
|
|
90
|
-
*
|
|
95
|
+
* error.fieldErrors.email = ['Required'];
|
|
91
96
|
* }
|
|
92
97
|
* return error;
|
|
93
98
|
* }
|
|
@@ -102,10 +107,6 @@ function configureForms() {
|
|
|
102
107
|
* ```
|
|
103
108
|
*/
|
|
104
109
|
|
|
105
|
-
/**
|
|
106
|
-
* @deprecated Use `useForm(schema, options)` instead for better type inference.
|
|
107
|
-
*/
|
|
108
|
-
|
|
109
110
|
function useForm(schemaOrOptions, maybeOptions) {
|
|
110
111
|
var _options$constraint, _globalConfig$getCons, _options$id, _options$onError;
|
|
111
112
|
var schema;
|
|
@@ -118,10 +119,11 @@ function configureForms() {
|
|
|
118
119
|
}
|
|
119
120
|
var constraint = (_options$constraint = options.constraint) !== null && _options$constraint !== void 0 ? _options$constraint : schema ? (_globalConfig$getCons = globalConfig.getConstraints) === null || _globalConfig$getCons === void 0 ? void 0 : _globalConfig$getCons.call(globalConfig, schema) : undefined;
|
|
120
121
|
var optionsRef = hooks.useLatest(options);
|
|
122
|
+
var serialize = react.useMemo(() => util.resolveSerialize(options.serialize, globalSerialize), [options.serialize]);
|
|
121
123
|
var fallbackId = react.useId();
|
|
122
124
|
var formId = (_options$id = options.id) !== null && _options$id !== void 0 ? _options$id : "form-".concat(fallbackId);
|
|
123
125
|
var [state$1, handleSubmit] = hooks.useConform(formId, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, options), {}, {
|
|
124
|
-
serialize
|
|
126
|
+
serialize,
|
|
125
127
|
intentName: globalConfig.intentName,
|
|
126
128
|
onError: (_options$onError = options.onError) !== null && _options$onError !== void 0 ? _options$onError : dom.focusFirstInvalidField,
|
|
127
129
|
onValidate(ctx) {
|
|
@@ -172,6 +174,7 @@ function configureForms() {
|
|
|
172
174
|
var context = react.useMemo(() => ({
|
|
173
175
|
formId,
|
|
174
176
|
state: state$1,
|
|
177
|
+
serialize,
|
|
175
178
|
constraint: constraint !== null && constraint !== void 0 ? constraint : null,
|
|
176
179
|
handleSubmit,
|
|
177
180
|
handleInput(event) {
|
|
@@ -210,14 +213,12 @@ function configureForms() {
|
|
|
210
213
|
intent.validate(event.target.name);
|
|
211
214
|
}
|
|
212
215
|
}
|
|
213
|
-
}), [formId, state$1, constraint, handleSubmit, intent, optionsRef]);
|
|
216
|
+
}), [formId, state$1, serialize, constraint, handleSubmit, intent, optionsRef]);
|
|
214
217
|
var form = react.useMemo(() => state.getFormMetadata(context, {
|
|
215
|
-
serialize: globalConfig.serialize,
|
|
216
218
|
extendFormMetadata: globalConfig.extendFormMetadata,
|
|
217
219
|
extendFieldMetadata: globalConfig.extendFieldMetadata
|
|
218
220
|
}), [context]);
|
|
219
221
|
var fields = react.useMemo(() => state.getFieldset(context, {
|
|
220
|
-
serialize: globalConfig.serialize,
|
|
221
222
|
extendFieldMetadata: globalConfig.extendFieldMetadata
|
|
222
223
|
}), [context]);
|
|
223
224
|
return {
|
|
@@ -231,8 +232,9 @@ function configureForms() {
|
|
|
231
232
|
* A React hook that provides access to form-level metadata and state.
|
|
232
233
|
* Requires `FormProvider` context when used in child components.
|
|
233
234
|
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
235
|
+
* See https://conform.guide/api/react/future/useFormMetadata
|
|
236
|
+
*
|
|
237
|
+
* **Example:**
|
|
236
238
|
* ```tsx
|
|
237
239
|
* function ErrorSummary() {
|
|
238
240
|
* const form = useFormMetadata();
|
|
@@ -249,7 +251,6 @@ function configureForms() {
|
|
|
249
251
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
250
252
|
var context = useFormContext(options.formId);
|
|
251
253
|
var formMetadata = react.useMemo(() => state.getFormMetadata(context, {
|
|
252
|
-
serialize: globalConfig.serialize,
|
|
253
254
|
extendFormMetadata: globalConfig.extendFormMetadata,
|
|
254
255
|
extendFieldMetadata: globalConfig.extendFieldMetadata
|
|
255
256
|
}), [context]);
|
|
@@ -260,8 +261,9 @@ function configureForms() {
|
|
|
260
261
|
* A React hook that provides access to a specific field's metadata and state.
|
|
261
262
|
* Requires `FormProvider` context when used in child components.
|
|
262
263
|
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
264
|
+
* See https://conform.guide/api/react/future/useField
|
|
265
|
+
*
|
|
266
|
+
* **Example:**
|
|
265
267
|
* ```tsx
|
|
266
268
|
* function FormField({ name, label }) {
|
|
267
269
|
* const field = useField(name);
|
|
@@ -281,7 +283,6 @@ function configureForms() {
|
|
|
281
283
|
var context = useFormContext(options.formId);
|
|
282
284
|
var field = react.useMemo(() => state.getField(context, {
|
|
283
285
|
name,
|
|
284
|
-
serialize: globalConfig.serialize,
|
|
285
286
|
extendFieldMetadata: globalConfig.extendFieldMetadata
|
|
286
287
|
}), [context, name]);
|
|
287
288
|
return field;
|
|
@@ -292,8 +293,9 @@ function configureForms() {
|
|
|
292
293
|
* Intent dispatchers allow you to trigger form operations like validation, field updates,
|
|
293
294
|
* and array manipulations without manual form submission.
|
|
294
295
|
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
296
|
+
* See https://conform.guide/api/react/future/useIntent
|
|
297
|
+
*
|
|
298
|
+
* **Example:**
|
|
297
299
|
* ```tsx
|
|
298
300
|
* function ResetButton() {
|
|
299
301
|
* const buttonRef = useRef<HTMLButtonElement>(null);
|
|
@@ -319,5 +321,132 @@ function configureForms() {
|
|
|
319
321
|
config: globalConfig
|
|
320
322
|
};
|
|
321
323
|
}
|
|
324
|
+
var defaultForms = configureForms();
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Provides form context to child components.
|
|
328
|
+
* Stacks contexts to support nested forms, with latest context taking priority.
|
|
329
|
+
*/
|
|
330
|
+
var FormProvider = defaultForms.FormProvider;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* The main React hook for form management. Handles form state, validation, and submission
|
|
334
|
+
* while providing access to form metadata, field objects, and form actions.
|
|
335
|
+
*
|
|
336
|
+
* It can be called in two ways:
|
|
337
|
+
* - **Schema first**: Pass a schema as the first argument for automatic validation with type inference
|
|
338
|
+
* - **Manual configuration**: Pass options with custom `onValidate` handler for manual validation
|
|
339
|
+
*
|
|
340
|
+
* See https://conform.guide/api/react/future/useForm
|
|
341
|
+
*
|
|
342
|
+
* **Schema first setup with zod:**
|
|
343
|
+
*
|
|
344
|
+
* ```tsx
|
|
345
|
+
* const { form, fields } = useForm(zodSchema, {
|
|
346
|
+
* lastResult,
|
|
347
|
+
* shouldValidate: 'onBlur',
|
|
348
|
+
* });
|
|
349
|
+
*
|
|
350
|
+
* return (
|
|
351
|
+
* <form {...form.props}>
|
|
352
|
+
* <input name={fields.email.name} defaultValue={fields.email.defaultValue} />
|
|
353
|
+
* <div>{fields.email.errors}</div>
|
|
354
|
+
* </form>
|
|
355
|
+
* );
|
|
356
|
+
* ```
|
|
357
|
+
*
|
|
358
|
+
* **Manual configuration setup with custom validation:**
|
|
359
|
+
*
|
|
360
|
+
* ```tsx
|
|
361
|
+
* const { form, fields } = useForm({
|
|
362
|
+
* onValidate({ payload, error }) {
|
|
363
|
+
* if (!payload.email) {
|
|
364
|
+
* error.fieldErrors.email = ['Required'];
|
|
365
|
+
* }
|
|
366
|
+
* return error;
|
|
367
|
+
* }
|
|
368
|
+
* });
|
|
369
|
+
*
|
|
370
|
+
* return (
|
|
371
|
+
* <form {...form.props}>
|
|
372
|
+
* <input name={fields.email.name} defaultValue={fields.email.defaultValue} />
|
|
373
|
+
* <div>{fields.email.errors}</div>
|
|
374
|
+
* </form>
|
|
375
|
+
* );
|
|
376
|
+
* ```
|
|
377
|
+
*/
|
|
378
|
+
var useForm = defaultForms.useForm;
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* A React hook that provides access to form-level metadata and state.
|
|
382
|
+
* Requires `FormProvider` context when used in child components.
|
|
383
|
+
*
|
|
384
|
+
* See https://conform.guide/api/react/future/useFormMetadata
|
|
385
|
+
*
|
|
386
|
+
* **Example:**
|
|
387
|
+
* ```tsx
|
|
388
|
+
* function ErrorSummary() {
|
|
389
|
+
* const form = useFormMetadata();
|
|
390
|
+
*
|
|
391
|
+
* if (form.valid) return null;
|
|
392
|
+
*
|
|
393
|
+
* return (
|
|
394
|
+
* <div>Please fix {Object.keys(form.fieldErrors).length} errors</div>
|
|
395
|
+
* );
|
|
396
|
+
* }
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
var useFormMetadata = defaultForms.useFormMetadata;
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* A React hook that provides access to a specific field's metadata and state.
|
|
403
|
+
* Requires `FormProvider` context when used in child components.
|
|
404
|
+
*
|
|
405
|
+
* See https://conform.guide/api/react/future/useField
|
|
406
|
+
*
|
|
407
|
+
* **Example:**
|
|
408
|
+
* ```tsx
|
|
409
|
+
* function FormField({ name, label }) {
|
|
410
|
+
* const field = useField(name);
|
|
411
|
+
*
|
|
412
|
+
* return (
|
|
413
|
+
* <div>
|
|
414
|
+
* <label htmlFor={field.id}>{label}</label>
|
|
415
|
+
* <input id={field.id} name={field.name} defaultValue={field.defaultValue} />
|
|
416
|
+
* {field.errors && <div>{field.errors.join(', ')}</div>}
|
|
417
|
+
* </div>
|
|
418
|
+
* );
|
|
419
|
+
* }
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
var useField = defaultForms.useField;
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* A React hook that provides an intent dispatcher for programmatic form actions.
|
|
426
|
+
* Intent dispatchers allow you to trigger form operations like validation, field updates,
|
|
427
|
+
* and array manipulations without manual form submission.
|
|
428
|
+
*
|
|
429
|
+
* See https://conform.guide/api/react/future/useIntent
|
|
430
|
+
*
|
|
431
|
+
* **Example:**
|
|
432
|
+
* ```tsx
|
|
433
|
+
* function ResetButton() {
|
|
434
|
+
* const buttonRef = useRef<HTMLButtonElement>(null);
|
|
435
|
+
* const intent = useIntent(buttonRef);
|
|
436
|
+
*
|
|
437
|
+
* return (
|
|
438
|
+
* <button type="button" ref={buttonRef} onClick={() => intent.reset()}>
|
|
439
|
+
* Reset Form
|
|
440
|
+
* </button>
|
|
441
|
+
* );
|
|
442
|
+
* }
|
|
443
|
+
* ```
|
|
444
|
+
*/
|
|
445
|
+
var useIntent = defaultForms.useIntent;
|
|
322
446
|
|
|
447
|
+
exports.FormProvider = FormProvider;
|
|
323
448
|
exports.configureForms = configureForms;
|
|
449
|
+
exports.useField = useField;
|
|
450
|
+
exports.useForm = useForm;
|
|
451
|
+
exports.useFormMetadata = useFormMetadata;
|
|
452
|
+
exports.useIntent = useIntent;
|
package/dist/future/forms.mjs
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { objectSpread2 as _objectSpread2 } from '../_virtual/_rollupPluginBabelHelpers.mjs';
|
|
3
3
|
import { isFieldElement } from '@conform-to/dom';
|
|
4
|
-
import { DEFAULT_INTENT_NAME,
|
|
4
|
+
import { DEFAULT_INTENT_NAME, defaultSerialize } from '@conform-to/dom/future';
|
|
5
5
|
import { useContext, useMemo, useId, createContext } from 'react';
|
|
6
6
|
import { focusFirstInvalidField, getFormElement, createIntentDispatcher } from './dom.mjs';
|
|
7
7
|
import { useLatest, useConform } from './hooks.mjs';
|
|
8
8
|
import { isTouched, getFormMetadata, getFieldset, getField } from './state.mjs';
|
|
9
|
-
import { isStandardSchemaV1, validateStandardSchemaV1, resolveValidateResult } from './util.mjs';
|
|
9
|
+
import { resolveSerialize, isStandardSchemaV1, validateStandardSchemaV1, resolveValidateResult } from './util.mjs';
|
|
10
10
|
import { jsx } from 'react/jsx-runtime';
|
|
11
11
|
|
|
12
12
|
function configureForms() {
|
|
13
|
-
var _config$intentName, _config$
|
|
13
|
+
var _config$intentName, _config$shouldValidat, _ref, _config$shouldRevalid, _config$isSchema, _config$validateSchem;
|
|
14
14
|
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
15
|
+
/**
|
|
16
|
+
* Global serializer that composes the user-provided serializer with the default serializer.
|
|
17
|
+
*/
|
|
18
|
+
var globalSerialize = resolveSerialize(config.serialize, defaultSerialize);
|
|
19
|
+
|
|
15
20
|
/**
|
|
16
21
|
* Global configuration with defaults applied
|
|
17
22
|
*/
|
|
18
23
|
var globalConfig = _objectSpread2(_objectSpread2({}, config), {}, {
|
|
19
24
|
intentName: (_config$intentName = config.intentName) !== null && _config$intentName !== void 0 ? _config$intentName : DEFAULT_INTENT_NAME,
|
|
20
|
-
serialize: (_config$serialize = config.serialize) !== null && _config$serialize !== void 0 ? _config$serialize : serialize,
|
|
21
25
|
shouldValidate: (_config$shouldValidat = config.shouldValidate) !== null && _config$shouldValidat !== void 0 ? _config$shouldValidat : 'onSubmit',
|
|
22
26
|
shouldRevalidate: (_ref = (_config$shouldRevalid = config.shouldRevalidate) !== null && _config$shouldRevalid !== void 0 ? _config$shouldRevalid : config.shouldValidate) !== null && _ref !== void 0 ? _ref : 'onSubmit',
|
|
23
27
|
isSchema: (_config$isSchema = config.isSchema) !== null && _config$isSchema !== void 0 ? _config$isSchema : isStandardSchemaV1,
|
|
@@ -60,8 +64,9 @@ function configureForms() {
|
|
|
60
64
|
* - **Schema first**: Pass a schema as the first argument for automatic validation with type inference
|
|
61
65
|
* - **Manual configuration**: Pass options with custom `onValidate` handler for manual validation
|
|
62
66
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
67
|
+
* See https://conform.guide/api/react/future/useForm
|
|
68
|
+
*
|
|
69
|
+
* **Schema first setup with zod:**
|
|
65
70
|
*
|
|
66
71
|
* ```tsx
|
|
67
72
|
* const { form, fields } = useForm(zodSchema, {
|
|
@@ -77,13 +82,13 @@ function configureForms() {
|
|
|
77
82
|
* );
|
|
78
83
|
* ```
|
|
79
84
|
*
|
|
80
|
-
*
|
|
85
|
+
* **Manual configuration setup with custom validation:**
|
|
81
86
|
*
|
|
82
87
|
* ```tsx
|
|
83
88
|
* const { form, fields } = useForm({
|
|
84
|
-
*
|
|
89
|
+
* onValidate({ payload, error }) {
|
|
85
90
|
* if (!payload.email) {
|
|
86
|
-
*
|
|
91
|
+
* error.fieldErrors.email = ['Required'];
|
|
87
92
|
* }
|
|
88
93
|
* return error;
|
|
89
94
|
* }
|
|
@@ -98,10 +103,6 @@ function configureForms() {
|
|
|
98
103
|
* ```
|
|
99
104
|
*/
|
|
100
105
|
|
|
101
|
-
/**
|
|
102
|
-
* @deprecated Use `useForm(schema, options)` instead for better type inference.
|
|
103
|
-
*/
|
|
104
|
-
|
|
105
106
|
function useForm(schemaOrOptions, maybeOptions) {
|
|
106
107
|
var _options$constraint, _globalConfig$getCons, _options$id, _options$onError;
|
|
107
108
|
var schema;
|
|
@@ -114,10 +115,11 @@ function configureForms() {
|
|
|
114
115
|
}
|
|
115
116
|
var constraint = (_options$constraint = options.constraint) !== null && _options$constraint !== void 0 ? _options$constraint : schema ? (_globalConfig$getCons = globalConfig.getConstraints) === null || _globalConfig$getCons === void 0 ? void 0 : _globalConfig$getCons.call(globalConfig, schema) : undefined;
|
|
116
117
|
var optionsRef = useLatest(options);
|
|
118
|
+
var serialize = useMemo(() => resolveSerialize(options.serialize, globalSerialize), [options.serialize]);
|
|
117
119
|
var fallbackId = useId();
|
|
118
120
|
var formId = (_options$id = options.id) !== null && _options$id !== void 0 ? _options$id : "form-".concat(fallbackId);
|
|
119
121
|
var [state, handleSubmit] = useConform(formId, _objectSpread2(_objectSpread2({}, options), {}, {
|
|
120
|
-
serialize
|
|
122
|
+
serialize,
|
|
121
123
|
intentName: globalConfig.intentName,
|
|
122
124
|
onError: (_options$onError = options.onError) !== null && _options$onError !== void 0 ? _options$onError : focusFirstInvalidField,
|
|
123
125
|
onValidate(ctx) {
|
|
@@ -168,6 +170,7 @@ function configureForms() {
|
|
|
168
170
|
var context = useMemo(() => ({
|
|
169
171
|
formId,
|
|
170
172
|
state,
|
|
173
|
+
serialize,
|
|
171
174
|
constraint: constraint !== null && constraint !== void 0 ? constraint : null,
|
|
172
175
|
handleSubmit,
|
|
173
176
|
handleInput(event) {
|
|
@@ -206,14 +209,12 @@ function configureForms() {
|
|
|
206
209
|
intent.validate(event.target.name);
|
|
207
210
|
}
|
|
208
211
|
}
|
|
209
|
-
}), [formId, state, constraint, handleSubmit, intent, optionsRef]);
|
|
212
|
+
}), [formId, state, serialize, constraint, handleSubmit, intent, optionsRef]);
|
|
210
213
|
var form = useMemo(() => getFormMetadata(context, {
|
|
211
|
-
serialize: globalConfig.serialize,
|
|
212
214
|
extendFormMetadata: globalConfig.extendFormMetadata,
|
|
213
215
|
extendFieldMetadata: globalConfig.extendFieldMetadata
|
|
214
216
|
}), [context]);
|
|
215
217
|
var fields = useMemo(() => getFieldset(context, {
|
|
216
|
-
serialize: globalConfig.serialize,
|
|
217
218
|
extendFieldMetadata: globalConfig.extendFieldMetadata
|
|
218
219
|
}), [context]);
|
|
219
220
|
return {
|
|
@@ -227,8 +228,9 @@ function configureForms() {
|
|
|
227
228
|
* A React hook that provides access to form-level metadata and state.
|
|
228
229
|
* Requires `FormProvider` context when used in child components.
|
|
229
230
|
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
231
|
+
* See https://conform.guide/api/react/future/useFormMetadata
|
|
232
|
+
*
|
|
233
|
+
* **Example:**
|
|
232
234
|
* ```tsx
|
|
233
235
|
* function ErrorSummary() {
|
|
234
236
|
* const form = useFormMetadata();
|
|
@@ -245,7 +247,6 @@ function configureForms() {
|
|
|
245
247
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
246
248
|
var context = useFormContext(options.formId);
|
|
247
249
|
var formMetadata = useMemo(() => getFormMetadata(context, {
|
|
248
|
-
serialize: globalConfig.serialize,
|
|
249
250
|
extendFormMetadata: globalConfig.extendFormMetadata,
|
|
250
251
|
extendFieldMetadata: globalConfig.extendFieldMetadata
|
|
251
252
|
}), [context]);
|
|
@@ -256,8 +257,9 @@ function configureForms() {
|
|
|
256
257
|
* A React hook that provides access to a specific field's metadata and state.
|
|
257
258
|
* Requires `FormProvider` context when used in child components.
|
|
258
259
|
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
260
|
+
* See https://conform.guide/api/react/future/useField
|
|
261
|
+
*
|
|
262
|
+
* **Example:**
|
|
261
263
|
* ```tsx
|
|
262
264
|
* function FormField({ name, label }) {
|
|
263
265
|
* const field = useField(name);
|
|
@@ -277,7 +279,6 @@ function configureForms() {
|
|
|
277
279
|
var context = useFormContext(options.formId);
|
|
278
280
|
var field = useMemo(() => getField(context, {
|
|
279
281
|
name,
|
|
280
|
-
serialize: globalConfig.serialize,
|
|
281
282
|
extendFieldMetadata: globalConfig.extendFieldMetadata
|
|
282
283
|
}), [context, name]);
|
|
283
284
|
return field;
|
|
@@ -288,8 +289,9 @@ function configureForms() {
|
|
|
288
289
|
* Intent dispatchers allow you to trigger form operations like validation, field updates,
|
|
289
290
|
* and array manipulations without manual form submission.
|
|
290
291
|
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
292
|
+
* See https://conform.guide/api/react/future/useIntent
|
|
293
|
+
*
|
|
294
|
+
* **Example:**
|
|
293
295
|
* ```tsx
|
|
294
296
|
* function ResetButton() {
|
|
295
297
|
* const buttonRef = useRef<HTMLButtonElement>(null);
|
|
@@ -315,5 +317,127 @@ function configureForms() {
|
|
|
315
317
|
config: globalConfig
|
|
316
318
|
};
|
|
317
319
|
}
|
|
320
|
+
var defaultForms = configureForms();
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Provides form context to child components.
|
|
324
|
+
* Stacks contexts to support nested forms, with latest context taking priority.
|
|
325
|
+
*/
|
|
326
|
+
var FormProvider = defaultForms.FormProvider;
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* The main React hook for form management. Handles form state, validation, and submission
|
|
330
|
+
* while providing access to form metadata, field objects, and form actions.
|
|
331
|
+
*
|
|
332
|
+
* It can be called in two ways:
|
|
333
|
+
* - **Schema first**: Pass a schema as the first argument for automatic validation with type inference
|
|
334
|
+
* - **Manual configuration**: Pass options with custom `onValidate` handler for manual validation
|
|
335
|
+
*
|
|
336
|
+
* See https://conform.guide/api/react/future/useForm
|
|
337
|
+
*
|
|
338
|
+
* **Schema first setup with zod:**
|
|
339
|
+
*
|
|
340
|
+
* ```tsx
|
|
341
|
+
* const { form, fields } = useForm(zodSchema, {
|
|
342
|
+
* lastResult,
|
|
343
|
+
* shouldValidate: 'onBlur',
|
|
344
|
+
* });
|
|
345
|
+
*
|
|
346
|
+
* return (
|
|
347
|
+
* <form {...form.props}>
|
|
348
|
+
* <input name={fields.email.name} defaultValue={fields.email.defaultValue} />
|
|
349
|
+
* <div>{fields.email.errors}</div>
|
|
350
|
+
* </form>
|
|
351
|
+
* );
|
|
352
|
+
* ```
|
|
353
|
+
*
|
|
354
|
+
* **Manual configuration setup with custom validation:**
|
|
355
|
+
*
|
|
356
|
+
* ```tsx
|
|
357
|
+
* const { form, fields } = useForm({
|
|
358
|
+
* onValidate({ payload, error }) {
|
|
359
|
+
* if (!payload.email) {
|
|
360
|
+
* error.fieldErrors.email = ['Required'];
|
|
361
|
+
* }
|
|
362
|
+
* return error;
|
|
363
|
+
* }
|
|
364
|
+
* });
|
|
365
|
+
*
|
|
366
|
+
* return (
|
|
367
|
+
* <form {...form.props}>
|
|
368
|
+
* <input name={fields.email.name} defaultValue={fields.email.defaultValue} />
|
|
369
|
+
* <div>{fields.email.errors}</div>
|
|
370
|
+
* </form>
|
|
371
|
+
* );
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
var useForm = defaultForms.useForm;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* A React hook that provides access to form-level metadata and state.
|
|
378
|
+
* Requires `FormProvider` context when used in child components.
|
|
379
|
+
*
|
|
380
|
+
* See https://conform.guide/api/react/future/useFormMetadata
|
|
381
|
+
*
|
|
382
|
+
* **Example:**
|
|
383
|
+
* ```tsx
|
|
384
|
+
* function ErrorSummary() {
|
|
385
|
+
* const form = useFormMetadata();
|
|
386
|
+
*
|
|
387
|
+
* if (form.valid) return null;
|
|
388
|
+
*
|
|
389
|
+
* return (
|
|
390
|
+
* <div>Please fix {Object.keys(form.fieldErrors).length} errors</div>
|
|
391
|
+
* );
|
|
392
|
+
* }
|
|
393
|
+
* ```
|
|
394
|
+
*/
|
|
395
|
+
var useFormMetadata = defaultForms.useFormMetadata;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* A React hook that provides access to a specific field's metadata and state.
|
|
399
|
+
* Requires `FormProvider` context when used in child components.
|
|
400
|
+
*
|
|
401
|
+
* See https://conform.guide/api/react/future/useField
|
|
402
|
+
*
|
|
403
|
+
* **Example:**
|
|
404
|
+
* ```tsx
|
|
405
|
+
* function FormField({ name, label }) {
|
|
406
|
+
* const field = useField(name);
|
|
407
|
+
*
|
|
408
|
+
* return (
|
|
409
|
+
* <div>
|
|
410
|
+
* <label htmlFor={field.id}>{label}</label>
|
|
411
|
+
* <input id={field.id} name={field.name} defaultValue={field.defaultValue} />
|
|
412
|
+
* {field.errors && <div>{field.errors.join(', ')}</div>}
|
|
413
|
+
* </div>
|
|
414
|
+
* );
|
|
415
|
+
* }
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
418
|
+
var useField = defaultForms.useField;
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* A React hook that provides an intent dispatcher for programmatic form actions.
|
|
422
|
+
* Intent dispatchers allow you to trigger form operations like validation, field updates,
|
|
423
|
+
* and array manipulations without manual form submission.
|
|
424
|
+
*
|
|
425
|
+
* See https://conform.guide/api/react/future/useIntent
|
|
426
|
+
*
|
|
427
|
+
* **Example:**
|
|
428
|
+
* ```tsx
|
|
429
|
+
* function ResetButton() {
|
|
430
|
+
* const buttonRef = useRef<HTMLButtonElement>(null);
|
|
431
|
+
* const intent = useIntent(buttonRef);
|
|
432
|
+
*
|
|
433
|
+
* return (
|
|
434
|
+
* <button type="button" ref={buttonRef} onClick={() => intent.reset()}>
|
|
435
|
+
* Reset Form
|
|
436
|
+
* </button>
|
|
437
|
+
* );
|
|
438
|
+
* }
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
var useIntent = defaultForms.useIntent;
|
|
318
442
|
|
|
319
|
-
export { configureForms };
|
|
443
|
+
export { FormProvider, configureForms, useField, useForm, useFormMetadata, useIntent };
|