@conform-to/react 0.4.0-pre.0 → 0.4.0-pre.1

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/hooks.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type FieldConfig, type FieldElement, type FieldValue, type FieldsetConstraint, type FormState, type ListCommand, type Primitive, type Submission } from '@conform-to/dom';
1
+ import { type FieldConfig, type FieldElement, type FieldValue, type FieldsetConstraint, type ListCommand, type Primitive, type Submission } from '@conform-to/dom';
2
2
  import { type InputHTMLAttributes, type FormEvent, type RefObject } from 'react';
3
3
  interface FormContext<Schema extends Record<string, any>> {
4
4
  form: HTMLFormElement;
@@ -6,6 +6,10 @@ interface FormContext<Schema extends Record<string, any>> {
6
6
  submission: Submission<Schema>;
7
7
  }
8
8
  export interface FormConfig<Schema extends Record<string, any>> {
9
+ /**
10
+ * Validation mode. Default to `client-only`.
11
+ */
12
+ mode?: 'client-only' | 'server-validation';
9
13
  /**
10
14
  * Define when the error should be reported initially.
11
15
  * Support "onSubmit", "onChange", "onBlur".
@@ -20,7 +24,7 @@ export interface FormConfig<Schema extends Record<string, any>> {
20
24
  /**
21
25
  * An object describing the state from the last submission
22
26
  */
23
- state?: FormState<Schema>;
27
+ state?: Submission<Schema>;
24
28
  /**
25
29
  * Enable native validation before hydation.
26
30
  *
@@ -36,7 +40,7 @@ export interface FormConfig<Schema extends Record<string, any>> {
36
40
  /**
37
41
  * A function to be called when the form should be (re)validated.
38
42
  */
39
- onValidate?: (context: FormContext<Schema>) => boolean;
43
+ onValidate?: (context: FormContext<Schema>) => void;
40
44
  /**
41
45
  * The submit event handler of the form. It will be called
42
46
  * only when the form is considered valid.
@@ -61,7 +65,7 @@ interface Form<Schema extends Record<string, any>> {
61
65
  * Returns properties required to hook into form events.
62
66
  * Applied custom validation and define when error should be reported.
63
67
  *
64
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#useform
68
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#useform
65
69
  */
66
70
  export declare function useForm<Schema extends Record<string, any>>(config?: FormConfig<Schema>): Form<Schema>;
67
71
  /**
@@ -102,7 +106,7 @@ export interface FieldsetConfig<Schema extends Record<string, any>> {
102
106
  /**
103
107
  * Returns all the information about the fieldset.
104
108
  *
105
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#usefieldset
109
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usefieldset
106
110
  */
107
111
  export declare function useFieldset<Schema extends Record<string, any>>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config?: FieldsetConfig<Schema>): Fieldset<Schema>;
108
112
  export declare function useFieldset<Schema extends Record<string, any>>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config?: FieldConfig<Schema>): Fieldset<Schema>;
