@conform-to/react 0.6.0-pre.0 → 0.6.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/module/hooks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
2
- import { getValidationMessage, shouldValidate, parseListCommand, reportSubmission, getFormData, parse, VALIDATION_UNDEFINED, getFormAttributes, getPaths, getName, getErrors, isFieldElement, requestIntent, validate, getFormElement, updateList } from '@conform-to/dom';
2
+ import { getScope, parseListCommand, reportSubmission, getFormData, parse, VALIDATION_UNDEFINED, getFormAttributes, getPaths, getName, isFieldElement, requestIntent, validate, getFormElement, FORM_ERROR_ELEMENT_NAME, getErrors, getValidationMessage, updateList } from '@conform-to/dom';
3
3
  import { useRef, useState, useEffect, useMemo, useLayoutEffect } from 'react';
4
4
 
5
5
  /**
@@ -9,30 +9,30 @@ import { useRef, useState, useEffect, useMemo, useLayoutEffect } from 'react';
9
9
  * @see https://conform.guide/api/react#useform
10
10
  */
11
11
  function useForm() {
12
- var _config$state;
12
+ var _config$lastSubmissio;
13
13
  var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
14
14
  var configRef = useRef(config);
15
15
  var ref = useRef(null);
16
- var [lastSubmission, setLastSubmission] = useState((_config$state = config.state) !== null && _config$state !== void 0 ? _config$state : null);
17
- var [error, setError] = useState(() => {
18
- if (!config.state) {
19
- return '';
16
+ var [lastSubmission, setLastSubmission] = useState((_config$lastSubmissio = config.lastSubmission) !== null && _config$lastSubmissio !== void 0 ? _config$lastSubmissio : null);
17
+ var [errors, setErrors] = useState(() => {
18
+ if (!config.lastSubmission) {
19
+ return [];
20
20
  }
21
- var message = config.state.error[''];
22
- return getValidationMessage(message);
21
+ return [].concat(config.lastSubmission.error['']);
23
22
  });
24
23
  var [uncontrolledState, setUncontrolledState] = useState(() => {
25
- var submission = config.state;
24
+ var submission = config.lastSubmission;
26
25
  if (!submission) {
27
26
  return {
28
27
  defaultValue: config.defaultValue
29
28
  };
30
29
  }
30
+ var scope = getScope(submission.intent);
31
31
  return {
32
32
  defaultValue: submission.payload,
33
33
  initialError: Object.entries(submission.error).reduce((result, _ref) => {
34
34
  var [name, message] = _ref;
35
- if (name !== '' && shouldValidate(submission.intent, name)) {
35
+ if (name !== '' && (scope === null || scope === name)) {
36
36
  result[name] = message;
37
37
  }
38
38
  return result;
@@ -53,7 +53,7 @@ function useForm() {
53
53
  }, []);
54
54
  useEffect(() => {
55
55
  var form = ref.current;
56
- var submission = config.state;
56
+ var submission = config.lastSubmission;
57
57
  if (!form || !submission) {
58
58
  return;
59
59
  }
@@ -64,7 +64,7 @@ function useForm() {
64
64
  }));
65
65
  }
66
66
  setLastSubmission(submission);
67
- }, [config.state]);
67
+ }, [config.lastSubmission]);
68
68
  useEffect(() => {
69
69
  var form = ref.current;
70
70
  if (!form || !lastSubmission) {
@@ -99,12 +99,12 @@ function useForm() {
99
99
  var handleInvalid = event => {
100
100
  var form = getFormElement(ref.current);
101
101
  var field = event.target;
102
- if (!form || !isFieldElement(field) || field.form !== form || field.name !== '__form__') {
102
+ if (!form || !isFieldElement(field) || field.form !== form || field.name !== FORM_ERROR_ELEMENT_NAME) {
103
103
  return;
104
104
  }
105
105
  event.preventDefault();
106
106
  if (field.dataset.conformTouched) {
107
- setError(field.validationMessage);
107
+ setErrors(getErrors(field.validationMessage));
108
108
  }
109
109
  };
110
110
  var handleReset = event => {
@@ -118,11 +118,10 @@ function useForm() {
118
118
  for (var field of form.elements) {
119
119
  if (isFieldElement(field)) {
120
120
  delete field.dataset.conformTouched;
121
- field.setAttribute('aria-invalid', 'false');
122
121
  field.setCustomValidity('');
123
122
  }
124
123
  }
125
- setError('');
124
+ setErrors([]);
126
125
  setUncontrolledState({
127
126
  defaultValue: formConfig.defaultValue
128
127
  });
@@ -146,12 +145,11 @@ function useForm() {
146
145
  };
147
146
  }, []);
148
147
  var form = {
149
- id: config.id,
150
148
  ref,
151
- error,
149
+ error: errors[0],
150
+ errors,
152
151
  props: {
153
152
  ref,
154
- id: config.id,
155
153
  noValidate,
156
154
  onSubmit(event) {
157
155
  var form = event.currentTarget;
@@ -194,14 +192,22 @@ function useForm() {
194
192
  console.warn(e);
195
193
  }
196
194
  }
197
- },
198
- config: fieldsetConfig
195
+ }
199
196
  };
197
+ if (config.id) {
198
+ form.id = config.id;
199
+ form.errorId = "".concat(config.id, "-error");
200
+ form.props.id = form.id;
201
+ form.props['aria-describedby'] = form.errorId;
202
+ }
203
+ if (form.errorId && form.errors.length > 0) {
204
+ form.props['aria-invalid'] = 'true';
205
+ }
200
206
  return [form, fieldset];
201
207
  }
202
208
 
203
209
  /**
204
- * All the information of the field, including state and config.
210
+ * A set of field configuration
205
211
  */
206
212
 
207
213
  function useFieldset(ref, config) {
@@ -229,7 +235,8 @@ function useFieldset(ref, config) {
229
235
  var [error, setError] = useState(() => {
230
236
  var result = {};
231
237
  for (var [key, _error] of Object.entries(uncontrolledState.initialError)) {
232
- result[key] = getErrors(getValidationMessage(_error === null || _error === void 0 ? void 0 : _error['']));
238
+ var _error$;
239
+ result[key] = [].concat((_error$ = _error === null || _error === void 0 ? void 0 : _error['']) !== null && _error$ !== void 0 ? _error$ : []);
233
240
  }
234
241
  return result;
235
242
  });
@@ -250,10 +257,6 @@ function useFieldset(ref, config) {
250
257
  // Update the error only if the field belongs to the fieldset
251
258
  if (typeof key === 'string' && paths.length === 0) {
252
259
  if (field.dataset.conformTouched) {
253
- // Update the aria attribute only if it is set
254
- if (field.getAttribute('aria-invalid')) {
255
- field.setAttribute('aria-invalid', field.validationMessage !== '' ? 'true' : 'false');
256
- }
257
260
  setError(prev => {
258
261
  var prevMessage = getValidationMessage(prev === null || prev === void 0 ? void 0 : prev[key]);
259
262
  if (prevMessage === field.validationMessage) {
@@ -305,19 +308,17 @@ function useFieldset(ref, config) {
305
308
  var fieldsetConfig = config !== null && config !== void 0 ? config : {};
306
309
  var constraint = (_fieldsetConfig$const = fieldsetConfig.constraint) === null || _fieldsetConfig$const === void 0 ? void 0 : _fieldsetConfig$const[key];
307
310
  var errors = error === null || error === void 0 ? void 0 : error[key];
308
- var field = {
309
- config: _objectSpread2({
310
- name: fieldsetConfig.name ? "".concat(fieldsetConfig.name, ".").concat(key) : key,
311
- defaultValue: uncontrolledState.defaultValue[key],
312
- initialError: uncontrolledState.initialError[key]
313
- }, constraint),
311
+ var field = _objectSpread2(_objectSpread2({}, constraint), {}, {
312
+ name: fieldsetConfig.name ? "".concat(fieldsetConfig.name, ".").concat(key) : key,
313
+ defaultValue: uncontrolledState.defaultValue[key],
314
+ initialError: uncontrolledState.initialError[key],
314
315
  error: errors === null || errors === void 0 ? void 0 : errors[0],
315
316
  errors
316
- };
317
+ });
317
318
  if (fieldsetConfig.form) {
318
- field.config.form = fieldsetConfig.form;
319
- field.config.id = "".concat(fieldsetConfig.form, "-").concat(field.config.name);
320
- field.config.errorId = "".concat(field.config.id, "-error");
319
+ field.form = fieldsetConfig.form;
320
+ field.id = "".concat(fieldsetConfig.form, "-").concat(field.name);
321
+ field.errorId = "".concat(field.id, "-error");
321
322
  }
322
323
  return field;
323
324
  }
@@ -350,7 +351,10 @@ function useFieldList(ref, config) {
350
351
  initialError
351
352
  };
352
353
  });
353
- var [error, setError] = useState(() => uncontrolledState.initialError.map(error => getErrors(getValidationMessage(error === null || error === void 0 ? void 0 : error['']))));
354
+ var [error, setError] = useState(() => uncontrolledState.initialError.map(error => {
355
+ var _error$2;
356
+ return [].concat((_error$2 = error === null || error === void 0 ? void 0 : error['']) !== null && _error$2 !== void 0 ? _error$2 : []);
357
+ }));
354
358
  var [entries, setEntries] = useState(() => {
355
359
  var _config$defaultValue3;
356
360
  return Object.entries((_config$defaultValue3 = config.defaultValue) !== null && _config$defaultValue3 !== void 0 ? _config$defaultValue3 : [undefined]);
@@ -460,19 +464,18 @@ function useFieldList(ref, config) {
460
464
  var fieldConfig = {
461
465
  name: "".concat(config.name, "[").concat(index, "]"),
462
466
  defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : uncontrolledState.defaultValue[index],
463
- initialError: uncontrolledState.initialError[index]
467
+ initialError: uncontrolledState.initialError[index],
468
+ error: errors === null || errors === void 0 ? void 0 : errors[0],
469
+ errors
464
470
  };
465
471
  if (config.form) {
466
472
  fieldConfig.form = config.form;
467
473
  fieldConfig.id = "".concat(config.form, "-").concat(config.name);
468
474
  fieldConfig.errorId = "".concat(fieldConfig.id, "-error");
469
475
  }
470
- return {
471
- key,
472
- error: errors === null || errors === void 0 ? void 0 : errors[0],
473
- errors,
474
- config: fieldConfig
475
- };
476
+ return _objectSpread2({
477
+ key
478
+ }, fieldConfig);
476
479
  });
477
480
  }
478
481
 
package/module/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { getFormElements, list, parse, requestIntent, requestSubmit, validate, validateConstraint } from '@conform-to/dom';
1
+ export { isFieldElement, list, parse, requestIntent, validate, validateConstraint } from '@conform-to/dom';
2
2
  export { useFieldList, useFieldset, useForm, useInputEvent } from './hooks.js';
3
3
  import * as helpers from './helpers.js';
4
4
  export { helpers as conform };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@conform-to/react",
3
3
  "description": "Conform view adapter for react",
4
4
  "license": "MIT",
5
- "version": "0.6.0-pre.0",
5
+ "version": "0.6.0",
6
6
  "main": "index.js",
7
7
  "module": "module/index.js",
8
8
  "repository": {
@@ -19,7 +19,7 @@
19
19
  "url": "https://github.com/edmundhung/conform/issues"
20
20
  },
21
21
  "dependencies": {
22
- "@conform-to/dom": "0.6.0-pre.0"
22
+ "@conform-to/dom": "0.6.0"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "react": ">=16.8"
package/base.d.ts DELETED
@@ -1,17 +0,0 @@
1
- import { type InputHTMLAttributes, type RefObject } from 'react';
2
- declare type EventLikeOrString = {
3
- target: {
4
- value: string;
5
- };
6
- } | string;
7
- declare type InputControl = {
8
- onChange: (eventLikeOrString: EventLikeOrString) => void;
9
- onInput: (eventLikeOrString: EventLikeOrString) => void;
10
- onFocus: () => void;
11
- onBlur: () => void;
12
- };
13
- export declare function useInputControl(ref: RefObject<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>): InputControl;
14
- export declare const BaseInput: import("react").ForwardRefExoticComponent<{
15
- name: string;
16
- } & Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "type" | "value" | "defaultValue"> & import("react").RefAttributes<HTMLInputElement>>;
17
- export {};
package/base.js DELETED
@@ -1,112 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
6
- var react = require('react');
7
-
8
- var _excluded = ["hidden", "className", "style"];
9
- /**
10
- * Triggering react custom change event
11
- * Solution based on dom-testing-library
12
- * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
13
- * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
14
- */
15
- function setNativeValue(element, value) {
16
- var {
17
- set: valueSetter
18
- } = Object.getOwnPropertyDescriptor(element, 'value') || {};
19
- var prototype = Object.getPrototypeOf(element);
20
- var {
21
- set: prototypeValueSetter
22
- } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
23
- if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
24
- prototypeValueSetter.call(element, value);
25
- } else {
26
- if (valueSetter) {
27
- valueSetter.call(element, value);
28
- } else {
29
- throw new Error('The given element does not have a value setter');
30
- }
31
- }
32
- }
33
- function useInputControl(ref) {
34
- function getInputElement() {
35
- var $input = ref.current;
36
- if (!$input) {
37
- console.warn('input ref is not available; Maybe you forget to setup the ref?');
38
- }
39
- return $input;
40
- }
41
- return {
42
- onChange(eventLikeOrString) {
43
- var $input = getInputElement();
44
- var value = typeof eventLikeOrString === 'string' ? eventLikeOrString : eventLikeOrString.target.value;
45
- if ($input && $input.value !== value) {
46
- $input.dispatchEvent(new InputEvent('beforeinput', {
47
- bubbles: true,
48
- cancelable: true
49
- }));
50
- setNativeValue($input, value);
51
- $input.dispatchEvent(new InputEvent('input', {
52
- bubbles: true,
53
- cancelable: true
54
- }));
55
- }
56
- },
57
- onInput(eventLikeOrString) {
58
- this.onChange(eventLikeOrString);
59
- },
60
- onFocus() {
61
- var $input = getInputElement();
62
- if ($input) {
63
- $input.dispatchEvent(new FocusEvent('focusin', {
64
- bubbles: true,
65
- cancelable: true
66
- }));
67
- $input.dispatchEvent(new FocusEvent('focus', {
68
- cancelable: true
69
- }));
70
- }
71
- },
72
- onBlur() {
73
- var $input = getInputElement();
74
- if ($input) {
75
- $input.dispatchEvent(new FocusEvent('focusout', {
76
- bubbles: true,
77
- cancelable: true
78
- }));
79
- $input.dispatchEvent(new FocusEvent('blur', {
80
- cancelable: true
81
- }));
82
- }
83
- }
84
- };
85
- }
86
- function BaseInputImpl(_ref, ref) {
87
- var {
88
- hidden = true,
89
- className,
90
- style
91
- } = _ref,
92
- props = _rollupPluginBabelHelpers.objectWithoutProperties(_ref, _excluded);
93
- return /*#__PURE__*/react.createElement('input', _rollupPluginBabelHelpers.objectSpread2({
94
- ref,
95
- className: hidden ? '' : className,
96
- style: hidden ? {
97
- position: 'absolute',
98
- width: '1px',
99
- height: '1px',
100
- padding: 0,
101
- margin: '-1px',
102
- overflow: 'hidden',
103
- clip: 'rect(0,0,0,0)',
104
- whiteSpace: 'nowrap',
105
- borderWidth: 0
106
- } : style
107
- }, props));
108
- }
109
- var BaseInput = /*#__PURE__*/react.forwardRef(BaseInputImpl);
110
-
111
- exports.BaseInput = BaseInput;
112
- exports.useInputControl = useInputControl;
package/module/base.js DELETED
@@ -1,107 +0,0 @@
1
- import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
2
- import { forwardRef, createElement } from 'react';
3
-
4
- var _excluded = ["hidden", "className", "style"];
5
- /**
6
- * Triggering react custom change event
7
- * Solution based on dom-testing-library
8
- * @see https://github.com/facebook/react/issues/10135#issuecomment-401496776
9
- * @see https://github.com/testing-library/dom-testing-library/blob/main/src/events.js#L104-L123
10
- */
11
- function setNativeValue(element, value) {
12
- var {
13
- set: valueSetter
14
- } = Object.getOwnPropertyDescriptor(element, 'value') || {};
15
- var prototype = Object.getPrototypeOf(element);
16
- var {
17
- set: prototypeValueSetter
18
- } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};
19
- if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
20
- prototypeValueSetter.call(element, value);
21
- } else {
22
- if (valueSetter) {
23
- valueSetter.call(element, value);
24
- } else {
25
- throw new Error('The given element does not have a value setter');
26
- }
27
- }
28
- }
29
- function useInputControl(ref) {
30
- function getInputElement() {
31
- var $input = ref.current;
32
- if (!$input) {
33
- console.warn('input ref is not available; Maybe you forget to setup the ref?');
34
- }
35
- return $input;
36
- }
37
- return {
38
- onChange(eventLikeOrString) {
39
- var $input = getInputElement();
40
- var value = typeof eventLikeOrString === 'string' ? eventLikeOrString : eventLikeOrString.target.value;
41
- if ($input && $input.value !== value) {
42
- $input.dispatchEvent(new InputEvent('beforeinput', {
43
- bubbles: true,
44
- cancelable: true
45
- }));
46
- setNativeValue($input, value);
47
- $input.dispatchEvent(new InputEvent('input', {
48
- bubbles: true,
49
- cancelable: true
50
- }));
51
- }
52
- },
53
- onInput(eventLikeOrString) {
54
- this.onChange(eventLikeOrString);
55
- },
56
- onFocus() {
57
- var $input = getInputElement();
58
- if ($input) {
59
- $input.dispatchEvent(new FocusEvent('focusin', {
60
- bubbles: true,
61
- cancelable: true
62
- }));
63
- $input.dispatchEvent(new FocusEvent('focus', {
64
- cancelable: true
65
- }));
66
- }
67
- },
68
- onBlur() {
69
- var $input = getInputElement();
70
- if ($input) {
71
- $input.dispatchEvent(new FocusEvent('focusout', {
72
- bubbles: true,
73
- cancelable: true
74
- }));
75
- $input.dispatchEvent(new FocusEvent('blur', {
76
- cancelable: true
77
- }));
78
- }
79
- }
80
- };
81
- }
82
- function BaseInputImpl(_ref, ref) {
83
- var {
84
- hidden = true,
85
- className,
86
- style
87
- } = _ref,
88
- props = _objectWithoutProperties(_ref, _excluded);
89
- return /*#__PURE__*/createElement('input', _objectSpread2({
90
- ref,
91
- className: hidden ? '' : className,
92
- style: hidden ? {
93
- position: 'absolute',
94
- width: '1px',
95
- height: '1px',
96
- padding: 0,
97
- margin: '-1px',
98
- overflow: 'hidden',
99
- clip: 'rect(0,0,0,0)',
100
- whiteSpace: 'nowrap',
101
- borderWidth: 0
102
- } : style
103
- }, props));
104
- }
105
- var BaseInput = /*#__PURE__*/forwardRef(BaseInputImpl);
106
-
107
- export { BaseInput, useInputControl };