@conform-to/react 0.5.0-pre.0 → 0.5.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 { getSubmissionType, reportSubmission, getFormData, parse, isFieldElement, hasError, getPaths, getName, requestValidate, getFormElement, parseListCommand, updateList } from '@conform-to/dom';
2
+ import { shouldValidate, reportSubmission, getFormData, parse, isFieldElement, hasError, getPaths, getName, requestCommand, validate, 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.1/packages/conform-react/README.md#useform
10
+ * @see https://conform.guide/api/react#useform
11
11
  */
12
12
  function useForm() {
13
13
  var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -21,17 +21,26 @@ function useForm() {
21
21
  })) !== null && _config$state$error$f !== void 0 ? _config$state$error$f : [];
22
22
  return message !== null && message !== void 0 ? message : '';
23
23
  });
24
- var [fieldsetConfig, setFieldsetConfig] = useState(() => {
25
- var _config$state$error2, _config$state2, _config$state$value, _config$state3;
26
- 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 : [];
24
+ var [uncontrolledState, setUncontrolledState] = useState(() => {
25
+ var submission = config.state;
26
+ if (!submission) {
27
+ return {
28
+ defaultValue: config.defaultValue
29
+ };
30
+ }
27
31
  return {
28
- 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,
29
- initialError: error.filter(_ref2 => {
32
+ defaultValue: submission.value,
33
+ initialError: submission.error.filter(_ref2 => {
30
34
  var [name] = _ref2;
31
- return name !== '' && getSubmissionType(name) === null;
35
+ return name !== '' && shouldValidate(submission, name);
32
36
  })
33
37
  };
34
38
  });
39
+ var fieldsetConfig = _objectSpread2(_objectSpread2({}, uncontrolledState), {}, {
40
+ constraint: config.constraint,
41
+ form: config.id
42
+ });
43
+ var fieldset = useFieldset(ref, fieldsetConfig);
35
44
  var [noValidate, setNoValidate] = useState(config.noValidate || !config.fallbackNative);
36
45
  useEffect(() => {
37
46
  configRef.current = config;
@@ -55,11 +64,8 @@ function useForm() {
55
64
  if (!form || !isFieldElement(field) || field.form !== form) {
56
65
  return;
57
66
  }
58
- if (formConfig.initialReport === 'onChange') {
59
- field.dataset.conformTouched = 'true';
60
- }
61
- if (field.dataset.conformTouched) {
62
- requestValidate(form, field.name);
67
+ if (field.dataset.conformTouched || formConfig.initialReport === 'onChange') {
68
+ requestCommand(form, validate(field.name));
63
69
  }
64
70
  };
65
71
  var handleBlur = event => {
@@ -70,8 +76,7 @@ function useForm() {
70
76
  return;
71
77
  }
72
78
  if (formConfig.initialReport === 'onBlur' && !field.dataset.conformTouched) {
73
- field.dataset.conformTouched = 'true';
74
- requestValidate(form, field.name);
79
+ requestCommand(form, validate(field.name));
75
80
  }
76
81
  };
77
82
  var handleInvalid = event => {
@@ -96,11 +101,12 @@ function useForm() {
96
101
  for (var field of form.elements) {
97
102
  if (isFieldElement(field)) {
98
103
  delete field.dataset.conformTouched;
104
+ field.setAttribute('aria-invalid', 'false');
99
105
  field.setCustomValidity('');
100
106
  }
101
107
  }
102
108
  setError('');
103
- setFieldsetConfig({
109
+ setUncontrolledState({
104
110
  defaultValue: formConfig.defaultValue,
105
111
  initialError: []
106
112
  });
@@ -123,11 +129,13 @@ function useForm() {
123
129
  document.removeEventListener('reset', handleReset);
124
130
  };
125
131
  }, []);
126
- return {
132
+ var form = {
133
+ id: config.id,
127
134
  ref,
128
135
  error,
129
136
  props: {
130
137
  ref,
138
+ id: config.id,
131
139
  noValidate,
132
140
  onSubmit(event) {
133
141
  var form = event.currentTarget;
@@ -169,16 +177,6 @@ function useForm() {
169
177
  }
170
178
  }
171
179
  }
172
-
173
- // Touch all fields only if the submitter is not a command button
174
- if (submission.type === 'submit') {
175
- for (var field of form.elements) {
176
- if (isFieldElement(field)) {
177
- // Mark the field as touched
178
- field.dataset.conformTouched = 'true';
179
- }
180
- }
181
- }
182
180
  if (!config.noValidate && !(submitter !== null && submitter !== void 0 && submitter.formNoValidate) && hasError(submission.error) || submission.type === 'validate' && config.mode !== 'server-validation') {
183
181
  event.preventDefault();
184
182
  } else {
@@ -198,6 +196,7 @@ function useForm() {
198
196
  },
199
197
  config: fieldsetConfig
200
198
  };
199
+ return [form, fieldset];
201
200
  }
202
201
 
203
202
  /**
@@ -258,6 +257,10 @@ function useFieldset(ref, config) {
258
257
  // Update the error only if the field belongs to the fieldset
259
258
  if (typeof key === 'string' && paths.length === 0) {
260
259
  if (field.dataset.conformTouched) {
260
+ // Update the aria attribute only if it is set
261
+ if (field.getAttribute('aria-invalid')) {
262
+ field.setAttribute('aria-invalid', field.validationMessage !== '' ? 'true' : 'false');
263
+ }
261
264
  setError(prev => {
262
265
  var _prev$key;
263
266
  var prevMessage = (_prev$key = prev === null || prev === void 0 ? void 0 : prev[key]) !== null && _prev$key !== void 0 ? _prev$key : '';
@@ -312,21 +315,26 @@ function useFieldset(ref, config) {
312
315
  var field = {
313
316
  config: _objectSpread2({
314
317
  name: fieldsetConfig.name ? "".concat(fieldsetConfig.name, ".").concat(key) : key,
315
- form: fieldsetConfig.form,
316
318
  defaultValue: uncontrolledState.defaultValue[key],
317
319
  initialError: uncontrolledState.initialError[key]
318
320
  }, constraint),
319
321
  error: (_error$key = error === null || error === void 0 ? void 0 : error[key]) !== null && _error$key !== void 0 ? _error$key : ''
320
322
  };
323
+ if (fieldsetConfig.form) {
324
+ field.config.form = fieldsetConfig.form;
325
+ field.config.id = "".concat(fieldsetConfig.form, "-").concat(field.config.name);
326
+ field.config.errorId = "".concat(field.config.id, "-error");
327
+ }
321
328
  return field;
322
329
  }
323
330
  });
324
331
  }
332
+
325
333
  /**
326
334
  * Returns a list of key and config, with a group of helpers
327
335
  * configuring buttons for list manipulation
328
336
  *
329
- * @see https://github.com/edmundhung/conform/tree/v0.4.1/packages/conform-react/README.md#usefieldlist
337
+ * @see https://conform.guide/api/react#usefieldlist
330
338
  */
331
339
  function useFieldList(ref, config) {
332
340
  var configRef = useRef(config);
@@ -357,41 +365,6 @@ function useFieldList(ref, config) {
357
365
  var _config$defaultValue3;
358
366
  return Object.entries((_config$defaultValue3 = config.defaultValue) !== null && _config$defaultValue3 !== void 0 ? _config$defaultValue3 : [undefined]);
359
367
  });
360
- var list = entries.map((_ref3, index) => {
361
- var [key, defaultValue] = _ref3;
362
- return {
363
- key,
364
- error: error[index],
365
- config: {
366
- name: "".concat(config.name, "[").concat(index, "]"),
367
- form: config.form,
368
- defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : uncontrolledState.defaultValue[index],
369
- initialError: uncontrolledState.initialError[index]
370
- }
371
- };
372
- });
373
-
374
- /***
375
- * This use proxy to capture all information about the command and
376
- * have it encoded in the value.
377
- */
378
- var command = new Proxy({}, {
379
- get(_target, type) {
380
- return function () {
381
- var payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
382
- return {
383
- name: 'conform/list',
384
- value: JSON.stringify({
385
- type,
386
- scope: config.name,
387
- payload
388
- }),
389
- form: config.form,
390
- formNoValidate: true
391
- };
392
- };
393
- }
394
- });
395
368
  useEffect(() => {
396
369
  configRef.current = config;
397
370
  });
@@ -488,16 +461,31 @@ function useFieldList(ref, config) {
488
461
  document.removeEventListener('reset', resetHandler);
489
462
  };
490
463
  }, [ref]);
491
- return [list,
492
- // @ts-expect-error proxy type
493
- command];
464
+ return entries.map((_ref3, index) => {
465
+ var [key, defaultValue] = _ref3;
466
+ var fieldConfig = {
467
+ name: "".concat(config.name, "[").concat(index, "]"),
468
+ defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : uncontrolledState.defaultValue[index],
469
+ initialError: uncontrolledState.initialError[index]
470
+ };
471
+ if (config.form) {
472
+ fieldConfig.form = config.form;
473
+ fieldConfig.id = "".concat(config.form, "-").concat(config.name);
474
+ fieldConfig.errorId = "".concat(fieldConfig.id, "-error");
475
+ }
476
+ return {
477
+ key,
478
+ error: error[index],
479
+ config: fieldConfig
480
+ };
481
+ });
494
482
  }
495
483
  /**
496
484
  * Returns the properties required to configure a shadow input for validation.
497
485
  * This is particular useful when integrating dropdown and datepicker whichs
498
486
  * introduces custom input mode.
499
487
  *
500
- * @see https://github.com/edmundhung/conform/tree/v0.4.1/packages/conform-react/README.md#usecontrolledinput
488
+ * @see https://conform.guide/api/react#usecontrolledinput
501
489
  */
502
490
  function useControlledInput(config) {
503
491
  var _config$defaultValue4;
package/module/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { getFormElements, hasError, parse, shouldValidate } from '@conform-to/dom';
1
+ export { getFormElements, hasError, list, parse, requestCommand, requestSubmit, shouldValidate, validate } 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.5.0-pre.0",
5
+ "version": "0.5.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.5.0-pre.0"
22
+ "@conform-to/dom": "0.5.0"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "react": ">=16.8"