@conform-to/dom 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.
@@ -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/dom.d.ts CHANGED
@@ -49,7 +49,3 @@ export declare function requestSubmit(form: HTMLFormElement, submitter: Submitte
49
49
  * Focus on the first invalid form control in the form
50
50
  */
51
51
  export declare function focusFirstInvalidControl(form: HTMLFormElement): void;
52
- /**
53
- * Focus on the first form control with the provided name
54
- */
55
- export declare function focusFormControl(form: HTMLFormElement, name: string): void;
package/dom.js CHANGED
@@ -1,3 +1,7 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
1
5
  /**
2
6
  * A type guard to check if the provided reference is a form control element, including
3
7
  * `input`, `select`, `textarea` or `button`
@@ -136,20 +140,13 @@ function focusFirstInvalidControl(form) {
136
140
  }
137
141
  }
138
142
 
139
- /**
140
- * Focus on the first form control with the provided name
141
- */
142
- function focusFormControl(form, name) {
143
- var element = form.elements.namedItem(name);
144
- if (!element) {
145
- return;
146
- }
147
- if (element instanceof RadioNodeList) {
148
- element = element.item(0);
149
- }
150
- if (isFocusableFormControl(element)) {
151
- element.focus();
152
- }
153
- }
154
-
155
- export { createSubmitter, focusFirstInvalidControl, focusFormControl, getFormAction, getFormControls, getFormElement, getFormEncType, getFormMethod, isFocusableFormControl, isFormControl, requestSubmit };
143
+ exports.createSubmitter = createSubmitter;
144
+ exports.focusFirstInvalidControl = focusFirstInvalidControl;
145
+ exports.getFormAction = getFormAction;
146
+ exports.getFormControls = getFormControls;
147
+ exports.getFormElement = getFormElement;
148
+ exports.getFormEncType = getFormEncType;
149
+ exports.getFormMethod = getFormMethod;
150
+ exports.isFocusableFormControl = isFocusableFormControl;
151
+ exports.isFormControl = isFormControl;
152
+ exports.requestSubmit = requestSubmit;
@@ -1,7 +1,3 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
1
  /**
6
2
  * A type guard to check if the provided reference is a form control element, including
7
3
  * `input`, `select`, `textarea` or `button`
@@ -140,30 +136,4 @@ function focusFirstInvalidControl(form) {
140
136
  }
141
137
  }
142
138
 
143
- /**
144
- * Focus on the first form control with the provided name
145
- */
146
- function focusFormControl(form, name) {
147
- var element = form.elements.namedItem(name);
148
- if (!element) {
149
- return;
150
- }
151
- if (element instanceof RadioNodeList) {
152
- element = element.item(0);
153
- }
154
- if (isFocusableFormControl(element)) {
155
- element.focus();
156
- }
157
- }
158
-
159
- exports.createSubmitter = createSubmitter;
160
- exports.focusFirstInvalidControl = focusFirstInvalidControl;
161
- exports.focusFormControl = focusFormControl;
162
- exports.getFormAction = getFormAction;
163
- exports.getFormControls = getFormControls;
164
- exports.getFormElement = getFormElement;
165
- exports.getFormEncType = getFormEncType;
166
- exports.getFormMethod = getFormMethod;
167
- exports.isFocusableFormControl = isFocusableFormControl;
168
- exports.isFormControl = isFormControl;
169
- exports.requestSubmit = requestSubmit;
139
+ export { createSubmitter, focusFirstInvalidControl, getFormAction, getFormControls, getFormElement, getFormEncType, getFormMethod, isFocusableFormControl, isFormControl, requestSubmit };
package/formdata.d.ts CHANGED
@@ -28,7 +28,7 @@ export declare function setValue(target: any, name: string, valueFn: (prev?: unk
28
28
  /**
29
29
  * Resolves the payload into a plain object based on the JS syntax convention
30
30
  */
31
- export declare function resolve(payload: FormData | URLSearchParams): {};
31
+ export declare function resolve(payload: FormData | URLSearchParams, ignoreKeys?: string[]): {};
32
32
  /**
33
33
  * Format the error messages into a validation message
34
34
  */
package/formdata.js CHANGED
@@ -1,3 +1,7 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
1
5
  /**
2
6
  * A ponyfill-like helper to get the form data with the submitter value.
3
7
  * It does not respect the tree order nor handles the image input.
@@ -78,10 +82,13 @@ function setValue(target, name, valueFn) {
78
82
  /**
79
83
  * Resolves the payload into a plain object based on the JS syntax convention
80
84
  */
81
- function resolve(payload) {
85
+ function resolve(payload, ignoreKeys) {
82
86
  var data = {};
83
87
  var _loop = function _loop(value) {
84
- setValue(data, name, prev => {
88
+ if (ignoreKeys !== null && ignoreKeys !== void 0 && ignoreKeys.includes(key)) {
89
+ return "continue";
90
+ }
91
+ setValue(data, key, prev => {
85
92
  if (!prev) {
86
93
  return value;
87
94
  } else if (Array.isArray(prev)) {
@@ -91,8 +98,9 @@ function resolve(payload) {
91
98
  }
92
99
  });
93
100
  };
94
- for (var [name, value] of payload.entries()) {
95
- _loop(value);
101
+ for (var [key, value] of payload.entries()) {
102
+ var _ret = _loop(value);
103
+ if (_ret === "continue") continue;
96
104
  }
97
105
  return data;
98
106
  }
@@ -114,4 +122,10 @@ function getErrors(validationMessage) {
114
122
  return validationMessage.split(String.fromCharCode(31));
115
123
  }
116
124
 
117
- export { formatPaths, getErrors, getFormData, getPaths, getValidationMessage, resolve, setValue };
125
+ exports.formatPaths = formatPaths;
126
+ exports.getErrors = getErrors;
127
+ exports.getFormData = getFormData;
128
+ exports.getPaths = getPaths;
129
+ exports.getValidationMessage = getValidationMessage;
130
+ exports.resolve = resolve;
131
+ exports.setValue = setValue;
@@ -1,7 +1,3 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
1
  /**
6
2
  * A ponyfill-like helper to get the form data with the submitter value.
7
3
  * It does not respect the tree order nor handles the image input.
@@ -82,10 +78,13 @@ function setValue(target, name, valueFn) {
82
78
  /**
83
79
  * Resolves the payload into a plain object based on the JS syntax convention
84
80
  */
85
- function resolve(payload) {
81
+ function resolve(payload, ignoreKeys) {
86
82
  var data = {};
87
83
  var _loop = function _loop(value) {
88
- setValue(data, name, prev => {
84
+ if (ignoreKeys !== null && ignoreKeys !== void 0 && ignoreKeys.includes(key)) {
85
+ return "continue";
86
+ }
87
+ setValue(data, key, prev => {
89
88
  if (!prev) {
90
89
  return value;
91
90
  } else if (Array.isArray(prev)) {
@@ -95,8 +94,9 @@ function resolve(payload) {
95
94
  }
96
95
  });
97
96
  };
98
- for (var [name, value] of payload.entries()) {
99
- _loop(value);
97
+ for (var [key, value] of payload.entries()) {
98
+ var _ret = _loop(value);
99
+ if (_ret === "continue") continue;
100
100
  }
101
101
  return data;
102
102
  }
@@ -118,10 +118,4 @@ function getErrors(validationMessage) {
118
118
  return validationMessage.split(String.fromCharCode(31));
119
119
  }
120
120
 
121
- exports.formatPaths = formatPaths;
122
- exports.getErrors = getErrors;
123
- exports.getFormData = getFormData;
124
- exports.getPaths = getPaths;
125
- exports.getValidationMessage = getValidationMessage;
126
- exports.resolve = resolve;
127
- exports.setValue = setValue;
121
+ export { formatPaths, getErrors, getFormData, getPaths, getValidationMessage, resolve, setValue };
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { type FormControl as FieldElement, isFormControl as isFieldElement, isFocusableFormControl, getFormAction, getFormControls, getFormElement, getFormEncType, getFormMethod, focusFirstInvalidControl, focusFormControl, createSubmitter, requestSubmit, } from './dom';
2
- export { formatPaths as getName, getPaths, getFormData, getValidationMessage, getErrors, } from './formdata';
3
- export { type ListCommand, INTENT, getScope, isSubmitting, validate, list, parseListCommand, updateList, requestIntent, } from './intent';
4
- export { type Submission, parse } from './parse';
5
- export { type FieldConstraint, type FieldsetConstraint, type ResolveType, type KeysOf, } from './types';
1
+ export { type FormControl as FieldElement, isFormControl as isFieldElement, isFocusableFormControl, getFormAction, getFormControls, getFormElement, getFormEncType, getFormMethod, focusFirstInvalidControl, createSubmitter, requestSubmit, } from './dom.js';
2
+ export { formatPaths as getName, getPaths, getFormData, getValidationMessage, getErrors, } from './formdata.js';
3
+ export { INTENT, getIntent, parseIntent, validate, list, updateList, requestIntent, } from './intent.js';
4
+ export { type Submission, parse } from './parse.js';
5
+ export { type FieldConstraint, type FieldsetConstraint, type ResolveType, type KeysOf, } from './types.js';
package/index.js CHANGED
@@ -1,4 +1,34 @@
1
- export { createSubmitter, focusFirstInvalidControl, focusFormControl, getFormAction, getFormControls, getFormElement, getFormEncType, getFormMethod, isFormControl as isFieldElement, isFocusableFormControl, requestSubmit } from './dom.js';
2
- export { getErrors, getFormData, formatPaths as getName, getPaths, getValidationMessage } from './formdata.js';
3
- export { INTENT, getScope, isSubmitting, list, parseListCommand, requestIntent, updateList, validate } from './intent.js';
4
- export { parse } from './parse.js';
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var dom = require('./dom.js');
6
+ var formdata = require('./formdata.js');
7
+ var intent = require('./intent.js');
8
+ var parse = require('./parse.js');
9
+
10
+
11
+
12
+ exports.createSubmitter = dom.createSubmitter;
13
+ exports.focusFirstInvalidControl = dom.focusFirstInvalidControl;
14
+ exports.getFormAction = dom.getFormAction;
15
+ exports.getFormControls = dom.getFormControls;
16
+ exports.getFormElement = dom.getFormElement;
17
+ exports.getFormEncType = dom.getFormEncType;
18
+ exports.getFormMethod = dom.getFormMethod;
19
+ exports.isFieldElement = dom.isFormControl;
20
+ exports.isFocusableFormControl = dom.isFocusableFormControl;
21
+ exports.requestSubmit = dom.requestSubmit;
22
+ exports.getErrors = formdata.getErrors;
23
+ exports.getFormData = formdata.getFormData;
24
+ exports.getName = formdata.formatPaths;
25
+ exports.getPaths = formdata.getPaths;
26
+ exports.getValidationMessage = formdata.getValidationMessage;
27
+ exports.INTENT = intent.INTENT;
28
+ exports.getIntent = intent.getIntent;
29
+ exports.list = intent.list;
30
+ exports.parseIntent = intent.parseIntent;
31
+ exports.requestIntent = intent.requestIntent;
32
+ exports.updateList = intent.updateList;
33
+ exports.validate = intent.validate;
34
+ exports.parse = parse.parse;
package/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ export { createSubmitter, focusFirstInvalidControl, getFormAction, getFormControls, getFormElement, getFormEncType, getFormMethod, isFormControl as isFieldElement, isFocusableFormControl, requestSubmit } from './dom.mjs';
2
+ export { getErrors, getFormData, formatPaths as getName, getPaths, getValidationMessage } from './formdata.mjs';
3
+ export { INTENT, getIntent, list, parseIntent, requestIntent, updateList, validate } from './intent.mjs';
4
+ export { parse } from './parse.mjs';
package/intent.d.ts CHANGED
@@ -3,63 +3,57 @@ export interface IntentButtonProps {
3
3
  value: string;
4
4
  formNoValidate?: boolean;
5
5
  }
6
- export type ListCommand<Schema = unknown> = {
7
- type: 'prepend';
8
- scope: string;
9
- payload: {
10
- defaultValue: Schema;
11
- };
6
+ export type ListIntentPayload<Schema = unknown> = {
7
+ name: string;
8
+ operation: 'prepend';
9
+ defaultValue?: Schema;
12
10
  } | {
13
- type: 'append';
14
- scope: string;
15
- payload: {
16
- defaultValue: Schema;
17
- };
11
+ name: string;
12
+ operation: 'append';
13
+ defaultValue?: Schema;
18
14
  } | {
19
- type: 'replace';
20
- scope: string;
21
- payload: {
22
- defaultValue: Schema;
23
- index: number;
24
- };
15
+ name: string;
16
+ operation: 'replace';
17
+ defaultValue: Schema;
18
+ index: number;
25
19
  } | {
26
- type: 'remove';
27
- scope: string;
28
- payload: {
29
- index: number;
30
- };
20
+ name: string;
21
+ operation: 'remove';
22
+ index: number;
31
23
  } | {
32
- type: 'reorder';
33
- scope: string;
34
- payload: {
35
- from: number;
36
- to: number;
37
- };
24
+ name: string;
25
+ operation: 'reorder';
26
+ from: number;
27
+ to: number;
38
28
  };
39
- export interface ListCommandButtonBuilder {
40
- append<Schema>(name: string, payload?: {
41
- defaultValue: Schema;
42
- }): IntentButtonProps;
43
- prepend<Schema>(name: string, payload?: {
44
- defaultValue: Schema;
45
- }): IntentButtonProps;
46
- replace<Schema>(name: string, payload: {
47
- defaultValue: Schema;
29
+ /**
30
+ * Helpers to configure an intent button for modifying a list
31
+ *
32
+ * @see https://conform.guide/api/react#list
33
+ */
34
+ export declare const list: {
35
+ prepend: <Schema>(name: string, payload?: {
36
+ defaultValue?: Schema | undefined;
37
+ } | undefined) => IntentButtonProps;
38
+ append: <Schema_1>(name: string, payload?: {
39
+ defaultValue?: Schema_1 | undefined;
40
+ } | undefined) => IntentButtonProps;
41
+ replace: <Schema_2>(name: string, payload: {
42
+ defaultValue: Schema_2;
48
43
  index: number;
49
- }): IntentButtonProps;
50
- remove(name: string, payload: {
44
+ }) => IntentButtonProps;
45
+ remove: <Schema_3>(name: string, payload: {
51
46
  index: number;
52
- }): IntentButtonProps;
53
- reorder(name: string, payload: {
47
+ }) => IntentButtonProps;
48
+ reorder: <Schema_4>(name: string, payload: {
54
49
  from: number;
55
50
  to: number;
56
- }): IntentButtonProps;
57
- }
51
+ }) => IntentButtonProps;
52
+ };
58
53
  export declare const INTENT = "__intent__";
59
54
  /**
60
- *
61
- * @param payload
62
- * @returns
55
+ * Returns the intent from the form data or search params.
56
+ * It throws an error if multiple intent is set.
63
57
  */
64
58
  export declare function getIntent(payload: FormData | URLSearchParams): string;
65
59
  /**
@@ -67,18 +61,16 @@ export declare function getIntent(payload: FormData | URLSearchParams): string;
67
61
  *
68
62
  * @see https://conform.guide/api/react#validate
69
63
  */
70
- export declare function validate(field?: string): IntentButtonProps;
71
- export declare function requestIntent(form: HTMLFormElement | undefined, buttonProps: {
64
+ export declare function validate(field: string): IntentButtonProps;
65
+ export declare function requestIntent(form: HTMLFormElement | null | undefined, buttonProps: {
72
66
  value: string;
73
67
  formNoValidate?: boolean;
74
68
  }): void;
75
- /**
76
- * Helpers to configure an intent button for modifying a list
77
- *
78
- * @see https://conform.guide/api/react#list
79
- */
80
- export declare const list: ListCommandButtonBuilder;
81
- export declare function isSubmitting(intent: string): boolean;
82
- export declare function getScope(intent: string): string | null;
83
- export declare function parseListCommand<Schema = unknown>(intent: string): ListCommand<Schema> | null;
84
- export declare function updateList<Schema>(list: Array<Schema>, command: ListCommand<Schema>): Array<Schema>;
69
+ export declare function parseIntent<Schema>(intent: string): {
70
+ type: 'validate';
71
+ payload: string;
72
+ } | {
73
+ type: 'list';
74
+ payload: ListIntentPayload<Schema>;
75
+ } | null;
76
+ export declare function updateList<Schema>(list: Array<Schema>, payload: ListIntentPayload<Schema>): Array<Schema>;
package/intent.js CHANGED
@@ -1,21 +1,48 @@
1
- import { createSubmitter, requestSubmit } from './dom.js';
1
+ 'use strict';
2
2
 
3
- var INTENT = '__intent__';
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
6
+ var dom = require('./dom.js');
4
7
 
5
8
  /**
9
+ * Helpers to configure an intent button for modifying a list
6
10
  *
7
- * @param payload
8
- * @returns
11
+ * @see https://conform.guide/api/react#list
12
+ */
13
+ var list = new Proxy({}, {
14
+ get(_target, operation) {
15
+ return function (name) {
16
+ var payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
17
+ return {
18
+ name: INTENT,
19
+ value: "list/".concat(JSON.stringify(_rollupPluginBabelHelpers.objectSpread2({
20
+ name,
21
+ operation
22
+ }, payload))),
23
+ formNoValidate: true
24
+ };
25
+ };
26
+ }
27
+ });
28
+ var INTENT = '__intent__';
29
+
30
+ /**
31
+ * Returns the intent from the form data or search params.
32
+ * It throws an error if multiple intent is set.
9
33
  */
10
34
  function getIntent(payload) {
11
35
  if (!payload.has(INTENT)) {
12
36
  return 'submit';
13
37
  }
14
- var [intent, ...rest] = payload.getAll(INTENT);
15
- if (typeof intent !== 'string' || rest.length > 0) {
38
+ var [intent, secondIntent, ...rest] = payload.getAll(INTENT);
39
+
40
+ // The submitter value is included in the formData directly on Safari 15.6.
41
+ // This causes the intent to be duplicated in the payload.
42
+ // We will ignore the second intent if it is the same as the first one.
43
+ if (typeof intent !== 'string' || secondIntent && intent !== secondIntent || rest.length > 0) {
16
44
  throw new Error('The intent could only be set on a button');
17
45
  }
18
- payload.delete(INTENT);
19
46
  return intent;
20
47
  }
21
48
 
@@ -27,7 +54,7 @@ function getIntent(payload) {
27
54
  function validate(field) {
28
55
  return {
29
56
  name: INTENT,
30
- value: field ? "validate/".concat(field) : 'validate',
57
+ value: "validate/".concat(field),
31
58
  formNoValidate: true
32
59
  };
33
60
  }
@@ -36,86 +63,65 @@ function requestIntent(form, buttonProps) {
36
63
  console.warn('No form element is provided');
37
64
  return;
38
65
  }
39
- var submitter = createSubmitter({
66
+ var submitter = dom.createSubmitter({
40
67
  name: INTENT,
41
68
  value: buttonProps.value,
42
69
  hidden: true,
43
70
  formNoValidate: buttonProps.formNoValidate
44
71
  });
45
- requestSubmit(form, submitter);
46
- }
47
-
48
- /**
49
- * Helpers to configure an intent button for modifying a list
50
- *
51
- * @see https://conform.guide/api/react#list
52
- */
53
- var list = new Proxy({}, {
54
- get(_target, type) {
55
- return function (scope) {
56
- var payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
57
- return {
58
- name: INTENT,
59
- value: "list/".concat(type, "/").concat(scope, "/").concat(JSON.stringify(payload)),
60
- formNoValidate: true
61
- };
62
- };
63
- }
64
- });
65
- function isSubmitting(intent) {
66
- var [type] = intent.split('/', 1);
67
- return type !== 'validate' && type !== 'list';
72
+ dom.requestSubmit(form, submitter);
68
73
  }
69
- function getScope(intent) {
70
- var _parseListCommand$sco, _parseListCommand;
71
- var [type, ...rest] = intent.split('/');
72
- switch (type) {
73
- case 'validate':
74
- return rest.length > 0 ? rest.join('/') : null;
75
- case 'list':
76
- return (_parseListCommand$sco = (_parseListCommand = parseListCommand(intent)) === null || _parseListCommand === void 0 ? void 0 : _parseListCommand.scope) !== null && _parseListCommand$sco !== void 0 ? _parseListCommand$sco : null;
77
- default:
78
- return null;
79
- }
80
- }
81
- function parseListCommand(intent) {
82
- try {
83
- var [group, type, scope, json] = intent.split('/');
84
- if (group !== 'list' || !['prepend', 'append', 'replace', 'remove', 'reorder'].includes(type) || !scope) {
85
- return null;
74
+ function parseIntent(intent) {
75
+ var [type, payload] = intent.split('/', 2);
76
+ if (typeof payload !== 'undefined') {
77
+ try {
78
+ switch (type) {
79
+ case 'validate':
80
+ return {
81
+ type,
82
+ payload
83
+ };
84
+ case 'list':
85
+ return {
86
+ type,
87
+ payload: JSON.parse(payload)
88
+ };
89
+ }
90
+ } catch (error) {
91
+ throw new Error("Failed parsing intent: ".concat(intent), {
92
+ cause: error
93
+ });
86
94
  }
87
- var _payload = JSON.parse(json);
88
- return {
89
- // @ts-expect-error
90
- type,
91
- scope,
92
- payload: _payload
93
- };
94
- } catch (error) {
95
- return null;
96
95
  }
96
+ return null;
97
97
  }
98
- function updateList(list, command) {
99
- switch (command.type) {
98
+ function updateList(list, payload) {
99
+ switch (payload.operation) {
100
100
  case 'prepend':
101
- list.unshift(command.payload.defaultValue);
101
+ list.unshift(payload.defaultValue);
102
102
  break;
103
103
  case 'append':
104
- list.push(command.payload.defaultValue);
104
+ list.push(payload.defaultValue);
105
105
  break;
106
106
  case 'replace':
107
- list.splice(command.payload.index, 1, command.payload.defaultValue);
107
+ list.splice(payload.index, 1, payload.defaultValue);
108
108
  break;
109
109
  case 'remove':
110
- list.splice(command.payload.index, 1);
110
+ list.splice(payload.index, 1);
111
111
  break;
112
112
  case 'reorder':
113
- list.splice(command.payload.to, 0, ...list.splice(command.payload.from, 1));
113
+ list.splice(payload.to, 0, ...list.splice(payload.from, 1));
114
114
  break;
115
115
  default:
116
- throw new Error('Unknown list command received');
116
+ throw new Error('Unknown list intent received');
117
117
  }
118
118
  return list;
119
119
  }
120
120
 
121
- export { INTENT, getIntent, getScope, isSubmitting, list, parseListCommand, requestIntent, updateList, validate };
121
+ exports.INTENT = INTENT;
122
+ exports.getIntent = getIntent;
123
+ exports.list = list;
124
+ exports.parseIntent = parseIntent;
125
+ exports.requestIntent = requestIntent;
126
+ exports.updateList = updateList;
127
+ exports.validate = validate;
package/intent.mjs ADDED
@@ -0,0 +1,117 @@
1
+ import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
+ import { createSubmitter, requestSubmit } from './dom.mjs';
3
+
4
+ /**
5
+ * Helpers to configure an intent button for modifying a list
6
+ *
7
+ * @see https://conform.guide/api/react#list
8
+ */
9
+ var list = new Proxy({}, {
10
+ get(_target, operation) {
11
+ return function (name) {
12
+ var payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
13
+ return {
14
+ name: INTENT,
15
+ value: "list/".concat(JSON.stringify(_objectSpread2({
16
+ name,
17
+ operation
18
+ }, payload))),
19
+ formNoValidate: true
20
+ };
21
+ };
22
+ }
23
+ });
24
+ var INTENT = '__intent__';
25
+
26
+ /**
27
+ * Returns the intent from the form data or search params.
28
+ * It throws an error if multiple intent is set.
29
+ */
30
+ function getIntent(payload) {
31
+ if (!payload.has(INTENT)) {
32
+ return 'submit';
33
+ }
34
+ var [intent, secondIntent, ...rest] = payload.getAll(INTENT);
35
+
36
+ // The submitter value is included in the formData directly on Safari 15.6.
37
+ // This causes the intent to be duplicated in the payload.
38
+ // We will ignore the second intent if it is the same as the first one.
39
+ if (typeof intent !== 'string' || secondIntent && intent !== secondIntent || rest.length > 0) {
40
+ throw new Error('The intent could only be set on a button');
41
+ }
42
+ return intent;
43
+ }
44
+
45
+ /**
46
+ * Returns the properties required to configure an intent button for validation
47
+ *
48
+ * @see https://conform.guide/api/react#validate
49
+ */
50
+ function validate(field) {
51
+ return {
52
+ name: INTENT,
53
+ value: "validate/".concat(field),
54
+ formNoValidate: true
55
+ };
56
+ }
57
+ function requestIntent(form, buttonProps) {
58
+ if (!form) {
59
+ console.warn('No form element is provided');
60
+ return;
61
+ }
62
+ var submitter = createSubmitter({
63
+ name: INTENT,
64
+ value: buttonProps.value,
65
+ hidden: true,
66
+ formNoValidate: buttonProps.formNoValidate
67
+ });
68
+ requestSubmit(form, submitter);
69
+ }
70
+ function parseIntent(intent) {
71
+ var [type, payload] = intent.split('/', 2);
72
+ if (typeof payload !== 'undefined') {
73
+ try {
74
+ switch (type) {
75
+ case 'validate':
76
+ return {
77
+ type,
78
+ payload
79
+ };
80
+ case 'list':
81
+ return {
82
+ type,
83
+ payload: JSON.parse(payload)
84
+ };
85
+ }
86
+ } catch (error) {
87
+ throw new Error("Failed parsing intent: ".concat(intent), {
88
+ cause: error
89
+ });
90
+ }
91
+ }
92
+ return null;
93
+ }
94
+ function updateList(list, payload) {
95
+ switch (payload.operation) {
96
+ case 'prepend':
97
+ list.unshift(payload.defaultValue);
98
+ break;
99
+ case 'append':
100
+ list.push(payload.defaultValue);
101
+ break;
102
+ case 'replace':
103
+ list.splice(payload.index, 1, payload.defaultValue);
104
+ break;
105
+ case 'remove':
106
+ list.splice(payload.index, 1);
107
+ break;
108
+ case 'reorder':
109
+ list.splice(payload.to, 0, ...list.splice(payload.from, 1));
110
+ break;
111
+ default:
112
+ throw new Error('Unknown list intent received');
113
+ }
114
+ return list;
115
+ }
116
+
117
+ export { INTENT, getIntent, list, parseIntent, requestIntent, updateList, validate };
package/package.json CHANGED
@@ -3,18 +3,17 @@
3
3
  "description": "A set of opinionated helpers built on top of the Constraint Validation API",
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": {
package/parse.js CHANGED
@@ -1,20 +1,24 @@
1
- import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
2
- import { resolve, setValue } from './formdata.js';
3
- import { getIntent, parseListCommand, updateList } from './intent.js';
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
6
+ var formdata = require('./formdata.js');
7
+ var intent = require('./intent.js');
4
8
 
5
9
  function parse(payload, options) {
6
10
  var submission = {
7
- intent: getIntent(payload),
8
- payload: resolve(payload),
11
+ intent: intent.getIntent(payload),
12
+ payload: formdata.resolve(payload, [intent.INTENT]),
9
13
  error: {}
10
14
  };
11
- var command = parseListCommand(submission.intent);
12
- if (command) {
13
- setValue(submission.payload, command.scope, list => {
15
+ var intent$1 = intent.parseIntent(submission.intent);
16
+ if (intent$1 && intent$1.type === 'list') {
17
+ formdata.setValue(submission.payload, intent$1.payload.name, list => {
14
18
  if (typeof list !== 'undefined' && !Array.isArray(list)) {
15
- throw new Error('The list command can only be applied to a list');
19
+ throw new Error('The list intent can only be applied to a list');
16
20
  }
17
- return updateList(list !== null && list !== void 0 ? list : [], command);
21
+ return intent.updateList(list !== null && list !== void 0 ? list : [], intent$1.payload);
18
22
  });
19
23
  }
20
24
  if (typeof (options === null || options === void 0 ? void 0 : options.resolve) === 'undefined') {
@@ -22,7 +26,7 @@ function parse(payload, options) {
22
26
  }
23
27
  var result = options.resolve(submission.payload, submission.intent);
24
28
  var mergeResolveResult = resolved => {
25
- return _objectSpread2(_objectSpread2({}, submission), resolved);
29
+ return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, submission), resolved);
26
30
  };
27
31
  if (result instanceof Promise) {
28
32
  return result.then(mergeResolveResult);
@@ -30,4 +34,4 @@ function parse(payload, options) {
30
34
  return mergeResolveResult(result);
31
35
  }
32
36
 
33
- export { parse };
37
+ exports.parse = parse;
package/parse.mjs ADDED
@@ -0,0 +1,33 @@
1
+ import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
+ import { resolve, setValue } from './formdata.mjs';
3
+ import { getIntent, parseIntent, updateList, INTENT } from './intent.mjs';
4
+
5
+ function parse(payload, options) {
6
+ var submission = {
7
+ intent: getIntent(payload),
8
+ payload: resolve(payload, [INTENT]),
9
+ error: {}
10
+ };
11
+ var intent = parseIntent(submission.intent);
12
+ if (intent && intent.type === 'list') {
13
+ setValue(submission.payload, intent.payload.name, list => {
14
+ if (typeof list !== 'undefined' && !Array.isArray(list)) {
15
+ throw new Error('The list intent can only be applied to a list');
16
+ }
17
+ return updateList(list !== null && list !== void 0 ? list : [], intent.payload);
18
+ });
19
+ }
20
+ if (typeof (options === null || options === void 0 ? void 0 : options.resolve) === 'undefined') {
21
+ return submission;
22
+ }
23
+ var result = options.resolve(submission.payload, submission.intent);
24
+ var mergeResolveResult = resolved => {
25
+ return _objectSpread2(_objectSpread2({}, submission), resolved);
26
+ };
27
+ if (result instanceof Promise) {
28
+ return result.then(mergeResolveResult);
29
+ }
30
+ return mergeResolveResult(result);
31
+ }
32
+
33
+ export { parse };
package/types.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ export type Pretty<T> = {
2
+ [K in keyof T]: T[K];
3
+ } & {};
1
4
  export type FieldConstraint<Schema = any> = {
2
5
  required?: boolean;
3
6
  minLength?: number;
package/index.cjs DELETED
@@ -1,36 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var dom = require('./dom.cjs');
6
- var formdata = require('./formdata.cjs');
7
- var intent = require('./intent.cjs');
8
- var parse = require('./parse.cjs');
9
-
10
-
11
-
12
- exports.createSubmitter = dom.createSubmitter;
13
- exports.focusFirstInvalidControl = dom.focusFirstInvalidControl;
14
- exports.focusFormControl = dom.focusFormControl;
15
- exports.getFormAction = dom.getFormAction;
16
- exports.getFormControls = dom.getFormControls;
17
- exports.getFormElement = dom.getFormElement;
18
- exports.getFormEncType = dom.getFormEncType;
19
- exports.getFormMethod = dom.getFormMethod;
20
- exports.isFieldElement = dom.isFormControl;
21
- exports.isFocusableFormControl = dom.isFocusableFormControl;
22
- exports.requestSubmit = dom.requestSubmit;
23
- exports.getErrors = formdata.getErrors;
24
- exports.getFormData = formdata.getFormData;
25
- exports.getName = formdata.formatPaths;
26
- exports.getPaths = formdata.getPaths;
27
- exports.getValidationMessage = formdata.getValidationMessage;
28
- exports.INTENT = intent.INTENT;
29
- exports.getScope = intent.getScope;
30
- exports.isSubmitting = intent.isSubmitting;
31
- exports.list = intent.list;
32
- exports.parseListCommand = intent.parseListCommand;
33
- exports.requestIntent = intent.requestIntent;
34
- exports.updateList = intent.updateList;
35
- exports.validate = intent.validate;
36
- exports.parse = parse.parse;
package/intent.cjs DELETED
@@ -1,133 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var dom = require('./dom.cjs');
6
-
7
- var INTENT = '__intent__';
8
-
9
- /**
10
- *
11
- * @param payload
12
- * @returns
13
- */
14
- function getIntent(payload) {
15
- if (!payload.has(INTENT)) {
16
- return 'submit';
17
- }
18
- var [intent, ...rest] = payload.getAll(INTENT);
19
- if (typeof intent !== 'string' || rest.length > 0) {
20
- throw new Error('The intent could only be set on a button');
21
- }
22
- payload.delete(INTENT);
23
- return intent;
24
- }
25
-
26
- /**
27
- * Returns the properties required to configure an intent button for validation
28
- *
29
- * @see https://conform.guide/api/react#validate
30
- */
31
- function validate(field) {
32
- return {
33
- name: INTENT,
34
- value: field ? "validate/".concat(field) : 'validate',
35
- formNoValidate: true
36
- };
37
- }
38
- function requestIntent(form, buttonProps) {
39
- if (!form) {
40
- console.warn('No form element is provided');
41
- return;
42
- }
43
- var submitter = dom.createSubmitter({
44
- name: INTENT,
45
- value: buttonProps.value,
46
- hidden: true,
47
- formNoValidate: buttonProps.formNoValidate
48
- });
49
- dom.requestSubmit(form, submitter);
50
- }
51
-
52
- /**
53
- * Helpers to configure an intent button for modifying a list
54
- *
55
- * @see https://conform.guide/api/react#list
56
- */
57
- var list = new Proxy({}, {
58
- get(_target, type) {
59
- return function (scope) {
60
- var payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
61
- return {
62
- name: INTENT,
63
- value: "list/".concat(type, "/").concat(scope, "/").concat(JSON.stringify(payload)),
64
- formNoValidate: true
65
- };
66
- };
67
- }
68
- });
69
- function isSubmitting(intent) {
70
- var [type] = intent.split('/', 1);
71
- return type !== 'validate' && type !== 'list';
72
- }
73
- function getScope(intent) {
74
- var _parseListCommand$sco, _parseListCommand;
75
- var [type, ...rest] = intent.split('/');
76
- switch (type) {
77
- case 'validate':
78
- return rest.length > 0 ? rest.join('/') : null;
79
- case 'list':
80
- return (_parseListCommand$sco = (_parseListCommand = parseListCommand(intent)) === null || _parseListCommand === void 0 ? void 0 : _parseListCommand.scope) !== null && _parseListCommand$sco !== void 0 ? _parseListCommand$sco : null;
81
- default:
82
- return null;
83
- }
84
- }
85
- function parseListCommand(intent) {
86
- try {
87
- var [group, type, scope, json] = intent.split('/');
88
- if (group !== 'list' || !['prepend', 'append', 'replace', 'remove', 'reorder'].includes(type) || !scope) {
89
- return null;
90
- }
91
- var _payload = JSON.parse(json);
92
- return {
93
- // @ts-expect-error
94
- type,
95
- scope,
96
- payload: _payload
97
- };
98
- } catch (error) {
99
- return null;
100
- }
101
- }
102
- function updateList(list, command) {
103
- switch (command.type) {
104
- case 'prepend':
105
- list.unshift(command.payload.defaultValue);
106
- break;
107
- case 'append':
108
- list.push(command.payload.defaultValue);
109
- break;
110
- case 'replace':
111
- list.splice(command.payload.index, 1, command.payload.defaultValue);
112
- break;
113
- case 'remove':
114
- list.splice(command.payload.index, 1);
115
- break;
116
- case 'reorder':
117
- list.splice(command.payload.to, 0, ...list.splice(command.payload.from, 1));
118
- break;
119
- default:
120
- throw new Error('Unknown list command received');
121
- }
122
- return list;
123
- }
124
-
125
- exports.INTENT = INTENT;
126
- exports.getIntent = getIntent;
127
- exports.getScope = getScope;
128
- exports.isSubmitting = isSubmitting;
129
- exports.list = list;
130
- exports.parseListCommand = parseListCommand;
131
- exports.requestIntent = requestIntent;
132
- exports.updateList = updateList;
133
- exports.validate = validate;
package/parse.cjs DELETED
@@ -1,37 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.cjs');
6
- var formdata = require('./formdata.cjs');
7
- var intent = require('./intent.cjs');
8
-
9
- function parse(payload, options) {
10
- var submission = {
11
- intent: intent.getIntent(payload),
12
- payload: formdata.resolve(payload),
13
- error: {}
14
- };
15
- var command = intent.parseListCommand(submission.intent);
16
- if (command) {
17
- formdata.setValue(submission.payload, command.scope, list => {
18
- if (typeof list !== 'undefined' && !Array.isArray(list)) {
19
- throw new Error('The list command can only be applied to a list');
20
- }
21
- return intent.updateList(list !== null && list !== void 0 ? list : [], command);
22
- });
23
- }
24
- if (typeof (options === null || options === void 0 ? void 0 : options.resolve) === 'undefined') {
25
- return submission;
26
- }
27
- var result = options.resolve(submission.payload, submission.intent);
28
- var mergeResolveResult = resolved => {
29
- return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, submission), resolved);
30
- };
31
- if (result instanceof Promise) {
32
- return result.then(mergeResolveResult);
33
- }
34
- return mergeResolveResult(result);
35
- }
36
-
37
- exports.parse = parse;