@@ -129,7 +133,7 @@ interface ListControl<Schema> {
129
133
  * Returns a list of key and config, with a group of helpers
130
134
  * configuring buttons for list manipulation
131
135
  *
132
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#usefieldlist
136
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usefieldlist
133
137
  */
134
138
  export declare function useFieldList<Payload = any>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config: FieldConfig<Array<Payload>>): [
135
139
  Array<{
@@ -159,7 +163,7 @@ interface InputControl<Element extends {
159
163
  * This is particular useful when integrating dropdown and datepicker whichs
160
164
  * introduces custom input mode.
161
165
  *
162
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#usecontrolledinput
166
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usecontrolledinput
163
167
  */
164
168
  export declare function useControlledInput<Element extends {
165
169
  focus: () => void;
package/hooks.js CHANGED
@@ -11,7 +11,7 @@ var helpers = require('./helpers.js');
11
11
  * Returns properties required to hook into form events.
12
12
  * Applied custom validation and define when error should be reported.
13
13
  *
14
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#useform
14
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#useform
15
15
  */
16
16
  function useForm() {
17
17
  var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -27,15 +27,14 @@ function useForm() {
27
27
  return message !== null && message !== void 0 ? message : '';
28
28
  });
29
29
  var [fieldsetConfig, setFieldsetConfig] = react.useState(() => {
30
- var _config$state$error2, _config$state2, _config$state3, _config$state$value, _config$state4;
30
+ var _config$state$error2, _config$state2, _config$state$value, _config$state3;
31
31
 
32
32
  var error = (_config$state$error2 = (_config$state2 = config.state) === null || _config$state2 === void 0 ? void 0 : _config$state2.error) !== null && _config$state$error2 !== void 0 ? _config$state$error2 : [];
33
- var scope = (_config$state3 = config.state) === null || _config$state3 === void 0 ? void 0 : _config$state3.scope;
34
33
  return {
35
- defaultValue: (_config$state$value = (_config$state4 = config.state) === null || _config$state4 === void 0 ? void 0 : _config$state4.value) !== null && _config$state$value !== void 0 ? _config$state$value : config.defaultValue,
34
+ defaultValue: (_config$state$value = (_config$state3 = config.state) === null || _config$state3 === void 0 ? void 0 : _config$state3.value) !== null && _config$state$value !== void 0 ? _config$state$value : config.defaultValue,
36
35
  initialError: error.filter(_ref2 => {
37
36
  var [name] = _ref2;
38
- return name !== '' && dom.getSubmissionType(name) === null && (!scope || scope.includes(name));
37
+ return name !== '' && dom.getSubmissionType(name) === null;
39
38
  })
40
39
  };
41
40
  });
@@ -53,8 +52,10 @@ function useForm() {
53
52
  return;
54
53
  }
55
54
 
56
- if (!dom.reportValidity(form, config.state)) {
57
- dom.focusFirstInvalidField(form, config.state.scope);
55
+ dom.setFormError(form, config.state);
56
+
57
+ if (!form.reportValidity()) {
58
+ dom.focusFirstInvalidField(form);
58
59
  }
59
60
 
60
61
  dom.requestSubmit(form);
@@ -198,21 +199,31 @@ function useForm() {
198
199
  }
199
200
  }
200
201
 
201
- if (typeof config.onValidate === 'function' && !config.noValidate && !submitter.formNoValidate) {
202
- try {
203
- if (!config.onValidate(context)) {
202
+ try {
203
+ if (!config.noValidate && !submitter.formNoValidate) {
204
+ var _config$onValidate;
205
+
206
+ (_config$onValidate = config.onValidate) === null || _config$onValidate === void 0 ? void 0 : _config$onValidate.call(config, context);
207
+
208
+ if (!form.reportValidity()) {
204
209
  dom.focusFirstInvalidField(form);
205
210
  event.preventDefault();
206
211
  }
207
- } catch (e) {
212
+ }
213
+ } catch (e) {
214
+ if (e !== form) {
208
215
  console.warn(e);
209
216
  }
210
217
  }
211
218
 
212
219
  if (!event.defaultPrevented) {
213
- var _config$onSubmit;
220
+ if (config.mode !== 'server-validation' && submission.type === 'validate') {
221
+ event.preventDefault();
222
+ } else {
223
+ var _config$onSubmit;
214
224
 
215
- (_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, context);
225
+ (_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, context);
226
+ }
216
227
  }
217
228
  }
218
229
 
@@ -275,64 +286,12 @@ function useFieldset(ref, config) {
275
286
  configRef.current = config;
276
287
  });
277
288
  react.useEffect(() => {
278
- /**
279
- * Reset the error state of each field if its validity is changed.
280
- *
281
- * This is a workaround as no official way is provided to notify
282
- * when the validity of the field is changed from `invalid` to `valid`.
283
- */
284
- var resetError = form => {
285
- setError(prev => {
286
- var _configRef$current$na, _configRef$current;
287
-
288
- var next = prev;
289
- var fieldsetName = (_configRef$current$na = (_configRef$current = configRef.current) === null || _configRef$current === void 0 ? void 0 : _configRef$current.name) !== null && _configRef$current$na !== void 0 ? _configRef$current$na : '';
290
-
291
- for (var field of form.elements) {
292
- if (dom.isFieldElement(field) && field.name.startsWith(fieldsetName)) {
293
- var [key, ...paths] = dom.getPaths(fieldsetName.length > 0 ? field.name.slice(fieldsetName.length + 1) : field.name);
294
-
295
- if (typeof key === 'string' && paths.length === 0) {
296
- var _next$key, _next;
297
-
298
- var prevMessage = (_next$key = (_next = next) === null || _next === void 0 ? void 0 : _next[key]) !== null && _next$key !== void 0 ? _next$key : '';
299
- var nextMessage = field.validationMessage;
300
- /**
301
- * Techincally, checking prevMessage not being empty while nextMessage being empty
302
- * is sufficient for our usecase. It checks if the message is changed instead to allow
303
- * the hook to be useful independently.
304
- */
305
-
306
- if (prevMessage !== '' && prevMessage !== nextMessage) {
307
- next = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, next), {}, {
308
- [key]: nextMessage
309
- });
310
- }
311
- }
312
- }
313
- }
314
-
315
- return next;
316
- });
317
- };
318
-
319
- var handleInput = event => {
320
- var form = dom.getFormElement(ref.current);
321
- var field = event.target;
322
-
323
- if (!form || !dom.isFieldElement(field) || field.form !== form) {
324
- return;
325
- }
326
-
327
- resetError(form);
328
- };
329
-
330
289
  var invalidHandler = event => {
331
- var _configRef$current$na2, _configRef$current2;
290
+ var _configRef$current$na, _configRef$current;
332
291
 
333
292
  var form = dom.getFormElement(ref.current);
334
293
  var field = event.target;
335
- var fieldsetName = (_configRef$current$na2 = (_configRef$current2 = configRef.current) === null || _configRef$current2 === void 0 ? void 0 : _configRef$current2.name) !== null && _configRef$current$na2 !== void 0 ? _configRef$current$na2 : '';
294
+ var fieldsetName = (_configRef$current$na = (_configRef$current = configRef.current) === null || _configRef$current === void 0 ? void 0 : _configRef$current.name) !== null && _configRef$current$na !== void 0 ? _configRef$current$na : '';
336
295
 
337
296
  if (!form || !dom.isFieldElement(field) || field.form !== form || !field.name.startsWith(fieldsetName)) {
338
297
  return;
@@ -366,10 +325,39 @@ function useFieldset(ref, config) {
366
325
 
367
326
  if (!form || event.target !== form) {
368
327
  return;
369
- } // This helps resetting error that fullfilled by the submitter
328
+ }
329
+ /**
330
+ * Reset the error state of each field if its validity is changed.
331
+ *
332
+ * This is a workaround as no official way is provided to notify
333
+ * when the validity of the field is changed from `invalid` to `valid`.
334
+ */
335
+
370
336
 
337
+ setError(prev => {
338
+ var _configRef$current$na2, _configRef$current2;
339
+
340
+ var next = prev;
341
+ var fieldsetName = (_configRef$current$na2 = (_configRef$current2 = configRef.current) === null || _configRef$current2 === void 0 ? void 0 : _configRef$current2.name) !== null && _configRef$current$na2 !== void 0 ? _configRef$current$na2 : '';
371
342
 
372
- resetError(form);
343
+ for (var field of form.elements) {
344
+ if (dom.isFieldElement(field) && field.name.startsWith(fieldsetName)) {
345
+ var _next$key, _next;
346
+
347
+ var key = fieldsetName ? field.name.slice(fieldsetName.length + 1) : field.name;
348
+ var prevMessage = (_next$key = (_next = next) === null || _next === void 0 ? void 0 : _next[key]) !== null && _next$key !== void 0 ? _next$key : '';
349
+ var nextMessage = field.validationMessage;
350
+
351
+ if (prevMessage !== '' && nextMessage === '') {
352
+ next = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, next), {}, {
353
+ [key]: ''
354
+ });
355
+ }
356
+ }
357
+ }
358
+
359
+ return next;
360
+ });
373
361
  };
374
362
 
375
363
  var resetHandler = event => {
@@ -388,15 +376,13 @@ function useFieldset(ref, config) {
388
376
  initialError: {}
389
377
  });
390
378
  setError({});
391
- };
379
+ }; // The invalid event does not bubble and so listening on the capturing pharse is needed
392
380
 
393
- document.addEventListener('input', handleInput); // The invalid event does not bubble and so listening on the capturing pharse is needed
394
381
 
395
382
  document.addEventListener('invalid', invalidHandler, true);
396
383
  document.addEventListener('submit', submitHandler);
397
384
  document.addEventListener('reset', resetHandler);
398
385
  return () => {
399
- document.removeEventListener('input', handleInput);
400
386
  document.removeEventListener('invalid', invalidHandler, true);
401
387
  document.removeEventListener('submit', submitHandler);
402
388
  document.removeEventListener('reset', resetHandler);
@@ -437,7 +423,7 @@ function useFieldset(ref, config) {
437
423
  * Returns a list of key and config, with a group of helpers
438
424
  * configuring buttons for list manipulation
439
425
  *
440
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#usefieldlist
426
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usefieldlist
441
427
  */
442
428
  function useFieldList(ref, config) {
443
429
  var configRef = react.useRef(config);
@@ -581,7 +567,7 @@ function useFieldList(ref, config) {
581
567
  * This is particular useful when integrating dropdown and datepicker whichs
582
568
  * introduces custom input mode.
583
569
  *
584
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#usecontrolledinput
570
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usecontrolledinput
585
571
  */
586
572
  function useControlledInput(config) {
587
573
  var _config$defaultValue4;
package/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { type FieldsetConstraint, type FormState, type Submission, hasError, isFieldElement, parse, reportValidity, } from '@conform-to/dom';
1
+ export { type FieldsetConstraint, type Submission, hasError, isFieldElement, parse, setFormError, shouldValidate, } from '@conform-to/dom';
2
2
  export * from './hooks';
3
3
  export * as conform from './helpers';
package/index.js CHANGED
@@ -20,9 +20,13 @@ Object.defineProperty(exports, 'parse', {
20
20
  enumerable: true,
21
21
  get: function () { return dom.parse; }
22
22
  });
23
- Object.defineProperty(exports, 'reportValidity', {
23
+ Object.defineProperty(exports, 'setFormError', {
24
24
  enumerable: true,
25
- get: function () { return dom.reportValidity; }
25
+ get: function () { return dom.setFormError; }
26
+ });
27
+ Object.defineProperty(exports, 'shouldValidate', {
28
+ enumerable: true,
29
+ get: function () { return dom.shouldValidate; }
26
30
  });
27
31
  exports.useControlledInput = hooks.useControlledInput;
28
32
  exports.useFieldList = hooks.useFieldList;
package/module/hooks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
2
- import { getSubmissionType, reportValidity, focusFirstInvalidField, requestSubmit, isFieldElement, getFormData, parse, getPaths, getName, requestValidate, getFormElement, parseListCommand, updateList } from '@conform-to/dom';
2
+ import { getSubmissionType, setFormError, focusFirstInvalidField, requestSubmit, isFieldElement, getFormData, parse, getPaths, getName, requestValidate, getFormElement, parseListCommand, updateList } from '@conform-to/dom';
3
3
  import { useRef, useState, useEffect } from 'react';
4
4
  import { input } from './helpers.js';
5
5
 
@@ -7,7 +7,7 @@ import { input } from './helpers.js';
7
7
  * Returns properties required to hook into form events.
8
8
  * Applied custom validation and define when error should be reported.
9
9
  *
10
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#useform
10
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#useform
11
11
  */
12
12
  function useForm() {
13
13
  var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -23,15 +23,14 @@ function useForm() {
23
23
  return message !== null && message !== void 0 ? message : '';
24
24
  });
25
25
  var [fieldsetConfig, setFieldsetConfig] = useState(() => {
26
- var _config$state$error2, _config$state2, _config$state3, _config$state$value, _config$state4;
26
+ var _config$state$error2, _config$state2, _config$state$value, _config$state3;
27
27
 
28
28
  var error = (_config$state$error2 = (_config$state2 = config.state) === null || _config$state2 === void 0 ? void 0 : _config$state2.error) !== null && _config$state$error2 !== void 0 ? _config$state$error2 : [];
29
- var scope = (_config$state3 = config.state) === null || _config$state3 === void 0 ? void 0 : _config$state3.scope;
30
29
  return {
31
- defaultValue: (_config$state$value = (_config$state4 = config.state) === null || _config$state4 === void 0 ? void 0 : _config$state4.value) !== null && _config$state$value !== void 0 ? _config$state$value : config.defaultValue,
30
+ defaultValue: (_config$state$value = (_config$state3 = config.state) === null || _config$state3 === void 0 ? void 0 : _config$state3.value) !== null && _config$state$value !== void 0 ? _config$state$value : config.defaultValue,
32
31
  initialError: error.filter(_ref2 => {
33
32
  var [name] = _ref2;
34
- return name !== '' && getSubmissionType(name) === null && (!scope || scope.includes(name));
33
+ return name !== '' && getSubmissionType(name) === null;
35
34
  })
36
35
  };
37
36
  });
@@ -49,8 +48,10 @@ function useForm() {
49
48
  return;
50
49
  }
51
50
 
52
- if (!reportValidity(form, config.state)) {
53
- focusFirstInvalidField(form, config.state.scope);
51
+ setFormError(form, config.state);
52
+
53
+ if (!form.reportValidity()) {
54
+ focusFirstInvalidField(form);
54
55
  }
55
56
 
56
57
  requestSubmit(form);
@@ -194,21 +195,31 @@ function useForm() {
194
195
  }
195
196
  }
196
197
 
197
- if (typeof config.onValidate === 'function' && !config.noValidate && !submitter.formNoValidate) {
198
- try {
199
- if (!config.onValidate(context)) {
198
+ try {
199
+ if (!config.noValidate && !submitter.formNoValidate) {
200
+ var _config$onValidate;
201
+
202
+ (_config$onValidate = config.onValidate) === null || _config$onValidate === void 0 ? void 0 : _config$onValidate.call(config, context);
203
+
204
+ if (!form.reportValidity()) {
200
205
  focusFirstInvalidField(form);
201
206
  event.preventDefault();
202
207
  }
203
- } catch (e) {
208
+ }
209
+ } catch (e) {
210
+ if (e !== form) {
204
211
  console.warn(e);
205
212
  }
206
213
  }
207
214
 
208
215
  if (!event.defaultPrevented) {
209
- var _config$onSubmit;
216
+ if (config.mode !== 'server-validation' && submission.type === 'validate') {
217
+ event.preventDefault();
218
+ } else {
219
+ var _config$onSubmit;
210
220
 
211
- (_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, context);
221
+ (_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, context);
222
+ }
212
223
  }
213
224
  }
214
225
 
@@ -271,64 +282,12 @@ function useFieldset(ref, config) {
271
282
  configRef.current = config;
272
283
  });
273
284
  useEffect(() => {
274
- /**
275
- * Reset the error state of each field if its validity is changed.
276
- *
277
- * This is a workaround as no official way is provided to notify
278
- * when the validity of the field is changed from `invalid` to `valid`.
279
- */
280
- var resetError = form => {
281
- setError(prev => {
282
- var _configRef$current$na, _configRef$current;
283
-
284
- var next = prev;
285
- var fieldsetName = (_configRef$current$na = (_configRef$current = configRef.current) === null || _configRef$current === void 0 ? void 0 : _configRef$current.name) !== null && _configRef$current$na !== void 0 ? _configRef$current$na : '';
286
-
287
- for (var field of form.elements) {
288
- if (isFieldElement(field) && field.name.startsWith(fieldsetName)) {
289
- var [key, ...paths] = getPaths(fieldsetName.length > 0 ? field.name.slice(fieldsetName.length + 1) : field.name);
290
-
291
- if (typeof key === 'string' && paths.length === 0) {
292
- var _next$key, _next;
293
-
294
- var prevMessage = (_next$key = (_next = next) === null || _next === void 0 ? void 0 : _next[key]) !== null && _next$key !== void 0 ? _next$key : '';
295
- var nextMessage = field.validationMessage;
296
- /**
297
- * Techincally, checking prevMessage not being empty while nextMessage being empty
298
- * is sufficient for our usecase. It checks if the message is changed instead to allow
299
- * the hook to be useful independently.
300
- */
301
-
302
- if (prevMessage !== '' && prevMessage !== nextMessage) {
303
- next = _objectSpread2(_objectSpread2({}, next), {}, {
304
- [key]: nextMessage
305
- });
306
- }
307
- }
308
- }
309
- }
310
-
311
- return next;
312
- });
313
- };
314
-
315
- var handleInput = event => {
316
- var form = getFormElement(ref.current);
317
- var field = event.target;
318
-
319
- if (!form || !isFieldElement(field) || field.form !== form) {
320
- return;
321
- }
322
-
323
- resetError(form);
324
- };
325
-
326
285
  var invalidHandler = event => {
327
- var _configRef$current$na2, _configRef$current2;
286
+ var _configRef$current$na, _configRef$current;
328
287
 
329
288
  var form = getFormElement(ref.current);
330
289
  var field = event.target;
331
- var fieldsetName = (_configRef$current$na2 = (_configRef$current2 = configRef.current) === null || _configRef$current2 === void 0 ? void 0 : _configRef$current2.name) !== null && _configRef$current$na2 !== void 0 ? _configRef$current$na2 : '';
290
+ var fieldsetName = (_configRef$current$na = (_configRef$current = configRef.current) === null || _configRef$current === void 0 ? void 0 : _configRef$current.name) !== null && _configRef$current$na !== void 0 ? _configRef$current$na : '';
332
291
 
333
292
  if (!form || !isFieldElement(field) || field.form !== form || !field.name.startsWith(fieldsetName)) {
334
293
  return;
@@ -362,10 +321,39 @@ function useFieldset(ref, config) {
362
321
 
363
322
  if (!form || event.target !== form) {
364
323
  return;
365
- } // This helps resetting error that fullfilled by the submitter
324
+ }
325
+ /**
326
+ * Reset the error state of each field if its validity is changed.
327
+ *
328
+ * This is a workaround as no official way is provided to notify
329
+ * when the validity of the field is changed from `invalid` to `valid`.
330
+ */
331
+
366
332
 
333
+ setError(prev => {
334
+ var _configRef$current$na2, _configRef$current2;
335
+
336
+ var next = prev;
337
+ var fieldsetName = (_configRef$current$na2 = (_configRef$current2 = configRef.current) === null || _configRef$current2 === void 0 ? void 0 : _configRef$current2.name) !== null && _configRef$current$na2 !== void 0 ? _configRef$current$na2 : '';
367
338
 
368
- resetError(form);
339
+ for (var field of form.elements) {
340
+ if (isFieldElement(field) && field.name.startsWith(fieldsetName)) {
341
+ var _next$key, _next;
342
+
343
+ var key = fieldsetName ? field.name.slice(fieldsetName.length + 1) : field.name;
344
+ var prevMessage = (_next$key = (_next = next) === null || _next === void 0 ? void 0 : _next[key]) !== null && _next$key !== void 0 ? _next$key : '';
345
+ var nextMessage = field.validationMessage;
346
+
347
+ if (prevMessage !== '' && nextMessage === '') {
348
+ next = _objectSpread2(_objectSpread2({}, next), {}, {
349
+ [key]: ''
350
+ });
351
+ }
352
+ }
353
+ }
354
+
355
+ return next;
356
+ });
369
357
  };
370
358
 
371
359
  var resetHandler = event => {
@@ -384,15 +372,13 @@ function useFieldset(ref, config) {
384
372
  initialError: {}
385
373
  });
386
374
  setError({});
387
- };
375
+ }; // The invalid event does not bubble and so listening on the capturing pharse is needed
388
376
 
389
- document.addEventListener('input', handleInput); // The invalid event does not bubble and so listening on the capturing pharse is needed
390
377
 
391
378
  document.addEventListener('invalid', invalidHandler, true);
392
379
  document.addEventListener('submit', submitHandler);
393
380
  document.addEventListener('reset', resetHandler);
394
381
  return () => {
395
- document.removeEventListener('input', handleInput);
396
382
  document.removeEventListener('invalid', invalidHandler, true);
397
383
  document.removeEventListener('submit', submitHandler);
398
384
  document.removeEventListener('reset', resetHandler);
@@ -433,7 +419,7 @@ function useFieldset(ref, config) {
433
419
  * Returns a list of key and config, with a group of helpers
434
420
  * configuring buttons for list manipulation
435
421
  *
436
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#usefieldlist
422
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usefieldlist
437
423
  */
438
424
  function useFieldList(ref, config) {
439
425
  var configRef = useRef(config);
@@ -577,7 +563,7 @@ function useFieldList(ref, config) {
577
563
  * This is particular useful when integrating dropdown and datepicker whichs
578
564
  * introduces custom input mode.
579
565
  *
580
- * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.0/packages/conform-react/README.md#usecontrolledinput
566
+ * @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usecontrolledinput
581
567
  */
582
568
  function useControlledInput(config) {
583
569
  var _config$defaultValue4;
package/module/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { hasError, isFieldElement, parse, reportValidity } from '@conform-to/dom';
1
+ export { hasError, isFieldElement, parse, setFormError, shouldValidate } from '@conform-to/dom';
2
2
  export { useControlledInput, useFieldList, useFieldset, useForm } 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.4.0-pre.0",
5
+ "version": "0.4.0-pre.1",
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.4.0-pre.0"
22
+ "@conform-to/dom": "0.4.0-pre.1"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "react": ">=16.8"