@conform-to/react 0.7.2 → 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 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/configuration.md#nested-object) by monitoring the state of each nested field and prepraing the config required.
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/configuration.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/configuration.md#nested-list) at the same time.
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/configuration.md#naming-convention) with the validation result from the resolver.
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 FormControlProps {
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 = BaseOptions & ({
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?: BaseOptions): SelectProps;
63
- export declare function textarea<Schema extends Primitive | undefined | unknown>(config: FieldConfig<Schema>, options?: BaseOptions): TextareaProps;
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
- function getFormControlProps(config, options) {
9
- var props = {
10
- id: config.id,
11
- name: config.name,
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
- var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
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
- var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
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
- return cleanup(props);
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
- function getFormControlProps(config, options) {
5
- var props = {
6
- id: config.id,
7
- name: config.name,
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
- var props = _objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
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
- var props = _objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
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
- return cleanup(props);
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,
@@ -430,7 +440,7 @@ function useFieldList(ref, config) {
430
440
  };
431
441
  }, [ref, configRef, setError]);
432
442
  return entries.map((_ref3, index) => {
433
- var _config$initialError, _config$defaultValue2;
443
+ var _config$initialError;
434
444
  var [key, defaultValue] = _ref3;
435
445
  var errors = error[index];
436
446
  var initialError = Object.entries((_config$initialError = config.initialError) !== null && _config$initialError !== void 0 ? _config$initialError : {}).reduce((result, _ref4) => {
@@ -443,7 +453,7 @@ function useFieldList(ref, config) {
443
453
  }, {});
444
454
  var fieldConfig = {
445
455
  name: "".concat(config.name, "[").concat(index, "]"),
446
- defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : (_config$defaultValue2 = config.defaultValue) === null || _config$defaultValue2 === void 0 ? void 0 : _config$defaultValue2[index],
456
+ defaultValue,
447
457
  initialError,
448
458
  error: errors === null || errors === void 0 ? void 0 : errors[0],
449
459
  errors
@@ -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 ? void 0 : (_optionsRef$current4$ = _optionsRef$current4[listener]) === null || _optionsRef$current4$ === void 0 ? void 0 : _optionsRef$current4$.call(_optionsRef$current4, event);
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 ? void 0 : (_options$acceptMultip2 = options.acceptMultipleErrors) === null || _options$acceptMultip2 === void 0 ? void 0 : _options$acceptMultip2.call(options, {
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,
@@ -426,7 +436,7 @@ function useFieldList(ref, config) {
426
436
  };
427
437
  }, [ref, configRef, setError]);
428
438
  return entries.map((_ref3, index) => {
429
- var _config$initialError, _config$defaultValue2;
439
+ var _config$initialError;
430
440
  var [key, defaultValue] = _ref3;
431
441
  var errors = error[index];
432
442
  var initialError = Object.entries((_config$initialError = config.initialError) !== null && _config$initialError !== void 0 ? _config$initialError : {}).reduce((result, _ref4) => {
@@ -439,7 +449,7 @@ function useFieldList(ref, config) {
439
449
  }, {});
440
450
  var fieldConfig = {
441
451
  name: "".concat(config.name, "[").concat(index, "]"),
442
- defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : (_config$defaultValue2 = config.defaultValue) === null || _config$defaultValue2 === void 0 ? void 0 : _config$defaultValue2[index],
452
+ defaultValue,
443
453
  initialError,
444
454
  error: errors === null || errors === void 0 ? void 0 : errors[0],
445
455
  errors
@@ -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 ? void 0 : (_optionsRef$current4$ = _optionsRef$current4[listener]) === null || _optionsRef$current4$ === void 0 ? void 0 : _optionsRef$current4$.call(_optionsRef$current4, event);
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 ? void 0 : (_options$acceptMultip2 = options.acceptMultipleErrors) === null || _options$acceptMultip2 === void 0 ? void 0 : _options$acceptMultip2.call(options, {
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.2",
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.2"
33
+ "@conform-to/dom": "0.7.4"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "react": ">=16.8"