@conform-to/react 0.7.3 → 0.7.4
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 +3 -3
- package/helpers.d.ts +11 -7
- package/helpers.js +36 -26
- package/helpers.mjs +36 -27
- package/hooks.js +12 -2
- package/hooks.mjs +12 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -156,7 +156,7 @@ function LoginForm() {
|
|
|
156
156
|
|
|
157
157
|
### useFieldset
|
|
158
158
|
|
|
159
|
-
This hook enables you to work with [nested object](/docs/
|
|
159
|
+
This hook enables you to work with [nested object](/docs/complex-structures.md#nested-object) by monitoring the state of each nested field and prepraing the config required.
|
|
160
160
|
|
|
161
161
|
```tsx
|
|
162
162
|
import { useForm, useFieldset } from '@conform-to/react';
|
|
@@ -238,7 +238,7 @@ function ExampleForm() {
|
|
|
238
238
|
|
|
239
239
|
### useFieldList
|
|
240
240
|
|
|
241
|
-
This hook enables you to work with [array](/docs/
|
|
241
|
+
This hook enables you to work with [array](/docs/complex-structures.md#array) and support the [list](#list) intent button builder to modify a list. It can also be used with [useFieldset](#usefieldset) for [nested list](/docs/complex-structures.md#nested-list) at the same time.
|
|
242
242
|
|
|
243
243
|
```tsx
|
|
244
244
|
import { useForm, useFieldList, list } from '@conform-to/react';
|
|
@@ -385,7 +385,7 @@ function Example() {
|
|
|
385
385
|
|
|
386
386
|
### parse
|
|
387
387
|
|
|
388
|
-
It parses the formData based on the [naming convention](/docs/
|
|
388
|
+
It parses the formData based on the [naming convention](/docs/complex-structures.md#naming-convention) with the validation result from the resolver.
|
|
389
389
|
|
|
390
390
|
```tsx
|
|
391
391
|
import { parse } from '@conform-to/react';
|
package/helpers.d.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { INTENT, VALIDATION_UNDEFINED, VALIDATION_SKIPPED } from '@conform-to/dom';
|
|
2
2
|
import type { FieldConfig, Primitive } from './hooks.js';
|
|
3
3
|
import type { CSSProperties, HTMLInputTypeAttribute } from 'react';
|
|
4
|
-
interface
|
|
4
|
+
interface FormElementProps {
|
|
5
5
|
id?: string;
|
|
6
6
|
name: string;
|
|
7
7
|
form?: string;
|
|
8
|
+
'aria-describedby'?: string;
|
|
9
|
+
'aria-invalid'?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface FormControlProps extends FormElementProps {
|
|
8
12
|
required?: boolean;
|
|
9
13
|
autoFocus?: boolean;
|
|
10
14
|
tabIndex?: number;
|
|
11
15
|
style?: CSSProperties;
|
|
12
|
-
'aria-describedby'?: string;
|
|
13
|
-
'aria-invalid'?: boolean;
|
|
14
16
|
'aria-hidden'?: boolean;
|
|
15
17
|
}
|
|
16
18
|
interface InputProps<Schema> extends FormControlProps {
|
|
@@ -37,13 +39,14 @@ interface TextareaProps extends FormControlProps {
|
|
|
37
39
|
}
|
|
38
40
|
type BaseOptions = {
|
|
39
41
|
ariaAttributes?: false;
|
|
40
|
-
hidden?: boolean;
|
|
41
42
|
} | {
|
|
42
43
|
ariaAttributes: true;
|
|
43
44
|
description?: boolean;
|
|
45
|
+
};
|
|
46
|
+
type ControlOptions = BaseOptions & {
|
|
44
47
|
hidden?: boolean;
|
|
45
48
|
};
|
|
46
|
-
type InputOptions =
|
|
49
|
+
type InputOptions = ControlOptions & ({
|
|
47
50
|
type: 'checkbox' | 'radio';
|
|
48
51
|
value?: string;
|
|
49
52
|
} | {
|
|
@@ -59,6 +62,7 @@ export declare function input<Schema extends Primitive | unknown>(config: FieldC
|
|
|
59
62
|
export declare function input<Schema extends File | File[]>(config: FieldConfig<Schema>, options: InputOptions & {
|
|
60
63
|
type: 'file';
|
|
61
64
|
}): InputProps<Schema>;
|
|
62
|
-
export declare function select<Schema extends Primitive | Primitive[] | undefined | unknown>(config: FieldConfig<Schema>, options?:
|
|
63
|
-
export declare function textarea<Schema extends Primitive | undefined | unknown>(config: FieldConfig<Schema>, options?:
|
|
65
|
+
export declare function select<Schema extends Primitive | Primitive[] | undefined | unknown>(config: FieldConfig<Schema>, options?: ControlOptions): SelectProps;
|
|
66
|
+
export declare function textarea<Schema extends Primitive | undefined | unknown>(config: FieldConfig<Schema>, options?: ControlOptions): TextareaProps;
|
|
67
|
+
export declare function fieldset<Schema extends Record<string, any> | undefined | unknown>(config: FieldConfig<Schema>, options?: BaseOptions): FormControlProps;
|
|
64
68
|
export { INTENT, VALIDATION_UNDEFINED, VALIDATION_SKIPPED };
|
package/helpers.js
CHANGED
|
@@ -5,26 +5,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
|
|
6
6
|
var dom = require('@conform-to/dom');
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
form: config.form,
|
|
13
|
-
required: config.required,
|
|
14
|
-
autoFocus: config.initialError && Object.entries(config.initialError).length > 0 ? true : undefined
|
|
15
|
-
};
|
|
16
|
-
if (options !== null && options !== void 0 && options.ariaAttributes) {
|
|
17
|
-
var _config$error;
|
|
18
|
-
if (config.descriptionId && options !== null && options !== void 0 && options.description) {
|
|
19
|
-
props['aria-describedby'] = config.descriptionId;
|
|
20
|
-
}
|
|
21
|
-
if (config.errorId && (_config$error = config.error) !== null && _config$error !== void 0 && _config$error.length) {
|
|
22
|
-
props['aria-invalid'] = true;
|
|
23
|
-
props['aria-describedby'] = config.descriptionId && options !== null && options !== void 0 && options.description ? "".concat(config.errorId, " ").concat(config.descriptionId) : config.errorId;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, props), options !== null && options !== void 0 && options.hidden ? hiddenProps : {});
|
|
27
|
-
}
|
|
8
|
+
/**
|
|
9
|
+
* Cleanup `undefined` from the dervied props
|
|
10
|
+
* To minimize conflicts when merging with user defined props
|
|
11
|
+
*/
|
|
28
12
|
function cleanup(props) {
|
|
29
13
|
for (var key in props) {
|
|
30
14
|
if (props[key] === undefined) {
|
|
@@ -33,6 +17,30 @@ function cleanup(props) {
|
|
|
33
17
|
}
|
|
34
18
|
return props;
|
|
35
19
|
}
|
|
20
|
+
function getFormElementProps(config, options) {
|
|
21
|
+
var _config$error, _config$error2;
|
|
22
|
+
return cleanup({
|
|
23
|
+
id: config.id,
|
|
24
|
+
name: config.name,
|
|
25
|
+
form: config.form,
|
|
26
|
+
'aria-invalid': options !== null && options !== void 0 && options.ariaAttributes && config.errorId && (_config$error = config.error) !== null && _config$error !== void 0 && _config$error.length ? true : undefined,
|
|
27
|
+
'aria-describedby': options !== null && options !== void 0 && options.ariaAttributes ? [config.errorId && (_config$error2 = config.error) !== null && _config$error2 !== void 0 && _config$error2.length ? config.errorId : undefined, config.descriptionId && options !== null && options !== void 0 && options.description ? config.descriptionId : undefined].reduce((result, id) => {
|
|
28
|
+
if (!result) {
|
|
29
|
+
return id;
|
|
30
|
+
}
|
|
31
|
+
if (!id) {
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
return "".concat(result, " ").concat(id);
|
|
35
|
+
}) : undefined
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function getFormControlProps(config, options) {
|
|
39
|
+
return cleanup(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormElementProps(config, options)), {}, {
|
|
40
|
+
required: config.required,
|
|
41
|
+
autoFocus: config.initialError && Object.entries(config.initialError).length > 0 ? true : undefined
|
|
42
|
+
}, options !== null && options !== void 0 && options.hidden ? hiddenProps : undefined));
|
|
43
|
+
}
|
|
36
44
|
var hiddenProps = {
|
|
37
45
|
/**
|
|
38
46
|
* Style to make the input element visually hidden
|
|
@@ -74,19 +82,20 @@ function input(config) {
|
|
|
74
82
|
return cleanup(props);
|
|
75
83
|
}
|
|
76
84
|
function select(config, options) {
|
|
77
|
-
|
|
85
|
+
return cleanup(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
|
|
78
86
|
defaultValue: config.defaultValue,
|
|
79
87
|
multiple: config.multiple
|
|
80
|
-
});
|
|
81
|
-
return cleanup(props);
|
|
88
|
+
}));
|
|
82
89
|
}
|
|
83
90
|
function textarea(config, options) {
|
|
84
|
-
|
|
91
|
+
return cleanup(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
|
|
85
92
|
defaultValue: config.defaultValue,
|
|
86
93
|
minLength: config.minLength,
|
|
87
94
|
maxLength: config.maxLength
|
|
88
|
-
});
|
|
89
|
-
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
function fieldset(config, options) {
|
|
98
|
+
return getFormElementProps(config, options);
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
Object.defineProperty(exports, 'INTENT', {
|
|
@@ -101,6 +110,7 @@ Object.defineProperty(exports, 'VALIDATION_UNDEFINED', {
|
|
|
101
110
|
enumerable: true,
|
|
102
111
|
get: function () { return dom.VALIDATION_UNDEFINED; }
|
|
103
112
|
});
|
|
113
|
+
exports.fieldset = fieldset;
|
|
104
114
|
exports.hiddenProps = hiddenProps;
|
|
105
115
|
exports.input = input;
|
|
106
116
|
exports.select = select;
|
package/helpers.mjs
CHANGED
|
@@ -1,26 +1,10 @@
|
|
|
1
1
|
import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
2
|
export { INTENT, VALIDATION_SKIPPED, VALIDATION_UNDEFINED } from '@conform-to/dom';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
form: config.form,
|
|
9
|
-
required: config.required,
|
|
10
|
-
autoFocus: config.initialError && Object.entries(config.initialError).length > 0 ? true : undefined
|
|
11
|
-
};
|
|
12
|
-
if (options !== null && options !== void 0 && options.ariaAttributes) {
|
|
13
|
-
var _config$error;
|
|
14
|
-
if (config.descriptionId && options !== null && options !== void 0 && options.description) {
|
|
15
|
-
props['aria-describedby'] = config.descriptionId;
|
|
16
|
-
}
|
|
17
|
-
if (config.errorId && (_config$error = config.error) !== null && _config$error !== void 0 && _config$error.length) {
|
|
18
|
-
props['aria-invalid'] = true;
|
|
19
|
-
props['aria-describedby'] = config.descriptionId && options !== null && options !== void 0 && options.description ? "".concat(config.errorId, " ").concat(config.descriptionId) : config.errorId;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return _objectSpread2(_objectSpread2({}, props), options !== null && options !== void 0 && options.hidden ? hiddenProps : {});
|
|
23
|
-
}
|
|
4
|
+
/**
|
|
5
|
+
* Cleanup `undefined` from the dervied props
|
|
6
|
+
* To minimize conflicts when merging with user defined props
|
|
7
|
+
*/
|
|
24
8
|
function cleanup(props) {
|
|
25
9
|
for (var key in props) {
|
|
26
10
|
if (props[key] === undefined) {
|
|
@@ -29,6 +13,30 @@ function cleanup(props) {
|
|
|
29
13
|
}
|
|
30
14
|
return props;
|
|
31
15
|
}
|
|
16
|
+
function getFormElementProps(config, options) {
|
|
17
|
+
var _config$error, _config$error2;
|
|
18
|
+
return cleanup({
|
|
19
|
+
id: config.id,
|
|
20
|
+
name: config.name,
|
|
21
|
+
form: config.form,
|
|
22
|
+
'aria-invalid': options !== null && options !== void 0 && options.ariaAttributes && config.errorId && (_config$error = config.error) !== null && _config$error !== void 0 && _config$error.length ? true : undefined,
|
|
23
|
+
'aria-describedby': options !== null && options !== void 0 && options.ariaAttributes ? [config.errorId && (_config$error2 = config.error) !== null && _config$error2 !== void 0 && _config$error2.length ? config.errorId : undefined, config.descriptionId && options !== null && options !== void 0 && options.description ? config.descriptionId : undefined].reduce((result, id) => {
|
|
24
|
+
if (!result) {
|
|
25
|
+
return id;
|
|
26
|
+
}
|
|
27
|
+
if (!id) {
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
return "".concat(result, " ").concat(id);
|
|
31
|
+
}) : undefined
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function getFormControlProps(config, options) {
|
|
35
|
+
return cleanup(_objectSpread2(_objectSpread2({}, getFormElementProps(config, options)), {}, {
|
|
36
|
+
required: config.required,
|
|
37
|
+
autoFocus: config.initialError && Object.entries(config.initialError).length > 0 ? true : undefined
|
|
38
|
+
}, options !== null && options !== void 0 && options.hidden ? hiddenProps : undefined));
|
|
39
|
+
}
|
|
32
40
|
var hiddenProps = {
|
|
33
41
|
/**
|
|
34
42
|
* Style to make the input element visually hidden
|
|
@@ -70,19 +78,20 @@ function input(config) {
|
|
|
70
78
|
return cleanup(props);
|
|
71
79
|
}
|
|
72
80
|
function select(config, options) {
|
|
73
|
-
|
|
81
|
+
return cleanup(_objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
|
|
74
82
|
defaultValue: config.defaultValue,
|
|
75
83
|
multiple: config.multiple
|
|
76
|
-
});
|
|
77
|
-
return cleanup(props);
|
|
84
|
+
}));
|
|
78
85
|
}
|
|
79
86
|
function textarea(config, options) {
|
|
80
|
-
|
|
87
|
+
return cleanup(_objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
|
|
81
88
|
defaultValue: config.defaultValue,
|
|
82
89
|
minLength: config.minLength,
|
|
83
90
|
maxLength: config.maxLength
|
|
84
|
-
});
|
|
85
|
-
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
function fieldset(config, options) {
|
|
94
|
+
return getFormElementProps(config, options);
|
|
86
95
|
}
|
|
87
96
|
|
|
88
|
-
export { hiddenProps, input, select, textarea };
|
|
97
|
+
export { fieldset, hiddenProps, input, select, textarea };
|
package/hooks.js
CHANGED
|
@@ -6,6 +6,10 @@ var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js
|
|
|
6
6
|
var dom = require('@conform-to/dom');
|
|
7
7
|
var react = require('react');
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Properties to be applied to the form element
|
|
11
|
+
*/
|
|
12
|
+
|
|
9
13
|
/**
|
|
10
14
|
* Normalize error to an array of string.
|
|
11
15
|
*/
|
|
@@ -302,6 +306,12 @@ function useForm() {
|
|
|
302
306
|
* A set of field configuration
|
|
303
307
|
*/
|
|
304
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Returns all the information about the fieldset.
|
|
311
|
+
*
|
|
312
|
+
* @see https://conform.guide/api/react#usefieldset
|
|
313
|
+
*/
|
|
314
|
+
|
|
305
315
|
function useFieldset(ref, config) {
|
|
306
316
|
var [error] = useFormError(ref, {
|
|
307
317
|
initialError: config.initialError,
|
|
@@ -488,7 +498,7 @@ function useInputEvent(options) {
|
|
|
488
498
|
if (listener !== 'onReset') {
|
|
489
499
|
eventDispatched.current[listener] = true;
|
|
490
500
|
}
|
|
491
|
-
(_optionsRef$current4 = optionsRef.current) === null || _optionsRef$current4 === void 0
|
|
501
|
+
(_optionsRef$current4 = optionsRef.current) === null || _optionsRef$current4 === void 0 || (_optionsRef$current4$ = _optionsRef$current4[listener]) === null || _optionsRef$current4$ === void 0 ? void 0 : _optionsRef$current4$.call(_optionsRef$current4, event);
|
|
492
502
|
}
|
|
493
503
|
};
|
|
494
504
|
};
|
|
@@ -662,7 +672,7 @@ function validateConstraint(options) {
|
|
|
662
672
|
constraint,
|
|
663
673
|
defaultErrors: getDefaultErrors(_element3.validity, constraint)
|
|
664
674
|
});
|
|
665
|
-
var shouldAcceptMultipleErrors = (_options$acceptMultip = options === null || options === void 0
|
|
675
|
+
var shouldAcceptMultipleErrors = (_options$acceptMultip = options === null || options === void 0 || (_options$acceptMultip2 = options.acceptMultipleErrors) === null || _options$acceptMultip2 === void 0 ? void 0 : _options$acceptMultip2.call(options, {
|
|
666
676
|
name,
|
|
667
677
|
payload,
|
|
668
678
|
intent
|
package/hooks.mjs
CHANGED
|
@@ -2,6 +2,10 @@ import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHe
|
|
|
2
2
|
import { parseIntent, getFormData, parse, VALIDATION_UNDEFINED, VALIDATION_SKIPPED, getFormAction, getFormEncType, getFormMethod, getPaths, getName, isFieldElement, getErrors, getFormControls, getFormElement, updateList, getValidationMessage, focusFirstInvalidControl, isFocusableFormControl, requestIntent, validate } from '@conform-to/dom';
|
|
3
3
|
import { useState, useMemo, useEffect, useRef, useCallback, useLayoutEffect } from 'react';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Properties to be applied to the form element
|
|
7
|
+
*/
|
|
8
|
+
|
|
5
9
|
/**
|
|
6
10
|
* Normalize error to an array of string.
|
|
7
11
|
*/
|
|
@@ -298,6 +302,12 @@ function useForm() {
|
|
|
298
302
|
* A set of field configuration
|
|
299
303
|
*/
|
|
300
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Returns all the information about the fieldset.
|
|
307
|
+
*
|
|
308
|
+
* @see https://conform.guide/api/react#usefieldset
|
|
309
|
+
*/
|
|
310
|
+
|
|
301
311
|
function useFieldset(ref, config) {
|
|
302
312
|
var [error] = useFormError(ref, {
|
|
303
313
|
initialError: config.initialError,
|
|
@@ -484,7 +494,7 @@ function useInputEvent(options) {
|
|
|
484
494
|
if (listener !== 'onReset') {
|
|
485
495
|
eventDispatched.current[listener] = true;
|
|
486
496
|
}
|
|
487
|
-
(_optionsRef$current4 = optionsRef.current) === null || _optionsRef$current4 === void 0
|
|
497
|
+
(_optionsRef$current4 = optionsRef.current) === null || _optionsRef$current4 === void 0 || (_optionsRef$current4$ = _optionsRef$current4[listener]) === null || _optionsRef$current4$ === void 0 ? void 0 : _optionsRef$current4$.call(_optionsRef$current4, event);
|
|
488
498
|
}
|
|
489
499
|
};
|
|
490
500
|
};
|
|
@@ -658,7 +668,7 @@ function validateConstraint(options) {
|
|
|
658
668
|
constraint,
|
|
659
669
|
defaultErrors: getDefaultErrors(_element3.validity, constraint)
|
|
660
670
|
});
|
|
661
|
-
var shouldAcceptMultipleErrors = (_options$acceptMultip = options === null || options === void 0
|
|
671
|
+
var shouldAcceptMultipleErrors = (_options$acceptMultip = options === null || options === void 0 || (_options$acceptMultip2 = options.acceptMultipleErrors) === null || _options$acceptMultip2 === void 0 ? void 0 : _options$acceptMultip2.call(options, {
|
|
662
672
|
name,
|
|
663
673
|
payload,
|
|
664
674
|
intent
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Conform view adapter for react",
|
|
4
4
|
"homepage": "https://conform.guide",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "0.7.
|
|
6
|
+
"version": "0.7.4",
|
|
7
7
|
"main": "index.js",
|
|
8
8
|
"module": "index.mjs",
|
|
9
9
|
"types": "index.d.ts",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"url": "https://github.com/edmundhung/conform/issues"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@conform-to/dom": "0.7.
|
|
33
|
+
"@conform-to/dom": "0.7.4"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"react": ">=16.8"
|