@conform-to/react 0.7.0-pre.0 → 0.7.0-pre.2

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
@@ -507,7 +507,7 @@ export default function SignupForm() {
507
507
 
508
508
  ### list
509
509
 
510
- It provides serveral helpers to configure an intent button for [modifying a list](/docs/commands.md#modifying-a-list).
510
+ It provides serveral helpers to configure an intent button for [modifying a list](/docs/intent-button.md#modifying-a-list).
511
511
 
512
512
  ```tsx
513
513
  import { list } from '@conform-to/react';
@@ -540,7 +540,7 @@ function Example() {
540
540
 
541
541
  ### validate
542
542
 
543
- It returns the properties required to configure an intent button for [validation](/docs/commands.md#validation).
543
+ It returns the properties required to configure an intent button for [validation](/docs/intent-button.md#validation).
544
544
 
545
545
  ```tsx
546
546
  import { validate } from '@conform-to/react';
@@ -562,7 +562,7 @@ function Example() {
562
562
 
563
563
  ### requestIntent
564
564
 
565
- It lets you [trigger an intent](/docs/commands.md#triggering-an-intent) without requiring users to click on a button. It supports both [list](#list) and [validate](#validate) intent.
565
+ It lets you [trigger an intent](/docs/intent-button.md#triggering-an-intent) without requiring users to click on a button. It supports both [list](#list) and [validate](#validate) intent.
566
566
 
567
567
  ```tsx
568
568
  import {
@@ -1,3 +1,7 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
1
5
  function ownKeys(object, enumerableOnly) {
2
6
  var keys = Object.keys(object);
3
7
  if (Object.getOwnPropertySymbols) {
@@ -48,4 +52,7 @@ function _toPropertyKey(arg) {
48
52
  return typeof key === "symbol" ? key : String(key);
49
53
  }
50
54
 
51
- export { _defineProperty as defineProperty, _objectSpread2 as objectSpread2, _toPrimitive as toPrimitive, _toPropertyKey as toPropertyKey };
55
+ exports.defineProperty = _defineProperty;
56
+ exports.objectSpread2 = _objectSpread2;
57
+ exports.toPrimitive = _toPrimitive;
58
+ exports.toPropertyKey = _toPropertyKey;
@@ -1,7 +1,3 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
1
  function ownKeys(object, enumerableOnly) {
6
2
  var keys = Object.keys(object);
7
3
  if (Object.getOwnPropertySymbols) {
@@ -52,7 +48,4 @@ function _toPropertyKey(arg) {
52
48
  return typeof key === "symbol" ? key : String(key);
53
49
  }
54
50
 
55
- exports.defineProperty = _defineProperty;
56
- exports.objectSpread2 = _objectSpread2;
57
- exports.toPrimitive = _toPrimitive;
58
- exports.toPropertyKey = _toPropertyKey;
51
+ export { _defineProperty as defineProperty, _objectSpread2 as objectSpread2, _toPrimitive as toPrimitive, _toPropertyKey as toPropertyKey };
package/helpers.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { INTENT } from '@conform-to/dom';
2
- import { type FieldConfig, type Primitive, VALIDATION_UNDEFINED, VALIDATION_SKIPPED } from './hooks';
2
+ import { type FieldConfig, type Primitive, VALIDATION_UNDEFINED, VALIDATION_SKIPPED } from './hooks.js';
3
3
  import type { CSSProperties, HTMLInputTypeAttribute } from 'react';
4
4
  interface FormControlProps {
5
5
  id?: string;
package/helpers.js CHANGED
@@ -1,6 +1,10 @@
1
- import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
2
- export { INTENT } from '@conform-to/dom';
3
- export { VALIDATION_SKIPPED, VALIDATION_UNDEFINED } from './hooks.js';
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
6
+ var dom = require('@conform-to/dom');
7
+ var hooks = require('./hooks.js');
4
8
 
5
9
  /**
6
10
  * Style to make the input element visually hidden
@@ -47,7 +51,7 @@ function getFormControlProps(config, options) {
47
51
  }
48
52
  function input(config) {
49
53
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
50
- var props = _objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
54
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
51
55
  type: options.type,
52
56
  minLength: config.minLength,
53
57
  maxLength: config.maxLength,
@@ -67,14 +71,14 @@ function input(config) {
67
71
  return props;
68
72
  }
69
73
  function select(config, options) {
70
- var props = _objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
74
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
71
75
  defaultValue: config.defaultValue,
72
76
  multiple: config.multiple
73
77
  });
74
78
  return props;
75
79
  }
76
80
  function textarea(config, options) {
77
- var props = _objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
81
+ var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
78
82
  defaultValue: config.defaultValue,
79
83
  minLength: config.minLength,
80
84
  maxLength: config.maxLength
@@ -82,4 +86,12 @@ function textarea(config, options) {
82
86
  return props;
83
87
  }
84
88
 
85
- export { input, select, textarea };
89
+ Object.defineProperty(exports, 'INTENT', {
90
+ enumerable: true,
91
+ get: function () { return dom.INTENT; }
92
+ });
93
+ exports.VALIDATION_SKIPPED = hooks.VALIDATION_SKIPPED;
94
+ exports.VALIDATION_UNDEFINED = hooks.VALIDATION_UNDEFINED;
95
+ exports.input = input;
96
+ exports.select = select;
97
+ exports.textarea = textarea;
@@ -1,10 +1,6 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.cjs');
6
- var dom = require('@conform-to/dom');
7
- var hooks = require('./hooks.cjs');
1
+ import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
+ export { INTENT } from '@conform-to/dom';
3
+ export { VALIDATION_SKIPPED, VALIDATION_UNDEFINED } from './hooks.mjs';
8
4
 
9
5
  /**
10
6
  * Style to make the input element visually hidden
@@ -51,7 +47,7 @@ function getFormControlProps(config, options) {
51
47
  }
52
48
  function input(config) {
53
49
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
54
- var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
50
+ var props = _objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
55
51
  type: options.type,
56
52
  minLength: config.minLength,
57
53
  maxLength: config.maxLength,
@@ -71,14 +67,14 @@ function input(config) {
71
67
  return props;
72
68
  }
73
69
  function select(config, options) {
74
- var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
70
+ var props = _objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
75
71
  defaultValue: config.defaultValue,
76
72
  multiple: config.multiple
77
73
  });
78
74
  return props;
79
75
  }
80
76
  function textarea(config, options) {
81
- var props = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getFormControlProps(config, options)), {}, {
77
+ var props = _objectSpread2(_objectSpread2({}, getFormControlProps(config, options)), {}, {
82
78
  defaultValue: config.defaultValue,
83
79
  minLength: config.minLength,
84
80
  maxLength: config.maxLength
@@ -86,12 +82,4 @@ function textarea(config, options) {
86
82
  return props;
87
83
  }
88
84
 
89
- Object.defineProperty(exports, 'INTENT', {
90
- enumerable: true,
91
- get: function () { return dom.INTENT; }
92
- });
93
- exports.VALIDATION_SKIPPED = hooks.VALIDATION_SKIPPED;
94
- exports.VALIDATION_UNDEFINED = hooks.VALIDATION_UNDEFINED;
95
- exports.input = input;
96
- exports.select = select;
97
- exports.textarea = textarea;
85
+ export { input, select, textarea };
package/hooks.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type FieldConstraint, type FieldElement, type FieldsetConstraint, type Submission, type KeysOf, type ResolveType, getFormEncType, getFormMethod } from '@conform-to/dom';
1
+ import { type FieldConstraint, type FieldElement, type FieldsetConstraint, type Submission, type KeysOf, type ResolveType, getFormEncType, getFormMethod, parseIntent } from '@conform-to/dom';
2
2
  import { type FormEvent, type RefObject } from 'react';
3
3
  export type Primitive = null | undefined | string | number | boolean | Date;
4
4
  export interface FieldConfig<Schema> extends FieldConstraint<Schema> {
@@ -211,8 +211,5 @@ export declare function validateConstraint(options: {
211
211
  }) => string[];
212
212
  }): Submission;
213
213
  export declare function reportSubmission(form: HTMLFormElement, submission: Submission): void;
214
- /**
215
- * Check if the current focus is on a intent button.
216
- */
217
- export declare function isFocusedOnIntentButton(form: HTMLFormElement, intent: string): boolean;
214
+ export declare function getScope(intent: ReturnType<typeof parseIntent>): string | null;
218
215
  export {};
package/hooks.js CHANGED
@@ -1,6 +1,10 @@
1
- import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
2
- import { getScope, getFormData, parse, isSubmitting, getFormAction, getFormEncType, getFormMethod, getPaths, getName, isFieldElement, getErrors, getFormControls, getFormElement, parseListCommand, updateList, getValidationMessage, focusFormControl, focusFirstInvalidControl, INTENT, isFocusableFormControl, requestIntent, validate } from '@conform-to/dom';
3
- import { useState, useMemo, useEffect, useRef, useCallback, useLayoutEffect } from 'react';
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
6
+ var dom = require('@conform-to/dom');
7
+ var react = require('react');
4
8
 
5
9
  /**
6
10
  * Normalize error to an array of string.
@@ -13,40 +17,40 @@ function normalizeError(error) {
13
17
  return [].concat(error);
14
18
  }
15
19
  function useNoValidate(defaultNoValidate, validateBeforeHydrate) {
16
- var [noValidate, setNoValidate] = useState(defaultNoValidate || !validateBeforeHydrate);
17
- useEffect(() => {
20
+ var [noValidate, setNoValidate] = react.useState(defaultNoValidate || !validateBeforeHydrate);
21
+ react.useEffect(() => {
18
22
  setNoValidate(true);
19
23
  }, []);
20
24
  return noValidate;
21
25
  }
22
26
  function useFormRef(userProvidedRef) {
23
- var formRef = useRef(null);
27
+ var formRef = react.useRef(null);
24
28
  return userProvidedRef !== null && userProvidedRef !== void 0 ? userProvidedRef : formRef;
25
29
  }
26
30
  function useConfigRef(config) {
27
- var ref = useRef(config);
31
+ var ref = react.useRef(config);
28
32
  useSafeLayoutEffect(() => {
29
33
  ref.current = config;
30
34
  });
31
35
  return ref;
32
36
  }
33
37
  function useFormReporter(ref, lastSubmission) {
34
- var [submission, setSubmission] = useState(lastSubmission);
35
- var report = useCallback((form, submission) => {
38
+ var [submission, setSubmission] = react.useState(lastSubmission);
39
+ var report = react.useCallback((form, submission) => {
36
40
  var event = new CustomEvent('conform', {
37
41
  detail: submission.intent
38
42
  });
39
43
  form.dispatchEvent(event);
40
44
  setSubmission(submission);
41
45
  }, []);
42
- useEffect(() => {
46
+ react.useEffect(() => {
43
47
  var form = ref.current;
44
48
  if (!form || !lastSubmission) {
45
49
  return;
46
50
  }
47
51
  report(form, lastSubmission);
48
52
  }, [ref, lastSubmission, report]);
49
- useEffect(() => {
53
+ react.useEffect(() => {
50
54
  var form = ref.current;
51
55
  if (!form || !submission) {
52
56
  return;
@@ -56,30 +60,30 @@ function useFormReporter(ref, lastSubmission) {
56
60
  return report;
57
61
  }
58
62
  function useFormError(ref, config) {
59
- var [error, setError] = useState(() => {
63
+ var [error, setError] = react.useState(() => {
60
64
  if (!config.initialError) {
61
65
  return {};
62
66
  }
63
67
  var result = {};
64
68
  for (var [name, message] of Object.entries(config.initialError)) {
65
- var paths = getPaths(name);
69
+ var paths = dom.getPaths(name);
66
70
  if (paths.length === 1) {
67
71
  result[paths[0]] = normalizeError(message);
68
72
  }
69
73
  }
70
74
  return result;
71
75
  });
72
- useEffect(() => {
76
+ react.useEffect(() => {
73
77
  var handleInvalid = event => {
74
- var form = getFormElement(ref.current);
78
+ var form = dom.getFormElement(ref.current);
75
79
  var element = event.target;
76
- if (!isFieldElement(element) || element.form !== form || !element.dataset.conformTouched) {
80
+ if (!dom.isFieldElement(element) || element.form !== form || !element.dataset.conformTouched) {
77
81
  return;
78
82
  }
79
83
  var key = element.name;
80
84
  if (config.name) {
81
- var scopePaths = getPaths(config.name);
82
- var fieldPaths = getPaths(element.name);
85
+ var scopePaths = dom.getPaths(config.name);
86
+ var fieldPaths = dom.getPaths(element.name);
83
87
  for (var i = 0; i <= scopePaths.length; i++) {
84
88
  var path = fieldPaths[i];
85
89
  if (i < scopePaths.length) {
@@ -93,17 +97,17 @@ function useFormError(ref, config) {
93
97
  }
94
98
  }
95
99
  setError(prev => {
96
- if (element.validationMessage === getValidationMessage(prev[key])) {
100
+ if (element.validationMessage === dom.getValidationMessage(prev[key])) {
97
101
  return prev;
98
102
  }
99
- return _objectSpread2(_objectSpread2({}, prev), {}, {
100
- [key]: getErrors(element.validationMessage)
103
+ return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, prev), {}, {
104
+ [key]: dom.getErrors(element.validationMessage)
101
105
  });
102
106
  });
103
107
  event.preventDefault();
104
108
  };
105
109
  var handleReset = event => {
106
- var form = getFormElement(ref.current);
110
+ var form = dom.getFormElement(ref.current);
107
111
  if (form && event.target === form) {
108
112
  setError({});
109
113
  }
@@ -131,16 +135,17 @@ function useForm() {
131
135
  var ref = useFormRef(config.ref);
132
136
  var noValidate = useNoValidate(config.noValidate, config.fallbackNative);
133
137
  var report = useFormReporter(ref, config.lastSubmission);
134
- var [errors, setErrors] = useState(() => {
138
+ var [errors, setErrors] = react.useState(() => {
135
139
  var _config$lastSubmissio;
136
140
  return normalizeError((_config$lastSubmissio = config.lastSubmission) === null || _config$lastSubmissio === void 0 ? void 0 : _config$lastSubmissio.error['']);
137
141
  });
138
- var initialError = useMemo(() => {
142
+ var initialError = react.useMemo(() => {
139
143
  var submission = config.lastSubmission;
140
144
  if (!submission) {
141
145
  return {};
142
146
  }
143
- var scope = getScope(submission.intent);
147
+ var intent = dom.parseIntent(submission.intent);
148
+ var scope = getScope(intent);
144
149
  return scope === null ? submission.error : {
145
150
  [scope]: submission.error[scope]
146
151
  };
@@ -151,7 +156,7 @@ function useForm() {
151
156
  constraint: config.constraint,
152
157
  form: config.id
153
158
  });
154
- useEffect(() => {
159
+ react.useEffect(() => {
155
160
  // custom validate handler
156
161
  var createValidateHandler = name => event => {
157
162
  var field = event.target;
@@ -161,22 +166,22 @@ function useForm() {
161
166
  shouldValidate = initialReport === 'onChange' ? 'onInput' : initialReport,
162
167
  shouldRevalidate = 'onInput'
163
168
  } = configRef.current;
164
- if (!form || !isFocusableFormControl(field) || field.form !== form || !field.name) {
169
+ if (!form || !dom.isFocusableFormControl(field) || field.form !== form || !field.name) {
165
170
  return;
166
171
  }
167
172
  if (field.dataset.conformTouched ? shouldRevalidate === name : shouldValidate === name) {
168
- requestIntent(form, validate(field.name));
173
+ dom.requestIntent(form, dom.validate(field.name));
169
174
  }
170
175
  };
171
176
  var handleInvalid = event => {
172
177
  var form = ref.current;
173
178
  var field = event.target;
174
- if (!form || !isFieldElement(field) || field.form !== form || field.name !== FORM_ERROR_ELEMENT_NAME) {
179
+ if (!form || !dom.isFieldElement(field) || field.form !== form || field.name !== FORM_ERROR_ELEMENT_NAME) {
175
180
  return;
176
181
  }
177
182
  event.preventDefault();
178
183
  if (field.dataset.conformTouched) {
179
- setErrors(getErrors(field.validationMessage));
184
+ setErrors(dom.getErrors(field.validationMessage));
180
185
  }
181
186
  };
182
187
  var handleReset = event => {
@@ -186,7 +191,7 @@ function useForm() {
186
191
  }
187
192
 
188
193
  // Reset all field state
189
- for (var element of getFormControls(form)) {
194
+ for (var element of dom.getFormControls(form)) {
190
195
  delete element.dataset.conformTouched;
191
196
  element.setCustomValidity('');
192
197
  }
@@ -221,20 +226,35 @@ function useForm() {
221
226
  }
222
227
  try {
223
228
  var _config$onValidate, _config$onValidate2;
224
- var formData = getFormData(form, submitter);
229
+ var formData = dom.getFormData(form, submitter);
225
230
  var submission = (_config$onValidate = (_config$onValidate2 = config.onValidate) === null || _config$onValidate2 === void 0 ? void 0 : _config$onValidate2.call(config, {
226
231
  form,
227
232
  formData
228
- })) !== null && _config$onValidate !== void 0 ? _config$onValidate : parse(formData);
229
- var messages = Object.entries(submission.error).reduce((messages, _ref2) => {
230
- var [, message] = _ref2;
231
- return messages.concat(normalizeError(message));
232
- }, []);
233
- var shouldValidate = !config.noValidate && !(submitter !== null && submitter !== void 0 && submitter.formNoValidate);
234
- var shouldFallbackToServer = messages.includes(VALIDATION_UNDEFINED);
235
- var hasClientValidation = typeof config.onValidate !== 'undefined';
236
- var isValid = messages.length === 0;
237
- if (hasClientValidation && (isSubmitting(submission.intent) ? shouldValidate && !isValid : !shouldFallbackToServer)) {
233
+ })) !== null && _config$onValidate !== void 0 ? _config$onValidate : dom.parse(formData);
234
+ var {
235
+ errors: _errors,
236
+ shouldServerValidate
237
+ } = Object.entries(submission.error).reduce((result, _ref2) => {
238
+ var [, error] = _ref2;
239
+ for (var message of normalizeError(error)) {
240
+ if (message === VALIDATION_UNDEFINED) {
241
+ result.shouldServerValidate = true;
242
+ } else if (message !== VALIDATION_SKIPPED) {
243
+ result.errors.push(message);
244
+ }
245
+ }
246
+ return result;
247
+ }, {
248
+ errors: [],
249
+ shouldServerValidate: false
250
+ });
251
+ if (
252
+ // has client validation
253
+ typeof config.onValidate !== 'undefined' &&
254
+ // not necessary to validate on the server
255
+ !shouldServerValidate && (
256
+ // client validation failed or non submit intent
257
+ !config.noValidate && !(submitter !== null && submitter !== void 0 && submitter.formNoValidate) && _errors.length > 0 || dom.parseIntent(submission.intent) !== null)) {
238
258
  report(form, submission);
239
259
  event.preventDefault();
240
260
  } else {
@@ -242,9 +262,9 @@ function useForm() {
242
262
  (_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, {
243
263
  formData,
244
264
  submission,
245
- action: getFormAction(nativeEvent),
246
- encType: getFormEncType(nativeEvent),
247
- method: getFormMethod(nativeEvent)
265
+ action: dom.getFormAction(nativeEvent),
266
+ encType: dom.getFormEncType(nativeEvent),
267
+ method: dom.getFormMethod(nativeEvent)
248
268
  });
249
269
  }
250
270
  } catch (e) {
@@ -291,13 +311,13 @@ function useFieldset(ref, config) {
291
311
  var errors = error === null || error === void 0 ? void 0 : error[key];
292
312
  var initialError = Object.entries((_fieldsetConfig$initi = fieldsetConfig.initialError) !== null && _fieldsetConfig$initi !== void 0 ? _fieldsetConfig$initi : {}).reduce((result, _ref3) => {
293
313
  var [name, message] = _ref3;
294
- var [field, ...paths] = getPaths(name);
314
+ var [field, ...paths] = dom.getPaths(name);
295
315
  if (field === key) {
296
- result[getName(paths)] = message;
316
+ result[dom.getName(paths)] = message;
297
317
  }
298
318
  return result;
299
319
  }, {});
300
- var field = _objectSpread2(_objectSpread2({}, constraint), {}, {
320
+ var field = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, constraint), {}, {
301
321
  name: fieldsetConfig.name ? "".concat(fieldsetConfig.name, ".").concat(key) : key,
302
322
  // @ts-expect-error The FieldValue type might need a rework
303
323
  defaultValue: (_fieldsetConfig$defau = fieldsetConfig.defaultValue) === null || _fieldsetConfig$defau === void 0 ? void 0 : _fieldsetConfig$defau[key],
@@ -327,37 +347,33 @@ function useFieldList(ref, config) {
327
347
  initialError: config.initialError,
328
348
  name: config.name
329
349
  });
330
- var [entries, setEntries] = useState(() => {
350
+ var [entries, setEntries] = react.useState(() => {
331
351
  var _config$defaultValue;
332
352
  return Object.entries((_config$defaultValue = config.defaultValue) !== null && _config$defaultValue !== void 0 ? _config$defaultValue : [undefined]);
333
353
  });
334
- useEffect(() => {
354
+ react.useEffect(() => {
335
355
  var conformHandler = event => {
336
- var form = getFormElement(ref.current);
356
+ var form = dom.getFormElement(ref.current);
337
357
  if (!form || event.target !== form) {
338
358
  return;
339
359
  }
340
- var command = parseListCommand(event.detail);
341
- if ((command === null || command === void 0 ? void 0 : command.scope) !== configRef.current.name) {
342
- // Ensure the scope of the listener are limited to specific field name
360
+ var intent = dom.parseIntent(event.detail);
361
+ if ((intent === null || intent === void 0 ? void 0 : intent.type) !== 'list' || (intent === null || intent === void 0 ? void 0 : intent.payload.name) !== configRef.current.name) {
343
362
  return;
344
363
  }
345
364
  setEntries(entries => {
346
- switch (command.type) {
365
+ var list = [...entries];
366
+ switch (intent.payload.operation) {
347
367
  case 'append':
348
368
  case 'prepend':
349
369
  case 'replace':
350
- return updateList([...(entries !== null && entries !== void 0 ? entries : [])], _objectSpread2(_objectSpread2({}, command), {}, {
351
- payload: _objectSpread2(_objectSpread2({}, command.payload), {}, {
352
- defaultValue: ["".concat(Date.now()),
353
- // @ts-expect-error unknown type as it is sent through network
354
- command.payload.defaultValue]
355
- })
370
+ return dom.updateList(list, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, intent.payload), {}, {
371
+ defaultValue: [
372
+ // Generate a random key to avoid conflicts
373
+ crypto.getRandomValues(new Uint32Array(1))[0].toString(36), intent.payload.defaultValue]
356
374
  }));
357
375
  default:
358
- {
359
- return updateList([...(entries !== null && entries !== void 0 ? entries : [])], command);
360
- }
376
+ return dom.updateList(list, intent.payload);
361
377
  }
362
378
  });
363
379
  setError(error => {
@@ -367,28 +383,24 @@ function useFieldList(ref, config) {
367
383
  errorList[key] = messages;
368
384
  }
369
385
  }
370
- switch (command.type) {
386
+ switch (intent.payload.operation) {
371
387
  case 'append':
372
388
  case 'prepend':
373
389
  case 'replace':
374
- errorList = updateList(errorList, _objectSpread2(_objectSpread2({}, command), {}, {
375
- payload: _objectSpread2(_objectSpread2({}, command.payload), {}, {
376
- defaultValue: undefined
377
- })
390
+ errorList = dom.updateList(errorList, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, intent.payload), {}, {
391
+ defaultValue: undefined
378
392
  }));
379
393
  break;
380
394
  default:
381
- {
382
- errorList = updateList(errorList, command);
383
- break;
384
- }
395
+ errorList = dom.updateList(errorList, intent.payload);
396
+ break;
385
397
  }
386
398
  return Object.assign({}, errorList);
387
399
  });
388
400
  };
389
401
  var resetHandler = event => {
390
402
  var _configRef$current$de;
391
- var form = getFormElement(ref.current);
403
+ var form = dom.getFormElement(ref.current);
392
404
  if (!form || event.target !== form) {
393
405
  return;
394
406
  }
@@ -410,9 +422,9 @@ function useFieldList(ref, config) {
410
422
  var errors = error[index];
411
423
  var initialError = Object.entries((_config$initialError = config.initialError) !== null && _config$initialError !== void 0 ? _config$initialError : {}).reduce((result, _ref5) => {
412
424
  var [name, message] = _ref5;
413
- var [field, ...paths] = getPaths(name);
425
+ var [field, ...paths] = dom.getPaths(name);
414
426
  if (field === index) {
415
- result[getName(paths)] = message;
427
+ result[dom.getName(paths)] = message;
416
428
  }
417
429
  return result;
418
430
  }, {});
@@ -429,7 +441,7 @@ function useFieldList(ref, config) {
429
441
  fieldConfig.errorId = "".concat(fieldConfig.id, "-error");
430
442
  fieldConfig.descriptionId = "".concat(fieldConfig.id, "-description");
431
443
  }
432
- return _objectSpread2({
444
+ return _rollupPluginBabelHelpers.objectSpread2({
433
445
  key
434
446
  }, fieldConfig);
435
447
  });
@@ -468,13 +480,13 @@ function setNativeValue(element, value) {
468
480
  * useLayoutEffect is client-only.
469
481
  * This basically makes it a no-op on server
470
482
  */
471
- var useSafeLayoutEffect = typeof document === 'undefined' ? useEffect : useLayoutEffect;
483
+ var useSafeLayoutEffect = typeof document === 'undefined' ? react.useEffect : react.useLayoutEffect;
472
484
  function useInputEvent(options) {
473
- var ref = useRef(null);
485
+ var ref = react.useRef(null);
474
486
  var optionsRef = useConfigRef(options);
475
- var changeDispatched = useRef(false);
476
- var focusDispatched = useRef(false);
477
- var blurDispatched = useRef(false);
487
+ var changeDispatched = react.useRef(false);
488
+ var focusDispatched = react.useRef(false);
489
+ var blurDispatched = react.useRef(false);
478
490
  useSafeLayoutEffect(() => {
479
491
  var getInputElement = () => {
480
492
  var _optionsRef$current$g, _optionsRef$current, _optionsRef$current$g2;
@@ -525,7 +537,7 @@ function useInputEvent(options) {
525
537
  document.removeEventListener('reset', resetHandler);
526
538
  };
527
539
  }, []);
528
- var control = useMemo(() => {
540
+ var control = react.useMemo(() => {
529
541
  var getInputElement = () => {
530
542
  var _optionsRef$current$g3, _optionsRef$current4, _optionsRef$current4$;
531
543
  return (_optionsRef$current$g3 = (_optionsRef$current4 = optionsRef.current) === null || _optionsRef$current4 === void 0 ? void 0 : (_optionsRef$current4$ = _optionsRef$current4.getElement) === null || _optionsRef$current4$ === void 0 ? void 0 : _optionsRef$current4$.call(_optionsRef$current4, ref.current)) !== null && _optionsRef$current$g3 !== void 0 ? _optionsRef$current$g3 : ref.current;
@@ -640,12 +652,12 @@ function validateConstraint(options) {
640
652
  } = _ref6;
641
653
  return defaultErrors;
642
654
  };
643
- return parse(formData, {
655
+ return dom.parse(formData, {
644
656
  resolve(payload, intent) {
645
657
  var error = {};
646
658
  var constraintPattern = /^constraint[A-Z][^A-Z]*$/;
647
659
  var _loop = function _loop(element) {
648
- if (isFieldElement(element)) {
660
+ if (dom.isFieldElement(element)) {
649
661
  var _options$acceptMultip, _options$acceptMultip2;
650
662
  var name = element.name !== FORM_ERROR_ELEMENT_NAME ? element.name : '';
651
663
  var constraint = Object.entries(element.dataset).reduce((result, _ref7) => {
@@ -718,8 +730,9 @@ function reportSubmission(form, submission) {
718
730
  form.appendChild(button);
719
731
  }
720
732
  }
721
- var scope = getScope(submission.intent);
722
- for (var element of getFormControls(form)) {
733
+ var intent = dom.parseIntent(submission.intent);
734
+ var scope = getScope(intent);
735
+ for (var element of dom.getFormControls(form)) {
723
736
  var _elementName = element.name !== FORM_ERROR_ELEMENT_NAME ? element.name : '';
724
737
  var messages = normalizeError(submission.error[_elementName]);
725
738
  if (scope === null || scope === _elementName) {
@@ -729,25 +742,31 @@ function reportSubmission(form, submission) {
729
742
  var invalidEvent = new Event('invalid', {
730
743
  cancelable: true
731
744
  });
732
- element.setCustomValidity(getValidationMessage(messages));
745
+ element.setCustomValidity(dom.getValidationMessage(messages));
733
746
  element.dispatchEvent(invalidEvent);
734
747
  }
735
748
  }
736
- if (isSubmitting(submission.intent) || isFocusedOnIntentButton(form, submission.intent)) {
737
- if (scope) {
738
- focusFormControl(form, scope);
739
- } else {
740
- focusFirstInvalidControl(form);
741
- }
749
+ if (!intent) {
750
+ dom.focusFirstInvalidControl(form);
742
751
  }
743
752
  }
744
-
745
- /**
746
- * Check if the current focus is on a intent button.
747
- */
748
- function isFocusedOnIntentButton(form, intent) {
749
- var element = document.activeElement;
750
- return isFieldElement(element) && element.type === 'submit' && element.form === form && element.name === INTENT && element.value === intent;
753
+ function getScope(intent) {
754
+ switch (intent === null || intent === void 0 ? void 0 : intent.type) {
755
+ case 'validate':
756
+ return intent.payload;
757
+ case 'list':
758
+ return intent.payload.name;
759
+ }
760
+ return null;
751
761
  }
752
762
 
753
- export { FORM_ERROR_ELEMENT_NAME, VALIDATION_SKIPPED, VALIDATION_UNDEFINED, isFocusedOnIntentButton, reportSubmission, useFieldList, useFieldset, useForm, useInputEvent, validateConstraint };
763
+ exports.FORM_ERROR_ELEMENT_NAME = FORM_ERROR_ELEMENT_NAME;
764
+ exports.VALIDATION_SKIPPED = VALIDATION_SKIPPED;
765
+ exports.VALIDATION_UNDEFINED = VALIDATION_UNDEFINED;
766
+ exports.getScope = getScope;
767
+ exports.reportSubmission = reportSubmission;
768
+ exports.useFieldList = useFieldList;
769
+ exports.useFieldset = useFieldset;
770
+ exports.useForm = useForm;
771
+ exports.useInputEvent = useInputEvent;
772
+ exports.validateConstraint = validateConstraint;
@@ -1,10 +1,6 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.cjs');
6
- var dom = require('@conform-to/dom');
7
- var react = require('react');
1
+ import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
+ import { parseIntent, getFormData, parse, getFormAction, getFormEncType, getFormMethod, getPaths, getName, isFieldElement, getErrors, getFormControls, getFormElement, updateList, getValidationMessage, focusFirstInvalidControl, isFocusableFormControl, requestIntent, validate } from '@conform-to/dom';
3
+ import { useState, useMemo, useEffect, useRef, useCallback, useLayoutEffect } from 'react';
8
4
 
9
5
  /**
10
6
  * Normalize error to an array of string.
@@ -17,40 +13,40 @@ function normalizeError(error) {
17
13
  return [].concat(error);
18
14
  }
19
15
  function useNoValidate(defaultNoValidate, validateBeforeHydrate) {
20
- var [noValidate, setNoValidate] = react.useState(defaultNoValidate || !validateBeforeHydrate);
21
- react.useEffect(() => {
16
+ var [noValidate, setNoValidate] = useState(defaultNoValidate || !validateBeforeHydrate);
17
+ useEffect(() => {
22
18
  setNoValidate(true);
23
19
  }, []);
24
20
  return noValidate;
25
21
  }
26
22
  function useFormRef(userProvidedRef) {
27
- var formRef = react.useRef(null);
23
+ var formRef = useRef(null);
28
24
  return userProvidedRef !== null && userProvidedRef !== void 0 ? userProvidedRef : formRef;
29
25
  }
30
26
  function useConfigRef(config) {
31
- var ref = react.useRef(config);
27
+ var ref = useRef(config);
32
28
  useSafeLayoutEffect(() => {
33
29
  ref.current = config;
34
30
  });
35
31
  return ref;
36
32
  }
37
33
  function useFormReporter(ref, lastSubmission) {
38
- var [submission, setSubmission] = react.useState(lastSubmission);
39
- var report = react.useCallback((form, submission) => {
34
+ var [submission, setSubmission] = useState(lastSubmission);
35
+ var report = useCallback((form, submission) => {
40
36
  var event = new CustomEvent('conform', {
41
37
  detail: submission.intent
42
38
  });
43
39
  form.dispatchEvent(event);
44
40
  setSubmission(submission);
45
41
  }, []);
46
- react.useEffect(() => {
42
+ useEffect(() => {
47
43
  var form = ref.current;
48
44
  if (!form || !lastSubmission) {
49
45
  return;
50
46
  }
51
47
  report(form, lastSubmission);
52
48
  }, [ref, lastSubmission, report]);
53
- react.useEffect(() => {
49
+ useEffect(() => {
54
50
  var form = ref.current;
55
51
  if (!form || !submission) {
56
52
  return;
@@ -60,30 +56,30 @@ function useFormReporter(ref, lastSubmission) {
60
56
  return report;
61
57
  }
62
58
  function useFormError(ref, config) {
63
- var [error, setError] = react.useState(() => {
59
+ var [error, setError] = useState(() => {
64
60
  if (!config.initialError) {
65
61
  return {};
66
62
  }
67
63
  var result = {};
68
64
  for (var [name, message] of Object.entries(config.initialError)) {
69
- var paths = dom.getPaths(name);
65
+ var paths = getPaths(name);
70
66
  if (paths.length === 1) {
71
67
  result[paths[0]] = normalizeError(message);
72
68
  }
73
69
  }
74
70
  return result;
75
71
  });
76
- react.useEffect(() => {
72
+ useEffect(() => {
77
73
  var handleInvalid = event => {
78
- var form = dom.getFormElement(ref.current);
74
+ var form = getFormElement(ref.current);
79
75
  var element = event.target;
80
- if (!dom.isFieldElement(element) || element.form !== form || !element.dataset.conformTouched) {
76
+ if (!isFieldElement(element) || element.form !== form || !element.dataset.conformTouched) {
81
77
  return;
82
78
  }
83
79
  var key = element.name;
84
80
  if (config.name) {
85
- var scopePaths = dom.getPaths(config.name);
86
- var fieldPaths = dom.getPaths(element.name);
81
+ var scopePaths = getPaths(config.name);
82
+ var fieldPaths = getPaths(element.name);
87
83
  for (var i = 0; i <= scopePaths.length; i++) {
88
84
  var path = fieldPaths[i];
89
85
  if (i < scopePaths.length) {
@@ -97,17 +93,17 @@ function useFormError(ref, config) {
97
93
  }
98
94
  }
99
95
  setError(prev => {
100
- if (element.validationMessage === dom.getValidationMessage(prev[key])) {
96
+ if (element.validationMessage === getValidationMessage(prev[key])) {
101
97
  return prev;
102
98
  }
103
- return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, prev), {}, {
104
- [key]: dom.getErrors(element.validationMessage)
99
+ return _objectSpread2(_objectSpread2({}, prev), {}, {
100
+ [key]: getErrors(element.validationMessage)
105
101
  });
106
102
  });
107
103
  event.preventDefault();
108
104
  };
109
105
  var handleReset = event => {
110
- var form = dom.getFormElement(ref.current);
106
+ var form = getFormElement(ref.current);
111
107
  if (form && event.target === form) {
112
108
  setError({});
113
109
  }
@@ -135,16 +131,17 @@ function useForm() {
135
131
  var ref = useFormRef(config.ref);
136
132
  var noValidate = useNoValidate(config.noValidate, config.fallbackNative);
137
133
  var report = useFormReporter(ref, config.lastSubmission);
138
- var [errors, setErrors] = react.useState(() => {
134
+ var [errors, setErrors] = useState(() => {
139
135
  var _config$lastSubmissio;
140
136
  return normalizeError((_config$lastSubmissio = config.lastSubmission) === null || _config$lastSubmissio === void 0 ? void 0 : _config$lastSubmissio.error['']);
141
137
  });
142
- var initialError = react.useMemo(() => {
138
+ var initialError = useMemo(() => {
143
139
  var submission = config.lastSubmission;
144
140
  if (!submission) {
145
141
  return {};
146
142
  }
147
- var scope = dom.getScope(submission.intent);
143
+ var intent = parseIntent(submission.intent);
144
+ var scope = getScope(intent);
148
145
  return scope === null ? submission.error : {
149
146
  [scope]: submission.error[scope]
150
147
  };
@@ -155,7 +152,7 @@ function useForm() {
155
152
  constraint: config.constraint,
156
153
  form: config.id
157
154
  });
158
- react.useEffect(() => {
155
+ useEffect(() => {
159
156
  // custom validate handler
160
157
  var createValidateHandler = name => event => {
161
158
  var field = event.target;
@@ -165,22 +162,22 @@ function useForm() {
165
162
  shouldValidate = initialReport === 'onChange' ? 'onInput' : initialReport,
166
163
  shouldRevalidate = 'onInput'
167
164
  } = configRef.current;
168
- if (!form || !dom.isFocusableFormControl(field) || field.form !== form || !field.name) {
165
+ if (!form || !isFocusableFormControl(field) || field.form !== form || !field.name) {
169
166
  return;
170
167
  }
171
168
  if (field.dataset.conformTouched ? shouldRevalidate === name : shouldValidate === name) {
172
- dom.requestIntent(form, dom.validate(field.name));
169
+ requestIntent(form, validate(field.name));
173
170
  }
174
171
  };
175
172
  var handleInvalid = event => {
176
173
  var form = ref.current;
177
174
  var field = event.target;
178
- if (!form || !dom.isFieldElement(field) || field.form !== form || field.name !== FORM_ERROR_ELEMENT_NAME) {
175
+ if (!form || !isFieldElement(field) || field.form !== form || field.name !== FORM_ERROR_ELEMENT_NAME) {
179
176
  return;
180
177
  }
181
178
  event.preventDefault();
182
179
  if (field.dataset.conformTouched) {
183
- setErrors(dom.getErrors(field.validationMessage));
180
+ setErrors(getErrors(field.validationMessage));
184
181
  }
185
182
  };
186
183
  var handleReset = event => {
@@ -190,7 +187,7 @@ function useForm() {
190
187
  }
191
188
 
192
189
  // Reset all field state
193
- for (var element of dom.getFormControls(form)) {
190
+ for (var element of getFormControls(form)) {
194
191
  delete element.dataset.conformTouched;
195
192
  element.setCustomValidity('');
196
193
  }
@@ -225,20 +222,35 @@ function useForm() {
225
222
  }
226
223
  try {
227
224
  var _config$onValidate, _config$onValidate2;
228
- var formData = dom.getFormData(form, submitter);
225
+ var formData = getFormData(form, submitter);
229
226
  var submission = (_config$onValidate = (_config$onValidate2 = config.onValidate) === null || _config$onValidate2 === void 0 ? void 0 : _config$onValidate2.call(config, {
230
227
  form,
231
228
  formData
232
- })) !== null && _config$onValidate !== void 0 ? _config$onValidate : dom.parse(formData);
233
- var messages = Object.entries(submission.error).reduce((messages, _ref2) => {
234
- var [, message] = _ref2;
235
- return messages.concat(normalizeError(message));
236
- }, []);
237
- var shouldValidate = !config.noValidate && !(submitter !== null && submitter !== void 0 && submitter.formNoValidate);
238
- var shouldFallbackToServer = messages.includes(VALIDATION_UNDEFINED);
239
- var hasClientValidation = typeof config.onValidate !== 'undefined';
240
- var isValid = messages.length === 0;
241
- if (hasClientValidation && (dom.isSubmitting(submission.intent) ? shouldValidate && !isValid : !shouldFallbackToServer)) {
229
+ })) !== null && _config$onValidate !== void 0 ? _config$onValidate : parse(formData);
230
+ var {
231
+ errors: _errors,
232
+ shouldServerValidate
233
+ } = Object.entries(submission.error).reduce((result, _ref2) => {
234
+ var [, error] = _ref2;
235
+ for (var message of normalizeError(error)) {
236
+ if (message === VALIDATION_UNDEFINED) {
237
+ result.shouldServerValidate = true;
238
+ } else if (message !== VALIDATION_SKIPPED) {
239
+ result.errors.push(message);
240
+ }
241
+ }
242
+ return result;
243
+ }, {
244
+ errors: [],
245
+ shouldServerValidate: false
246
+ });
247
+ if (
248
+ // has client validation
249
+ typeof config.onValidate !== 'undefined' &&
250
+ // not necessary to validate on the server
251
+ !shouldServerValidate && (
252
+ // client validation failed or non submit intent
253
+ !config.noValidate && !(submitter !== null && submitter !== void 0 && submitter.formNoValidate) && _errors.length > 0 || parseIntent(submission.intent) !== null)) {
242
254
  report(form, submission);
243
255
  event.preventDefault();
244
256
  } else {
@@ -246,9 +258,9 @@ function useForm() {
246
258
  (_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, {
247
259
  formData,
248
260
  submission,
249
- action: dom.getFormAction(nativeEvent),
250
- encType: dom.getFormEncType(nativeEvent),
251
- method: dom.getFormMethod(nativeEvent)
261
+ action: getFormAction(nativeEvent),
262
+ encType: getFormEncType(nativeEvent),
263
+ method: getFormMethod(nativeEvent)
252
264
  });
253
265
  }
254
266
  } catch (e) {
@@ -295,13 +307,13 @@ function useFieldset(ref, config) {
295
307
  var errors = error === null || error === void 0 ? void 0 : error[key];
296
308
  var initialError = Object.entries((_fieldsetConfig$initi = fieldsetConfig.initialError) !== null && _fieldsetConfig$initi !== void 0 ? _fieldsetConfig$initi : {}).reduce((result, _ref3) => {
297
309
  var [name, message] = _ref3;
298
- var [field, ...paths] = dom.getPaths(name);
310
+ var [field, ...paths] = getPaths(name);
299
311
  if (field === key) {
300
- result[dom.getName(paths)] = message;
312
+ result[getName(paths)] = message;
301
313
  }
302
314
  return result;
303
315
  }, {});
304
- var field = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, constraint), {}, {
316
+ var field = _objectSpread2(_objectSpread2({}, constraint), {}, {
305
317
  name: fieldsetConfig.name ? "".concat(fieldsetConfig.name, ".").concat(key) : key,
306
318
  // @ts-expect-error The FieldValue type might need a rework
307
319
  defaultValue: (_fieldsetConfig$defau = fieldsetConfig.defaultValue) === null || _fieldsetConfig$defau === void 0 ? void 0 : _fieldsetConfig$defau[key],
@@ -331,37 +343,33 @@ function useFieldList(ref, config) {
331
343
  initialError: config.initialError,
332
344
  name: config.name
333
345
  });
334
- var [entries, setEntries] = react.useState(() => {
346
+ var [entries, setEntries] = useState(() => {
335
347
  var _config$defaultValue;
336
348
  return Object.entries((_config$defaultValue = config.defaultValue) !== null && _config$defaultValue !== void 0 ? _config$defaultValue : [undefined]);
337
349
  });
338
- react.useEffect(() => {
350
+ useEffect(() => {
339
351
  var conformHandler = event => {
340
- var form = dom.getFormElement(ref.current);
352
+ var form = getFormElement(ref.current);
341
353
  if (!form || event.target !== form) {
342
354
  return;
343
355
  }
344
- var command = dom.parseListCommand(event.detail);
345
- if ((command === null || command === void 0 ? void 0 : command.scope) !== configRef.current.name) {
346
- // Ensure the scope of the listener are limited to specific field name
356
+ var intent = parseIntent(event.detail);
357
+ if ((intent === null || intent === void 0 ? void 0 : intent.type) !== 'list' || (intent === null || intent === void 0 ? void 0 : intent.payload.name) !== configRef.current.name) {
347
358
  return;
348
359
  }
349
360
  setEntries(entries => {
350
- switch (command.type) {
361
+ var list = [...entries];
362
+ switch (intent.payload.operation) {
351
363
  case 'append':
352
364
  case 'prepend':
353
365
  case 'replace':
354
- return dom.updateList([...(entries !== null && entries !== void 0 ? entries : [])], _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, command), {}, {
355
- payload: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, command.payload), {}, {
356
- defaultValue: ["".concat(Date.now()),
357
- // @ts-expect-error unknown type as it is sent through network
358
- command.payload.defaultValue]
359
- })
366
+ return updateList(list, _objectSpread2(_objectSpread2({}, intent.payload), {}, {
367
+ defaultValue: [
368
+ // Generate a random key to avoid conflicts
369
+ crypto.getRandomValues(new Uint32Array(1))[0].toString(36), intent.payload.defaultValue]
360
370
  }));
361
371
  default:
362
- {
363
- return dom.updateList([...(entries !== null && entries !== void 0 ? entries : [])], command);
364
- }
372
+ return updateList(list, intent.payload);
365
373
  }
366
374
  });
367
375
  setError(error => {
@@ -371,28 +379,24 @@ function useFieldList(ref, config) {
371
379
  errorList[key] = messages;
372
380
  }
373
381
  }
374
- switch (command.type) {
382
+ switch (intent.payload.operation) {
375
383
  case 'append':
376
384
  case 'prepend':
377
385
  case 'replace':
378
- errorList = dom.updateList(errorList, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, command), {}, {
379
- payload: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, command.payload), {}, {
380
- defaultValue: undefined
381
- })
386
+ errorList = updateList(errorList, _objectSpread2(_objectSpread2({}, intent.payload), {}, {
387
+ defaultValue: undefined
382
388
  }));
383
389
  break;
384
390
  default:
385
- {
386
- errorList = dom.updateList(errorList, command);
387
- break;
388
- }
391
+ errorList = updateList(errorList, intent.payload);
392
+ break;
389
393
  }
390
394
  return Object.assign({}, errorList);
391
395
  });
392
396
  };
393
397
  var resetHandler = event => {
394
398
  var _configRef$current$de;
395
- var form = dom.getFormElement(ref.current);
399
+ var form = getFormElement(ref.current);
396
400
  if (!form || event.target !== form) {
397
401
  return;
398
402
  }
@@ -414,9 +418,9 @@ function useFieldList(ref, config) {
414
418
  var errors = error[index];
415
419
  var initialError = Object.entries((_config$initialError = config.initialError) !== null && _config$initialError !== void 0 ? _config$initialError : {}).reduce((result, _ref5) => {
416
420
  var [name, message] = _ref5;
417
- var [field, ...paths] = dom.getPaths(name);
421
+ var [field, ...paths] = getPaths(name);
418
422
  if (field === index) {
419
- result[dom.getName(paths)] = message;
423
+ result[getName(paths)] = message;
420
424
  }
421
425
  return result;
422
426
  }, {});
@@ -433,7 +437,7 @@ function useFieldList(ref, config) {
433
437
  fieldConfig.errorId = "".concat(fieldConfig.id, "-error");
434
438
  fieldConfig.descriptionId = "".concat(fieldConfig.id, "-description");
435
439
  }
436
- return _rollupPluginBabelHelpers.objectSpread2({
440
+ return _objectSpread2({
437
441
  key
438
442
  }, fieldConfig);
439
443
  });
@@ -472,13 +476,13 @@ function setNativeValue(element, value) {
472
476
  * useLayoutEffect is client-only.
473
477
  * This basically makes it a no-op on server
474
478
  */
475
- var useSafeLayoutEffect = typeof document === 'undefined' ? react.useEffect : react.useLayoutEffect;
479
+ var useSafeLayoutEffect = typeof document === 'undefined' ? useEffect : useLayoutEffect;
476
480
  function useInputEvent(options) {
477
- var ref = react.useRef(null);
481
+ var ref = useRef(null);
478
482
  var optionsRef = useConfigRef(options);
479
- var changeDispatched = react.useRef(false);
480
- var focusDispatched = react.useRef(false);
481
- var blurDispatched = react.useRef(false);
483
+ var changeDispatched = useRef(false);
484
+ var focusDispatched = useRef(false);
485
+ var blurDispatched = useRef(false);
482
486
  useSafeLayoutEffect(() => {
483
487
  var getInputElement = () => {
484
488
  var _optionsRef$current$g, _optionsRef$current, _optionsRef$current$g2;
@@ -529,7 +533,7 @@ function useInputEvent(options) {
529
533
  document.removeEventListener('reset', resetHandler);
530
534
  };
531
535
  }, []);
532
- var control = react.useMemo(() => {
536
+ var control = useMemo(() => {
533
537
  var getInputElement = () => {
534
538
  var _optionsRef$current$g3, _optionsRef$current4, _optionsRef$current4$;
535
539
  return (_optionsRef$current$g3 = (_optionsRef$current4 = optionsRef.current) === null || _optionsRef$current4 === void 0 ? void 0 : (_optionsRef$current4$ = _optionsRef$current4.getElement) === null || _optionsRef$current4$ === void 0 ? void 0 : _optionsRef$current4$.call(_optionsRef$current4, ref.current)) !== null && _optionsRef$current$g3 !== void 0 ? _optionsRef$current$g3 : ref.current;
@@ -644,12 +648,12 @@ function validateConstraint(options) {
644
648
  } = _ref6;
645
649
  return defaultErrors;
646
650
  };
647
- return dom.parse(formData, {
651
+ return parse(formData, {
648
652
  resolve(payload, intent) {
649
653
  var error = {};
650
654
  var constraintPattern = /^constraint[A-Z][^A-Z]*$/;
651
655
  var _loop = function _loop(element) {
652
- if (dom.isFieldElement(element)) {
656
+ if (isFieldElement(element)) {
653
657
  var _options$acceptMultip, _options$acceptMultip2;
654
658
  var name = element.name !== FORM_ERROR_ELEMENT_NAME ? element.name : '';
655
659
  var constraint = Object.entries(element.dataset).reduce((result, _ref7) => {
@@ -722,8 +726,9 @@ function reportSubmission(form, submission) {
722
726
  form.appendChild(button);
723
727
  }
724
728
  }
725
- var scope = dom.getScope(submission.intent);
726
- for (var element of dom.getFormControls(form)) {
729
+ var intent = parseIntent(submission.intent);
730
+ var scope = getScope(intent);
731
+ for (var element of getFormControls(form)) {
727
732
  var _elementName = element.name !== FORM_ERROR_ELEMENT_NAME ? element.name : '';
728
733
  var messages = normalizeError(submission.error[_elementName]);
729
734
  if (scope === null || scope === _elementName) {
@@ -733,34 +738,22 @@ function reportSubmission(form, submission) {
733
738
  var invalidEvent = new Event('invalid', {
734
739
  cancelable: true
735
740
  });
736
- element.setCustomValidity(dom.getValidationMessage(messages));
741
+ element.setCustomValidity(getValidationMessage(messages));
737
742
  element.dispatchEvent(invalidEvent);
738
743
  }
739
744
  }
740
- if (dom.isSubmitting(submission.intent) || isFocusedOnIntentButton(form, submission.intent)) {
741
- if (scope) {
742
- dom.focusFormControl(form, scope);
743
- } else {
744
- dom.focusFirstInvalidControl(form);
745
- }
745
+ if (!intent) {
746
+ focusFirstInvalidControl(form);
746
747
  }
747
748
  }
748
-
749
- /**
750
- * Check if the current focus is on a intent button.
751
- */
752
- function isFocusedOnIntentButton(form, intent) {
753
- var element = document.activeElement;
754
- return dom.isFieldElement(element) && element.type === 'submit' && element.form === form && element.name === dom.INTENT && element.value === intent;
749
+ function getScope(intent) {
750
+ switch (intent === null || intent === void 0 ? void 0 : intent.type) {
751
+ case 'validate':
752
+ return intent.payload;
753
+ case 'list':
754
+ return intent.payload.name;
755
+ }
756
+ return null;
755
757
  }
756
758
 
757
- exports.FORM_ERROR_ELEMENT_NAME = FORM_ERROR_ELEMENT_NAME;
758
- exports.VALIDATION_SKIPPED = VALIDATION_SKIPPED;
759
- exports.VALIDATION_UNDEFINED = VALIDATION_UNDEFINED;
760
- exports.isFocusedOnIntentButton = isFocusedOnIntentButton;
761
- exports.reportSubmission = reportSubmission;
762
- exports.useFieldList = useFieldList;
763
- exports.useFieldset = useFieldset;
764
- exports.useForm = useForm;
765
- exports.useInputEvent = useInputEvent;
766
- exports.validateConstraint = validateConstraint;
759
+ export { FORM_ERROR_ELEMENT_NAME, VALIDATION_SKIPPED, VALIDATION_UNDEFINED, getScope, reportSubmission, useFieldList, useFieldset, useForm, useInputEvent, validateConstraint };
package/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { type FieldsetConstraint, type Submission, parse, list, validate, requestIntent, isFieldElement, } from '@conform-to/dom';
2
- export { type Fieldset, type FieldConfig, type FieldsetConfig, type FormConfig, useForm, useFieldset, useFieldList, useInputEvent, validateConstraint, } from './hooks';
3
- export * as conform from './helpers';
2
+ export { type Fieldset, type FieldConfig, type FieldsetConfig, type FormConfig, useForm, useFieldset, useFieldList, useInputEvent, validateConstraint, } from './hooks.js';
3
+ export * as conform from './helpers.js';
package/index.js CHANGED
@@ -1,4 +1,36 @@
1
- export { isFieldElement, list, parse, requestIntent, validate } from '@conform-to/dom';
2
- export { useFieldList, useFieldset, useForm, useInputEvent, validateConstraint } from './hooks.js';
3
- import * as helpers from './helpers.js';
4
- export { helpers as conform };
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var dom = require('@conform-to/dom');
6
+ var hooks = require('./hooks.js');
7
+ var helpers = require('./helpers.js');
8
+
9
+
10
+
11
+ Object.defineProperty(exports, 'isFieldElement', {
12
+ enumerable: true,
13
+ get: function () { return dom.isFieldElement; }
14
+ });
15
+ Object.defineProperty(exports, 'list', {
16
+ enumerable: true,
17
+ get: function () { return dom.list; }
18
+ });
19
+ Object.defineProperty(exports, 'parse', {
20
+ enumerable: true,
21
+ get: function () { return dom.parse; }
22
+ });
23
+ Object.defineProperty(exports, 'requestIntent', {
24
+ enumerable: true,
25
+ get: function () { return dom.requestIntent; }
26
+ });
27
+ Object.defineProperty(exports, 'validate', {
28
+ enumerable: true,
29
+ get: function () { return dom.validate; }
30
+ });
31
+ exports.useFieldList = hooks.useFieldList;
32
+ exports.useFieldset = hooks.useFieldset;
33
+ exports.useForm = hooks.useForm;
34
+ exports.useInputEvent = hooks.useInputEvent;
35
+ exports.validateConstraint = hooks.validateConstraint;
36
+ exports.conform = helpers;
package/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ export { isFieldElement, list, parse, requestIntent, validate } from '@conform-to/dom';
2
+ export { useFieldList, useFieldset, useForm, useInputEvent, validateConstraint } from './hooks.mjs';
3
+ import * as helpers from './helpers.mjs';
4
+ export { helpers as conform };
package/package.json CHANGED
@@ -3,18 +3,17 @@
3
3
  "description": "Conform view adapter for react",
4
4
  "homepage": "https://conform.guide",
5
5
  "license": "MIT",
6
- "version": "0.7.0-pre.0",
7
- "type": "module",
8
- "main": "index.cjs",
9
- "module": "index.js",
6
+ "version": "0.7.0-pre.2",
7
+ "main": "index.js",
8
+ "module": "index.mjs",
10
9
  "types": "index.d.ts",
11
10
  "exports": {
12
11
  ".": {
13
12
  "types": "./index.d.ts",
14
- "module": "./index.js",
15
- "import": "./index.js",
16
- "require": "./index.cjs",
17
- "default": "./index.js"
13
+ "module": "./index.mjs",
14
+ "import": "./index.mjs",
15
+ "require": "./index.js",
16
+ "default": "./index.mjs"
18
17
  }
19
18
  },
20
19
  "repository": {
@@ -31,7 +30,7 @@
31
30
  "url": "https://github.com/edmundhung/conform/issues"
32
31
  },
33
32
  "dependencies": {
34
- "@conform-to/dom": "0.7.0-pre.0"
33
+ "@conform-to/dom": "0.7.0-pre.2"
35
34
  },
36
35
  "peerDependencies": {
37
36
  "react": ">=16.8"
package/index.cjs DELETED
@@ -1,36 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var dom = require('@conform-to/dom');
6
- var hooks = require('./hooks.cjs');
7
- var helpers = require('./helpers.cjs');
8
-
9
-
10
-
11
- Object.defineProperty(exports, 'isFieldElement', {
12
- enumerable: true,
13
- get: function () { return dom.isFieldElement; }
14
- });
15
- Object.defineProperty(exports, 'list', {
16
- enumerable: true,
17
- get: function () { return dom.list; }
18
- });
19
- Object.defineProperty(exports, 'parse', {
20
- enumerable: true,
21
- get: function () { return dom.parse; }
22
- });
23
- Object.defineProperty(exports, 'requestIntent', {
24
- enumerable: true,
25
- get: function () { return dom.requestIntent; }
26
- });
27
- Object.defineProperty(exports, 'validate', {
28
- enumerable: true,
29
- get: function () { return dom.validate; }
30
- });
31
- exports.useFieldList = hooks.useFieldList;
32
- exports.useFieldset = hooks.useFieldset;
33
- exports.useForm = hooks.useForm;
34
- exports.useInputEvent = hooks.useInputEvent;
35
- exports.validateConstraint = hooks.validateConstraint;
36
- exports.conform = helpers;