@conform-to/react 0.4.0-pre.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_virtual/_rollupPluginBabelHelpers.js +0 -6
- package/helpers.js +0 -9
- package/hooks.js +18 -115
- package/module/_virtual/_rollupPluginBabelHelpers.js +0 -6
- package/module/helpers.js +0 -9
- package/module/hooks.js +18 -115
- package/package.json +2 -2
|
@@ -4,17 +4,14 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
function ownKeys(object, enumerableOnly) {
|
|
6
6
|
var keys = Object.keys(object);
|
|
7
|
-
|
|
8
7
|
if (Object.getOwnPropertySymbols) {
|
|
9
8
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
10
9
|
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
11
10
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
12
11
|
})), keys.push.apply(keys, symbols);
|
|
13
12
|
}
|
|
14
|
-
|
|
15
13
|
return keys;
|
|
16
14
|
}
|
|
17
|
-
|
|
18
15
|
function _objectSpread2(target) {
|
|
19
16
|
for (var i = 1; i < arguments.length; i++) {
|
|
20
17
|
var source = null != arguments[i] ? arguments[i] : {};
|
|
@@ -24,10 +21,8 @@ function _objectSpread2(target) {
|
|
|
24
21
|
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
25
22
|
});
|
|
26
23
|
}
|
|
27
|
-
|
|
28
24
|
return target;
|
|
29
25
|
}
|
|
30
|
-
|
|
31
26
|
function _defineProperty(obj, key, value) {
|
|
32
27
|
if (key in obj) {
|
|
33
28
|
Object.defineProperty(obj, key, {
|
|
@@ -39,7 +34,6 @@ function _defineProperty(obj, key, value) {
|
|
|
39
34
|
} else {
|
|
40
35
|
obj[key] = value;
|
|
41
36
|
}
|
|
42
|
-
|
|
43
37
|
return obj;
|
|
44
38
|
}
|
|
45
39
|
|
package/helpers.js
CHANGED
|
@@ -21,23 +21,19 @@ function input(config) {
|
|
|
21
21
|
pattern: config.pattern,
|
|
22
22
|
multiple: config.multiple
|
|
23
23
|
};
|
|
24
|
-
|
|
25
24
|
if (config.initialError && config.initialError.length > 0) {
|
|
26
25
|
attributes.autoFocus = true;
|
|
27
26
|
}
|
|
28
|
-
|
|
29
27
|
if (isCheckboxOrRadio) {
|
|
30
28
|
attributes.value = value !== null && value !== void 0 ? value : 'on';
|
|
31
29
|
attributes.defaultChecked = config.defaultValue === attributes.value;
|
|
32
30
|
} else {
|
|
33
31
|
attributes.defaultValue = config.defaultValue;
|
|
34
32
|
}
|
|
35
|
-
|
|
36
33
|
return attributes;
|
|
37
34
|
}
|
|
38
35
|
function select(config) {
|
|
39
36
|
var _config$defaultValue;
|
|
40
|
-
|
|
41
37
|
var attributes = {
|
|
42
38
|
name: config.name,
|
|
43
39
|
form: config.form,
|
|
@@ -45,16 +41,13 @@ function select(config) {
|
|
|
45
41
|
required: config.required,
|
|
46
42
|
multiple: config.multiple
|
|
47
43
|
};
|
|
48
|
-
|
|
49
44
|
if (config.initialError && config.initialError.length > 0) {
|
|
50
45
|
attributes.autoFocus = true;
|
|
51
46
|
}
|
|
52
|
-
|
|
53
47
|
return attributes;
|
|
54
48
|
}
|
|
55
49
|
function textarea(config) {
|
|
56
50
|
var _config$defaultValue2;
|
|
57
|
-
|
|
58
51
|
var attributes = {
|
|
59
52
|
name: config.name,
|
|
60
53
|
form: config.form,
|
|
@@ -64,11 +57,9 @@ function textarea(config) {
|
|
|
64
57
|
maxLength: config.maxLength,
|
|
65
58
|
autoFocus: Boolean(config.initialError)
|
|
66
59
|
};
|
|
67
|
-
|
|
68
60
|
if (config.initialError && config.initialError.length > 0) {
|
|
69
61
|
attributes.autoFocus = true;
|
|
70
62
|
}
|
|
71
|
-
|
|
72
63
|
return attributes;
|
|
73
64
|
}
|
|
74
65
|
|
package/hooks.js
CHANGED
|
@@ -19,7 +19,6 @@ function useForm() {
|
|
|
19
19
|
var ref = react.useRef(null);
|
|
20
20
|
var [error, setError] = react.useState(() => {
|
|
21
21
|
var _config$state$error$f, _config$state, _config$state$error;
|
|
22
|
-
|
|
23
22
|
var [, message] = (_config$state$error$f = (_config$state = config.state) === null || _config$state === void 0 ? void 0 : (_config$state$error = _config$state.error) === null || _config$state$error === void 0 ? void 0 : _config$state$error.find(_ref => {
|
|
24
23
|
var [key] = _ref;
|
|
25
24
|
return key === '';
|
|
@@ -28,7 +27,6 @@ function useForm() {
|
|
|
28
27
|
});
|
|
29
28
|
var [fieldsetConfig, setFieldsetConfig] = react.useState(() => {
|
|
30
29
|
var _config$state$error2, _config$state2, _config$state$value, _config$state3;
|
|
31
|
-
|
|
32
30
|
var error = (_config$state$error2 = (_config$state2 = config.state) === null || _config$state2 === void 0 ? void 0 : _config$state2.error) !== null && _config$state$error2 !== void 0 ? _config$state$error2 : [];
|
|
33
31
|
return {
|
|
34
32
|
defaultValue: (_config$state$value = (_config$state3 = config.state) === null || _config$state3 === void 0 ? void 0 : _config$state3.value) !== null && _config$state$value !== void 0 ? _config$state$value : config.defaultValue,
|
|
@@ -47,17 +45,13 @@ function useForm() {
|
|
|
47
45
|
}, []);
|
|
48
46
|
react.useEffect(() => {
|
|
49
47
|
var form = ref.current;
|
|
50
|
-
|
|
51
48
|
if (!form || !config.state) {
|
|
52
49
|
return;
|
|
53
50
|
}
|
|
54
|
-
|
|
55
51
|
dom.setFormError(form, config.state);
|
|
56
|
-
|
|
57
52
|
if (!form.reportValidity()) {
|
|
58
53
|
dom.focusFirstInvalidField(form);
|
|
59
54
|
}
|
|
60
|
-
|
|
61
55
|
dom.requestSubmit(form);
|
|
62
56
|
}, [config.state]);
|
|
63
57
|
react.useEffect(() => {
|
|
@@ -66,80 +60,66 @@ function useForm() {
|
|
|
66
60
|
var field = event.target;
|
|
67
61
|
var form = ref.current;
|
|
68
62
|
var formConfig = configRef.current;
|
|
69
|
-
|
|
70
63
|
if (!form || !dom.isFieldElement(field) || field.form !== form) {
|
|
71
64
|
return;
|
|
72
65
|
}
|
|
73
|
-
|
|
74
66
|
if (formConfig.initialReport === 'onChange') {
|
|
75
67
|
field.dataset.conformTouched = 'true';
|
|
76
68
|
}
|
|
77
|
-
|
|
78
69
|
if (field.dataset.conformTouched) {
|
|
79
70
|
dom.requestValidate(form, field.name);
|
|
80
71
|
}
|
|
81
72
|
};
|
|
82
|
-
|
|
83
73
|
var handleBlur = event => {
|
|
84
74
|
var field = event.target;
|
|
85
75
|
var form = ref.current;
|
|
86
76
|
var formConfig = configRef.current;
|
|
87
|
-
|
|
88
77
|
if (!form || !dom.isFieldElement(field) || field.form !== form) {
|
|
89
78
|
return;
|
|
90
79
|
}
|
|
91
|
-
|
|
92
80
|
if (formConfig.initialReport === 'onBlur' && !field.dataset.conformTouched) {
|
|
93
81
|
field.dataset.conformTouched = 'true';
|
|
94
82
|
dom.requestValidate(form, field.name);
|
|
95
83
|
}
|
|
96
84
|
};
|
|
97
|
-
|
|
98
85
|
var handleInvalid = event => {
|
|
99
86
|
var form = dom.getFormElement(ref.current);
|
|
100
87
|
var field = event.target;
|
|
101
|
-
|
|
102
88
|
if (!form || !dom.isFieldElement(field) || field.form !== form || field.name !== '') {
|
|
103
89
|
return;
|
|
104
90
|
}
|
|
105
|
-
|
|
106
91
|
event.preventDefault();
|
|
107
|
-
|
|
108
92
|
if (field.dataset.conformTouched) {
|
|
109
93
|
setError(field.validationMessage);
|
|
110
94
|
}
|
|
111
95
|
};
|
|
112
|
-
|
|
113
96
|
var handleReset = event => {
|
|
114
97
|
var form = ref.current;
|
|
115
98
|
var formConfig = configRef.current;
|
|
116
|
-
|
|
117
99
|
if (!form || event.target !== form) {
|
|
118
100
|
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
101
|
+
}
|
|
121
102
|
|
|
103
|
+
// Reset all field state
|
|
122
104
|
for (var field of form.elements) {
|
|
123
105
|
if (dom.isFieldElement(field)) {
|
|
124
106
|
delete field.dataset.conformTouched;
|
|
125
107
|
field.setCustomValidity('');
|
|
126
108
|
}
|
|
127
109
|
}
|
|
128
|
-
|
|
129
110
|
setError('');
|
|
130
111
|
setFieldsetConfig({
|
|
131
112
|
defaultValue: formConfig.defaultValue,
|
|
132
113
|
initialError: []
|
|
133
114
|
});
|
|
134
115
|
};
|
|
116
|
+
|
|
135
117
|
/**
|
|
136
118
|
* The input event handler will be triggered in capturing phase in order to
|
|
137
119
|
* allow follow-up action in the bubble phase based on the latest validity
|
|
138
120
|
* E.g. `useFieldset` reset the error of valid field after checking the
|
|
139
121
|
* validity in the bubble phase.
|
|
140
122
|
*/
|
|
141
|
-
|
|
142
|
-
|
|
143
123
|
document.addEventListener('input', handleInput, true);
|
|
144
124
|
document.addEventListener('blur', handleBlur, true);
|
|
145
125
|
document.addEventListener('invalid', handleInvalid, true);
|
|
@@ -157,35 +137,30 @@ function useForm() {
|
|
|
157
137
|
props: {
|
|
158
138
|
ref,
|
|
159
139
|
noValidate,
|
|
160
|
-
|
|
161
140
|
onSubmit(event) {
|
|
162
141
|
var form = event.currentTarget;
|
|
163
142
|
var nativeEvent = event.nativeEvent;
|
|
164
143
|
var submitter = nativeEvent.submitter;
|
|
165
|
-
|
|
166
144
|
for (var element of form.elements) {
|
|
167
145
|
if (dom.isFieldElement(element) && element.name === '') {
|
|
168
146
|
setError(element.validationMessage);
|
|
169
147
|
break;
|
|
170
148
|
}
|
|
171
149
|
}
|
|
150
|
+
|
|
172
151
|
/**
|
|
173
152
|
* It checks defaultPrevented to confirm if the submission is intentional
|
|
174
153
|
* This is utilized by `useFieldList` to modify the list state when the submit
|
|
175
154
|
* event is captured and revalidate the form with new fields without triggering
|
|
176
155
|
* a form submission at the same time.
|
|
177
156
|
*/
|
|
178
|
-
|
|
179
|
-
|
|
180
157
|
if (!submitter || event.defaultPrevented) {
|
|
181
158
|
event.preventDefault();
|
|
182
159
|
return;
|
|
183
160
|
}
|
|
184
|
-
|
|
185
161
|
try {
|
|
186
162
|
var submission;
|
|
187
163
|
var formData = dom.getFormData(form, submitter);
|
|
188
|
-
|
|
189
164
|
if (typeof config.onValidate === 'function') {
|
|
190
165
|
submission = config.onValidate({
|
|
191
166
|
form,
|
|
@@ -193,7 +168,6 @@ function useForm() {
|
|
|
193
168
|
});
|
|
194
169
|
} else {
|
|
195
170
|
submission = dom.parse(formData);
|
|
196
|
-
|
|
197
171
|
if (config.mode !== 'server-validation') {
|
|
198
172
|
/**
|
|
199
173
|
* As there is no custom logic defined,
|
|
@@ -207,16 +181,15 @@ function useForm() {
|
|
|
207
181
|
value: {},
|
|
208
182
|
error: []
|
|
209
183
|
});
|
|
210
|
-
|
|
211
184
|
for (var _element of form.elements) {
|
|
212
185
|
if (dom.isFieldElement(_element) && _element.willValidate) {
|
|
213
186
|
submission.error.push([_element.name, _element.validationMessage]);
|
|
214
187
|
}
|
|
215
188
|
}
|
|
216
189
|
}
|
|
217
|
-
}
|
|
218
|
-
|
|
190
|
+
}
|
|
219
191
|
|
|
192
|
+
// Touch all fields only if the submitter is not a command button
|
|
220
193
|
if (submission.type === 'submit') {
|
|
221
194
|
for (var field of form.elements) {
|
|
222
195
|
if (dom.isFieldElement(field)) {
|
|
@@ -225,21 +198,17 @@ function useForm() {
|
|
|
225
198
|
}
|
|
226
199
|
}
|
|
227
200
|
}
|
|
228
|
-
|
|
229
201
|
if (!config.noValidate && !submitter.formNoValidate && dom.hasError(submission.error) || submission.type === 'validate' && config.mode !== 'server-validation') {
|
|
230
202
|
event.preventDefault();
|
|
231
203
|
} else {
|
|
232
204
|
var _config$onSubmit;
|
|
233
|
-
|
|
234
205
|
(_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, {
|
|
235
206
|
formData,
|
|
236
207
|
submission
|
|
237
208
|
});
|
|
238
209
|
}
|
|
239
|
-
|
|
240
210
|
if (event.defaultPrevented) {
|
|
241
211
|
dom.setFormError(form, submission);
|
|
242
|
-
|
|
243
212
|
if (!form.reportValidity()) {
|
|
244
213
|
dom.focusFirstInvalidField(form);
|
|
245
214
|
}
|
|
@@ -248,34 +217,29 @@ function useForm() {
|
|
|
248
217
|
console.warn(e);
|
|
249
218
|
}
|
|
250
219
|
}
|
|
251
|
-
|
|
252
220
|
},
|
|
253
221
|
config: fieldsetConfig
|
|
254
222
|
};
|
|
255
223
|
}
|
|
224
|
+
|
|
256
225
|
/**
|
|
257
226
|
* All the information of the field, including state and config.
|
|
258
227
|
*/
|
|
259
228
|
|
|
260
229
|
function useFieldset(ref, config) {
|
|
261
230
|
var configRef = react.useRef(config);
|
|
262
|
-
var [uncontrolledState, setUncontrolledState] = react.useState(
|
|
231
|
+
var [uncontrolledState, setUncontrolledState] = react.useState(
|
|
232
|
+
// @ts-expect-error
|
|
263
233
|
() => {
|
|
264
234
|
var _config$defaultValue;
|
|
265
|
-
|
|
266
235
|
var initialError = {};
|
|
267
|
-
|
|
268
236
|
for (var [name, message] of (_config$initialError = config === null || config === void 0 ? void 0 : config.initialError) !== null && _config$initialError !== void 0 ? _config$initialError : []) {
|
|
269
237
|
var _config$initialError;
|
|
270
|
-
|
|
271
238
|
var [key, ...paths] = dom.getPaths(name);
|
|
272
|
-
|
|
273
239
|
if (typeof key === 'string') {
|
|
274
240
|
var _initialError$key;
|
|
275
|
-
|
|
276
241
|
var scopedName = dom.getName(paths);
|
|
277
242
|
var entries = (_initialError$key = initialError[key]) !== null && _initialError$key !== void 0 ? _initialError$key : [];
|
|
278
|
-
|
|
279
243
|
if (scopedName === '' && entries.length > 0 && entries[0][0] !== '') {
|
|
280
244
|
initialError[key] = [[scopedName, message], ...entries];
|
|
281
245
|
} else {
|
|
@@ -283,7 +247,6 @@ function useFieldset(ref, config) {
|
|
|
283
247
|
}
|
|
284
248
|
}
|
|
285
249
|
}
|
|
286
|
-
|
|
287
250
|
return {
|
|
288
251
|
defaultValue: (_config$defaultValue = config === null || config === void 0 ? void 0 : config.defaultValue) !== null && _config$defaultValue !== void 0 ? _config$defaultValue : {},
|
|
289
252
|
initialError
|
|
@@ -291,17 +254,13 @@ function useFieldset(ref, config) {
|
|
|
291
254
|
});
|
|
292
255
|
var [error, setError] = react.useState(() => {
|
|
293
256
|
var result = {};
|
|
294
|
-
|
|
295
257
|
for (var [key, entries] of Object.entries(uncontrolledState.initialError)) {
|
|
296
258
|
var _entries$;
|
|
297
|
-
|
|
298
259
|
var [name, message] = (_entries$ = entries === null || entries === void 0 ? void 0 : entries[0]) !== null && _entries$ !== void 0 ? _entries$ : [];
|
|
299
|
-
|
|
300
260
|
if (name === '') {
|
|
301
261
|
result[key] = message !== null && message !== void 0 ? message : '';
|
|
302
262
|
}
|
|
303
263
|
}
|
|
304
|
-
|
|
305
264
|
return result;
|
|
306
265
|
});
|
|
307
266
|
react.useEffect(() => {
|
|
@@ -310,66 +269,53 @@ function useFieldset(ref, config) {
|
|
|
310
269
|
react.useEffect(() => {
|
|
311
270
|
var invalidHandler = event => {
|
|
312
271
|
var _configRef$current$na;
|
|
313
|
-
|
|
314
272
|
var form = dom.getFormElement(ref.current);
|
|
315
273
|
var field = event.target;
|
|
316
274
|
var fieldsetName = (_configRef$current$na = configRef.current.name) !== null && _configRef$current$na !== void 0 ? _configRef$current$na : '';
|
|
317
|
-
|
|
318
275
|
if (!form || !dom.isFieldElement(field) || field.form !== form || !field.name.startsWith(fieldsetName)) {
|
|
319
276
|
return;
|
|
320
277
|
}
|
|
278
|
+
var [key, ...paths] = dom.getPaths(fieldsetName.length > 0 ? field.name.slice(fieldsetName.length + 1) : field.name);
|
|
321
279
|
|
|
322
|
-
|
|
323
|
-
|
|
280
|
+
// Update the error only if the field belongs to the fieldset
|
|
324
281
|
if (typeof key === 'string' && paths.length === 0) {
|
|
325
282
|
if (field.dataset.conformTouched) {
|
|
326
283
|
setError(prev => {
|
|
327
284
|
var _prev$key;
|
|
328
|
-
|
|
329
285
|
var prevMessage = (_prev$key = prev === null || prev === void 0 ? void 0 : prev[key]) !== null && _prev$key !== void 0 ? _prev$key : '';
|
|
330
|
-
|
|
331
286
|
if (prevMessage === field.validationMessage) {
|
|
332
287
|
return prev;
|
|
333
288
|
}
|
|
334
|
-
|
|
335
289
|
return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, prev), {}, {
|
|
336
290
|
[key]: field.validationMessage
|
|
337
291
|
});
|
|
338
292
|
});
|
|
339
293
|
}
|
|
340
|
-
|
|
341
294
|
event.preventDefault();
|
|
342
295
|
}
|
|
343
296
|
};
|
|
344
|
-
|
|
345
297
|
var submitHandler = event => {
|
|
346
298
|
var form = dom.getFormElement(ref.current);
|
|
347
|
-
|
|
348
299
|
if (!form || event.target !== form) {
|
|
349
300
|
return;
|
|
350
301
|
}
|
|
302
|
+
|
|
351
303
|
/**
|
|
352
304
|
* Reset the error state of each field if its validity is changed.
|
|
353
305
|
*
|
|
354
306
|
* This is a workaround as no official way is provided to notify
|
|
355
307
|
* when the validity of the field is changed from `invalid` to `valid`.
|
|
356
308
|
*/
|
|
357
|
-
|
|
358
|
-
|
|
359
309
|
setError(prev => {
|
|
360
310
|
var _configRef$current$na2;
|
|
361
|
-
|
|
362
311
|
var next = prev;
|
|
363
312
|
var fieldsetName = (_configRef$current$na2 = configRef.current.name) !== null && _configRef$current$na2 !== void 0 ? _configRef$current$na2 : '';
|
|
364
|
-
|
|
365
313
|
for (var field of form.elements) {
|
|
366
314
|
if (dom.isFieldElement(field) && field.name.startsWith(fieldsetName)) {
|
|
367
315
|
var _next$key, _next;
|
|
368
|
-
|
|
369
316
|
var key = fieldsetName ? field.name.slice(fieldsetName.length + 1) : field.name;
|
|
370
317
|
var prevMessage = (_next$key = (_next = next) === null || _next === void 0 ? void 0 : _next[key]) !== null && _next$key !== void 0 ? _next$key : '';
|
|
371
318
|
var nextMessage = field.validationMessage;
|
|
372
|
-
|
|
373
319
|
if (prevMessage !== '' && nextMessage === '') {
|
|
374
320
|
next = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, next), {}, {
|
|
375
321
|
[key]: ''
|
|
@@ -377,20 +323,15 @@ function useFieldset(ref, config) {
|
|
|
377
323
|
}
|
|
378
324
|
}
|
|
379
325
|
}
|
|
380
|
-
|
|
381
326
|
return next;
|
|
382
327
|
});
|
|
383
328
|
};
|
|
384
|
-
|
|
385
329
|
var resetHandler = event => {
|
|
386
330
|
var _fieldsetConfig$defau;
|
|
387
|
-
|
|
388
331
|
var form = dom.getFormElement(ref.current);
|
|
389
|
-
|
|
390
332
|
if (!form || event.target !== form) {
|
|
391
333
|
return;
|
|
392
334
|
}
|
|
393
|
-
|
|
394
335
|
var fieldsetConfig = configRef.current;
|
|
395
336
|
setUncontrolledState({
|
|
396
337
|
// @ts-expect-error
|
|
@@ -398,9 +339,9 @@ function useFieldset(ref, config) {
|
|
|
398
339
|
initialError: {}
|
|
399
340
|
});
|
|
400
341
|
setError({});
|
|
401
|
-
};
|
|
402
|
-
|
|
342
|
+
};
|
|
403
343
|
|
|
344
|
+
// The invalid event does not bubble and so listening on the capturing pharse is needed
|
|
404
345
|
document.addEventListener('invalid', invalidHandler, true);
|
|
405
346
|
document.addEventListener('submit', submitHandler);
|
|
406
347
|
document.addEventListener('reset', resetHandler);
|
|
@@ -410,20 +351,18 @@ function useFieldset(ref, config) {
|
|
|
410
351
|
document.removeEventListener('reset', resetHandler);
|
|
411
352
|
};
|
|
412
353
|
}, [ref]);
|
|
354
|
+
|
|
413
355
|
/**
|
|
414
356
|
* This allows us constructing the field at runtime as we have no information
|
|
415
357
|
* about which fields would be available. The proxy will also help tracking
|
|
416
358
|
* the usage of each field for optimization in the future.
|
|
417
359
|
*/
|
|
418
|
-
|
|
419
360
|
return new Proxy({}, {
|
|
420
361
|
get(_target, key) {
|
|
421
362
|
var _fieldsetConfig$const, _error$key;
|
|
422
|
-
|
|
423
363
|
if (typeof key !== 'string') {
|
|
424
364
|
return;
|
|
425
365
|
}
|
|
426
|
-
|
|
427
366
|
var fieldsetConfig = config !== null && config !== void 0 ? config : {};
|
|
428
367
|
var constraint = (_fieldsetConfig$const = fieldsetConfig.constraint) === null || _fieldsetConfig$const === void 0 ? void 0 : _fieldsetConfig$const[key];
|
|
429
368
|
var field = {
|
|
@@ -437,10 +376,8 @@ function useFieldset(ref, config) {
|
|
|
437
376
|
};
|
|
438
377
|
return field;
|
|
439
378
|
}
|
|
440
|
-
|
|
441
379
|
});
|
|
442
380
|
}
|
|
443
|
-
|
|
444
381
|
/**
|
|
445
382
|
* Returns a list of key and config, with a group of helpers
|
|
446
383
|
* configuring buttons for list manipulation
|
|
@@ -451,21 +388,14 @@ function useFieldList(ref, config) {
|
|
|
451
388
|
var configRef = react.useRef(config);
|
|
452
389
|
var [uncontrolledState, setUncontrolledState] = react.useState(() => {
|
|
453
390
|
var _config$defaultValue2;
|
|
454
|
-
|
|
455
391
|
var initialError = [];
|
|
456
|
-
|
|
457
392
|
for (var [name, message] of (_config$initialError2 = config === null || config === void 0 ? void 0 : config.initialError) !== null && _config$initialError2 !== void 0 ? _config$initialError2 : []) {
|
|
458
393
|
var _config$initialError2;
|
|
459
|
-
|
|
460
394
|
var [index, ...paths] = dom.getPaths(name);
|
|
461
|
-
|
|
462
395
|
if (typeof index === 'number') {
|
|
463
396
|
var _initialError$index;
|
|
464
|
-
|
|
465
397
|
var scopedName = dom.getName(paths);
|
|
466
|
-
|
|
467
398
|
var _entries = (_initialError$index = initialError[index]) !== null && _initialError$index !== void 0 ? _initialError$index : [];
|
|
468
|
-
|
|
469
399
|
if (scopedName === '' && _entries.length > 0 && _entries[0][0] !== '') {
|
|
470
400
|
initialError[index] = [[scopedName, message], ..._entries];
|
|
471
401
|
} else {
|
|
@@ -473,7 +403,6 @@ function useFieldList(ref, config) {
|
|
|
473
403
|
}
|
|
474
404
|
}
|
|
475
405
|
}
|
|
476
|
-
|
|
477
406
|
return {
|
|
478
407
|
defaultValue: (_config$defaultValue2 = config.defaultValue) !== null && _config$defaultValue2 !== void 0 ? _config$defaultValue2 : [],
|
|
479
408
|
initialError
|
|
@@ -481,7 +410,6 @@ function useFieldList(ref, config) {
|
|
|
481
410
|
});
|
|
482
411
|
var [entries, setEntries] = react.useState(() => {
|
|
483
412
|
var _config$defaultValue3;
|
|
484
|
-
|
|
485
413
|
return Object.entries((_config$defaultValue3 = config.defaultValue) !== null && _config$defaultValue3 !== void 0 ? _config$defaultValue3 : [undefined]);
|
|
486
414
|
});
|
|
487
415
|
var list = entries.map((_ref3, index) => {
|
|
@@ -496,11 +424,11 @@ function useFieldList(ref, config) {
|
|
|
496
424
|
}
|
|
497
425
|
};
|
|
498
426
|
});
|
|
427
|
+
|
|
499
428
|
/***
|
|
500
429
|
* This use proxy to capture all information about the command and
|
|
501
430
|
* have it encoded in the value.
|
|
502
431
|
*/
|
|
503
|
-
|
|
504
432
|
var command = new Proxy({}, {
|
|
505
433
|
get(_target, type) {
|
|
506
434
|
return function () {
|
|
@@ -517,7 +445,6 @@ function useFieldList(ref, config) {
|
|
|
517
445
|
};
|
|
518
446
|
};
|
|
519
447
|
}
|
|
520
|
-
|
|
521
448
|
});
|
|
522
449
|
react.useEffect(() => {
|
|
523
450
|
configRef.current = config;
|
|
@@ -525,18 +452,14 @@ function useFieldList(ref, config) {
|
|
|
525
452
|
react.useEffect(() => {
|
|
526
453
|
var submitHandler = event => {
|
|
527
454
|
var form = dom.getFormElement(ref.current);
|
|
528
|
-
|
|
529
455
|
if (!form || event.target !== form || !(event.submitter instanceof HTMLButtonElement) || event.submitter.name !== 'conform/list') {
|
|
530
456
|
return;
|
|
531
457
|
}
|
|
532
|
-
|
|
533
458
|
var command = dom.parseListCommand(event.submitter.value);
|
|
534
|
-
|
|
535
459
|
if (command.scope !== configRef.current.name) {
|
|
536
460
|
// Ensure the scope of the listener are limited to specific field name
|
|
537
461
|
return;
|
|
538
462
|
}
|
|
539
|
-
|
|
540
463
|
setEntries(entries => {
|
|
541
464
|
switch (command.type) {
|
|
542
465
|
case 'append':
|
|
@@ -547,7 +470,6 @@ function useFieldList(ref, config) {
|
|
|
547
470
|
defaultValue: ["".concat(Date.now()), command.payload.defaultValue]
|
|
548
471
|
})
|
|
549
472
|
}));
|
|
550
|
-
|
|
551
473
|
default:
|
|
552
474
|
{
|
|
553
475
|
return dom.updateList([...(entries !== null && entries !== void 0 ? entries : [])], command);
|
|
@@ -556,16 +478,12 @@ function useFieldList(ref, config) {
|
|
|
556
478
|
});
|
|
557
479
|
event.preventDefault();
|
|
558
480
|
};
|
|
559
|
-
|
|
560
481
|
var resetHandler = event => {
|
|
561
482
|
var _fieldConfig$defaultV, _fieldConfig$defaultV2;
|
|
562
|
-
|
|
563
483
|
var form = dom.getFormElement(ref.current);
|
|
564
|
-
|
|
565
484
|
if (!form || event.target !== form) {
|
|
566
485
|
return;
|
|
567
486
|
}
|
|
568
|
-
|
|
569
487
|
var fieldConfig = configRef.current;
|
|
570
488
|
setUncontrolledState({
|
|
571
489
|
defaultValue: (_fieldConfig$defaultV = fieldConfig.defaultValue) !== null && _fieldConfig$defaultV !== void 0 ? _fieldConfig$defaultV : [],
|
|
@@ -573,7 +491,6 @@ function useFieldList(ref, config) {
|
|
|
573
491
|
});
|
|
574
492
|
setEntries(Object.entries((_fieldConfig$defaultV2 = fieldConfig.defaultValue) !== null && _fieldConfig$defaultV2 !== void 0 ? _fieldConfig$defaultV2 : [undefined]));
|
|
575
493
|
};
|
|
576
|
-
|
|
577
494
|
document.addEventListener('submit', submitHandler, true);
|
|
578
495
|
document.addEventListener('reset', resetHandler);
|
|
579
496
|
return () => {
|
|
@@ -581,10 +498,10 @@ function useFieldList(ref, config) {
|
|
|
581
498
|
document.removeEventListener('reset', resetHandler);
|
|
582
499
|
};
|
|
583
500
|
}, [ref]);
|
|
584
|
-
return [list,
|
|
501
|
+
return [list,
|
|
502
|
+
// @ts-expect-error proxy type
|
|
585
503
|
command];
|
|
586
504
|
}
|
|
587
|
-
|
|
588
505
|
/**
|
|
589
506
|
* Returns the properties required to configure a shadow input for validation.
|
|
590
507
|
* This is particular useful when integrating dropdown and datepicker whichs
|
|
@@ -594,7 +511,6 @@ function useFieldList(ref, config) {
|
|
|
594
511
|
*/
|
|
595
512
|
function useControlledInput(config) {
|
|
596
513
|
var _config$defaultValue4;
|
|
597
|
-
|
|
598
514
|
var ref = react.useRef(null);
|
|
599
515
|
var inputRef = react.useRef(null);
|
|
600
516
|
var configRef = react.useRef(config);
|
|
@@ -603,12 +519,10 @@ function useControlledInput(config) {
|
|
|
603
519
|
initialError: config.initialError
|
|
604
520
|
});
|
|
605
521
|
var [value, setValue] = react.useState("".concat((_config$defaultValue4 = config.defaultValue) !== null && _config$defaultValue4 !== void 0 ? _config$defaultValue4 : ''));
|
|
606
|
-
|
|
607
522
|
var handleChange = eventOrValue => {
|
|
608
523
|
if (!ref.current) {
|
|
609
524
|
return;
|
|
610
525
|
}
|
|
611
|
-
|
|
612
526
|
var newValue = typeof eventOrValue === 'string' ? eventOrValue : eventOrValue.target.value;
|
|
613
527
|
ref.current.value = newValue;
|
|
614
528
|
ref.current.dispatchEvent(new InputEvent('input', {
|
|
@@ -616,39 +530,31 @@ function useControlledInput(config) {
|
|
|
616
530
|
}));
|
|
617
531
|
setValue(newValue);
|
|
618
532
|
};
|
|
619
|
-
|
|
620
533
|
var handleBlur = () => {
|
|
621
534
|
var _ref$current;
|
|
622
|
-
|
|
623
535
|
(_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.dispatchEvent(new FocusEvent('blur', {
|
|
624
536
|
bubbles: true
|
|
625
537
|
}));
|
|
626
538
|
};
|
|
627
|
-
|
|
628
539
|
var handleInvalid = event => {
|
|
629
540
|
event.preventDefault();
|
|
630
541
|
};
|
|
631
|
-
|
|
632
542
|
react.useEffect(() => {
|
|
633
543
|
configRef.current = config;
|
|
634
544
|
});
|
|
635
545
|
react.useEffect(() => {
|
|
636
546
|
var resetHandler = event => {
|
|
637
547
|
var _configRef$current$de;
|
|
638
|
-
|
|
639
548
|
var form = dom.getFormElement(ref.current);
|
|
640
|
-
|
|
641
549
|
if (!form || event.target !== form) {
|
|
642
550
|
return;
|
|
643
551
|
}
|
|
644
|
-
|
|
645
552
|
setUncontrolledState({
|
|
646
553
|
defaultValue: configRef.current.defaultValue,
|
|
647
554
|
initialError: configRef.current.initialError
|
|
648
555
|
});
|
|
649
556
|
setValue("".concat((_configRef$current$de = configRef.current.defaultValue) !== null && _configRef$current$de !== void 0 ? _configRef$current$de : ''));
|
|
650
557
|
};
|
|
651
|
-
|
|
652
558
|
document.addEventListener('reset', resetHandler);
|
|
653
559
|
return () => {
|
|
654
560
|
document.removeEventListener('reset', resetHandler);
|
|
@@ -667,13 +573,10 @@ function useControlledInput(config) {
|
|
|
667
573
|
whiteSpace: 'nowrap',
|
|
668
574
|
borderWidth: 0
|
|
669
575
|
},
|
|
670
|
-
|
|
671
576
|
onFocus() {
|
|
672
577
|
var _inputRef$current;
|
|
673
|
-
|
|
674
578
|
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
|
|
675
579
|
}
|
|
676
|
-
|
|
677
580
|
}, helpers.input(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, config), uncontrolledState), {
|
|
678
581
|
type: 'text'
|
|
679
582
|
})), {
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
function ownKeys(object, enumerableOnly) {
|
|
2
2
|
var keys = Object.keys(object);
|
|
3
|
-
|
|
4
3
|
if (Object.getOwnPropertySymbols) {
|
|
5
4
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
6
5
|
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
7
6
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
8
7
|
})), keys.push.apply(keys, symbols);
|
|
9
8
|
}
|
|
10
|
-
|
|
11
9
|
return keys;
|
|
12
10
|
}
|
|
13
|
-
|
|
14
11
|
function _objectSpread2(target) {
|
|
15
12
|
for (var i = 1; i < arguments.length; i++) {
|
|
16
13
|
var source = null != arguments[i] ? arguments[i] : {};
|
|
@@ -20,10 +17,8 @@ function _objectSpread2(target) {
|
|
|
20
17
|
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
21
18
|
});
|
|
22
19
|
}
|
|
23
|
-
|
|
24
20
|
return target;
|
|
25
21
|
}
|
|
26
|
-
|
|
27
22
|
function _defineProperty(obj, key, value) {
|
|
28
23
|
if (key in obj) {
|
|
29
24
|
Object.defineProperty(obj, key, {
|
|
@@ -35,7 +30,6 @@ function _defineProperty(obj, key, value) {
|
|
|
35
30
|
} else {
|
|
36
31
|
obj[key] = value;
|
|
37
32
|
}
|
|
38
|
-
|
|
39
33
|
return obj;
|
|
40
34
|
}
|
|
41
35
|
|
package/module/helpers.js
CHANGED
|
@@ -17,23 +17,19 @@ function input(config) {
|
|
|
17
17
|
pattern: config.pattern,
|
|
18
18
|
multiple: config.multiple
|
|
19
19
|
};
|
|
20
|
-
|
|
21
20
|
if (config.initialError && config.initialError.length > 0) {
|
|
22
21
|
attributes.autoFocus = true;
|
|
23
22
|
}
|
|
24
|
-
|
|
25
23
|
if (isCheckboxOrRadio) {
|
|
26
24
|
attributes.value = value !== null && value !== void 0 ? value : 'on';
|
|
27
25
|
attributes.defaultChecked = config.defaultValue === attributes.value;
|
|
28
26
|
} else {
|
|
29
27
|
attributes.defaultValue = config.defaultValue;
|
|
30
28
|
}
|
|
31
|
-
|
|
32
29
|
return attributes;
|
|
33
30
|
}
|
|
34
31
|
function select(config) {
|
|
35
32
|
var _config$defaultValue;
|
|
36
|
-
|
|
37
33
|
var attributes = {
|
|
38
34
|
name: config.name,
|
|
39
35
|
form: config.form,
|
|
@@ -41,16 +37,13 @@ function select(config) {
|
|
|
41
37
|
required: config.required,
|
|
42
38
|
multiple: config.multiple
|
|
43
39
|
};
|
|
44
|
-
|
|
45
40
|
if (config.initialError && config.initialError.length > 0) {
|
|
46
41
|
attributes.autoFocus = true;
|
|
47
42
|
}
|
|
48
|
-
|
|
49
43
|
return attributes;
|
|
50
44
|
}
|
|
51
45
|
function textarea(config) {
|
|
52
46
|
var _config$defaultValue2;
|
|
53
|
-
|
|
54
47
|
var attributes = {
|
|
55
48
|
name: config.name,
|
|
56
49
|
form: config.form,
|
|
@@ -60,11 +53,9 @@ function textarea(config) {
|
|
|
60
53
|
maxLength: config.maxLength,
|
|
61
54
|
autoFocus: Boolean(config.initialError)
|
|
62
55
|
};
|
|
63
|
-
|
|
64
56
|
if (config.initialError && config.initialError.length > 0) {
|
|
65
57
|
attributes.autoFocus = true;
|
|
66
58
|
}
|
|
67
|
-
|
|
68
59
|
return attributes;
|
|
69
60
|
}
|
|
70
61
|
|
package/module/hooks.js
CHANGED
|
@@ -15,7 +15,6 @@ function useForm() {
|
|
|
15
15
|
var ref = useRef(null);
|
|
16
16
|
var [error, setError] = useState(() => {
|
|
17
17
|
var _config$state$error$f, _config$state, _config$state$error;
|
|
18
|
-
|
|
19
18
|
var [, message] = (_config$state$error$f = (_config$state = config.state) === null || _config$state === void 0 ? void 0 : (_config$state$error = _config$state.error) === null || _config$state$error === void 0 ? void 0 : _config$state$error.find(_ref => {
|
|
20
19
|
var [key] = _ref;
|
|
21
20
|
return key === '';
|
|
@@ -24,7 +23,6 @@ function useForm() {
|
|
|
24
23
|
});
|
|
25
24
|
var [fieldsetConfig, setFieldsetConfig] = useState(() => {
|
|
26
25
|
var _config$state$error2, _config$state2, _config$state$value, _config$state3;
|
|
27
|
-
|
|
28
26
|
var error = (_config$state$error2 = (_config$state2 = config.state) === null || _config$state2 === void 0 ? void 0 : _config$state2.error) !== null && _config$state$error2 !== void 0 ? _config$state$error2 : [];
|
|
29
27
|
return {
|
|
30
28
|
defaultValue: (_config$state$value = (_config$state3 = config.state) === null || _config$state3 === void 0 ? void 0 : _config$state3.value) !== null && _config$state$value !== void 0 ? _config$state$value : config.defaultValue,
|
|
@@ -43,17 +41,13 @@ function useForm() {
|
|
|
43
41
|
}, []);
|
|
44
42
|
useEffect(() => {
|
|
45
43
|
var form = ref.current;
|
|
46
|
-
|
|
47
44
|
if (!form || !config.state) {
|
|
48
45
|
return;
|
|
49
46
|
}
|
|
50
|
-
|
|
51
47
|
setFormError(form, config.state);
|
|
52
|
-
|
|
53
48
|
if (!form.reportValidity()) {
|
|
54
49
|
focusFirstInvalidField(form);
|
|
55
50
|
}
|
|
56
|
-
|
|
57
51
|
requestSubmit(form);
|
|
58
52
|
}, [config.state]);
|
|
59
53
|
useEffect(() => {
|
|
@@ -62,80 +56,66 @@ function useForm() {
|
|
|
62
56
|
var field = event.target;
|
|
63
57
|
var form = ref.current;
|
|
64
58
|
var formConfig = configRef.current;
|
|
65
|
-
|
|
66
59
|
if (!form || !isFieldElement(field) || field.form !== form) {
|
|
67
60
|
return;
|
|
68
61
|
}
|
|
69
|
-
|
|
70
62
|
if (formConfig.initialReport === 'onChange') {
|
|
71
63
|
field.dataset.conformTouched = 'true';
|
|
72
64
|
}
|
|
73
|
-
|
|
74
65
|
if (field.dataset.conformTouched) {
|
|
75
66
|
requestValidate(form, field.name);
|
|
76
67
|
}
|
|
77
68
|
};
|
|
78
|
-
|
|
79
69
|
var handleBlur = event => {
|
|
80
70
|
var field = event.target;
|
|
81
71
|
var form = ref.current;
|
|
82
72
|
var formConfig = configRef.current;
|
|
83
|
-
|
|
84
73
|
if (!form || !isFieldElement(field) || field.form !== form) {
|
|
85
74
|
return;
|
|
86
75
|
}
|
|
87
|
-
|
|
88
76
|
if (formConfig.initialReport === 'onBlur' && !field.dataset.conformTouched) {
|
|
89
77
|
field.dataset.conformTouched = 'true';
|
|
90
78
|
requestValidate(form, field.name);
|
|
91
79
|
}
|
|
92
80
|
};
|
|
93
|
-
|
|
94
81
|
var handleInvalid = event => {
|
|
95
82
|
var form = getFormElement(ref.current);
|
|
96
83
|
var field = event.target;
|
|
97
|
-
|
|
98
84
|
if (!form || !isFieldElement(field) || field.form !== form || field.name !== '') {
|
|
99
85
|
return;
|
|
100
86
|
}
|
|
101
|
-
|
|
102
87
|
event.preventDefault();
|
|
103
|
-
|
|
104
88
|
if (field.dataset.conformTouched) {
|
|
105
89
|
setError(field.validationMessage);
|
|
106
90
|
}
|
|
107
91
|
};
|
|
108
|
-
|
|
109
92
|
var handleReset = event => {
|
|
110
93
|
var form = ref.current;
|
|
111
94
|
var formConfig = configRef.current;
|
|
112
|
-
|
|
113
95
|
if (!form || event.target !== form) {
|
|
114
96
|
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
97
|
+
}
|
|
117
98
|
|
|
99
|
+
// Reset all field state
|
|
118
100
|
for (var field of form.elements) {
|
|
119
101
|
if (isFieldElement(field)) {
|
|
120
102
|
delete field.dataset.conformTouched;
|
|
121
103
|
field.setCustomValidity('');
|
|
122
104
|
}
|
|
123
105
|
}
|
|
124
|
-
|
|
125
106
|
setError('');
|
|
126
107
|
setFieldsetConfig({
|
|
127
108
|
defaultValue: formConfig.defaultValue,
|
|
128
109
|
initialError: []
|
|
129
110
|
});
|
|
130
111
|
};
|
|
112
|
+
|
|
131
113
|
/**
|
|
132
114
|
* The input event handler will be triggered in capturing phase in order to
|
|
133
115
|
* allow follow-up action in the bubble phase based on the latest validity
|
|
134
116
|
* E.g. `useFieldset` reset the error of valid field after checking the
|
|
135
117
|
* validity in the bubble phase.
|
|
136
118
|
*/
|
|
137
|
-
|
|
138
|
-
|
|
139
119
|
document.addEventListener('input', handleInput, true);
|
|
140
120
|
document.addEventListener('blur', handleBlur, true);
|
|
141
121
|
document.addEventListener('invalid', handleInvalid, true);
|
|
@@ -153,35 +133,30 @@ function useForm() {
|
|
|
153
133
|
props: {
|
|
154
134
|
ref,
|
|
155
135
|
noValidate,
|
|
156
|
-
|
|
157
136
|
onSubmit(event) {
|
|
158
137
|
var form = event.currentTarget;
|
|
159
138
|
var nativeEvent = event.nativeEvent;
|
|
160
139
|
var submitter = nativeEvent.submitter;
|
|
161
|
-
|
|
162
140
|
for (var element of form.elements) {
|
|
163
141
|
if (isFieldElement(element) && element.name === '') {
|
|
164
142
|
setError(element.validationMessage);
|
|
165
143
|
break;
|
|
166
144
|
}
|
|
167
145
|
}
|
|
146
|
+
|
|
168
147
|
/**
|
|
169
148
|
* It checks defaultPrevented to confirm if the submission is intentional
|
|
170
149
|
* This is utilized by `useFieldList` to modify the list state when the submit
|
|
171
150
|
* event is captured and revalidate the form with new fields without triggering
|
|
172
151
|
* a form submission at the same time.
|
|
173
152
|
*/
|
|
174
|
-
|
|
175
|
-
|
|
176
153
|
if (!submitter || event.defaultPrevented) {
|
|
177
154
|
event.preventDefault();
|
|
178
155
|
return;
|
|
179
156
|
}
|
|
180
|
-
|
|
181
157
|
try {
|
|
182
158
|
var submission;
|
|
183
159
|
var formData = getFormData(form, submitter);
|
|
184
|
-
|
|
185
160
|
if (typeof config.onValidate === 'function') {
|
|
186
161
|
submission = config.onValidate({
|
|
187
162
|
form,
|
|
@@ -189,7 +164,6 @@ function useForm() {
|
|
|
189
164
|
});
|
|
190
165
|
} else {
|
|
191
166
|
submission = parse(formData);
|
|
192
|
-
|
|
193
167
|
if (config.mode !== 'server-validation') {
|
|
194
168
|
/**
|
|
195
169
|
* As there is no custom logic defined,
|
|
@@ -203,16 +177,15 @@ function useForm() {
|
|
|
203
177
|
value: {},
|
|
204
178
|
error: []
|
|
205
179
|
});
|
|
206
|
-
|
|
207
180
|
for (var _element of form.elements) {
|
|
208
181
|
if (isFieldElement(_element) && _element.willValidate) {
|
|
209
182
|
submission.error.push([_element.name, _element.validationMessage]);
|
|
210
183
|
}
|
|
211
184
|
}
|
|
212
185
|
}
|
|
213
|
-
}
|
|
214
|
-
|
|
186
|
+
}
|
|
215
187
|
|
|
188
|
+
// Touch all fields only if the submitter is not a command button
|
|
216
189
|
if (submission.type === 'submit') {
|
|
217
190
|
for (var field of form.elements) {
|
|
218
191
|
if (isFieldElement(field)) {
|
|
@@ -221,21 +194,17 @@ function useForm() {
|
|
|
221
194
|
}
|
|
222
195
|
}
|
|
223
196
|
}
|
|
224
|
-
|
|
225
197
|
if (!config.noValidate && !submitter.formNoValidate && hasError(submission.error) || submission.type === 'validate' && config.mode !== 'server-validation') {
|
|
226
198
|
event.preventDefault();
|
|
227
199
|
} else {
|
|
228
200
|
var _config$onSubmit;
|
|
229
|
-
|
|
230
201
|
(_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, {
|
|
231
202
|
formData,
|
|
232
203
|
submission
|
|
233
204
|
});
|
|
234
205
|
}
|
|
235
|
-
|
|
236
206
|
if (event.defaultPrevented) {
|
|
237
207
|
setFormError(form, submission);
|
|
238
|
-
|
|
239
208
|
if (!form.reportValidity()) {
|
|
240
209
|
focusFirstInvalidField(form);
|
|
241
210
|
}
|
|
@@ -244,34 +213,29 @@ function useForm() {
|
|
|
244
213
|
console.warn(e);
|
|
245
214
|
}
|
|
246
215
|
}
|
|
247
|
-
|
|
248
216
|
},
|
|
249
217
|
config: fieldsetConfig
|
|
250
218
|
};
|
|
251
219
|
}
|
|
220
|
+
|
|
252
221
|
/**
|
|
253
222
|
* All the information of the field, including state and config.
|
|
254
223
|
*/
|
|
255
224
|
|
|
256
225
|
function useFieldset(ref, config) {
|
|
257
226
|
var configRef = useRef(config);
|
|
258
|
-
var [uncontrolledState, setUncontrolledState] = useState(
|
|
227
|
+
var [uncontrolledState, setUncontrolledState] = useState(
|
|
228
|
+
// @ts-expect-error
|
|
259
229
|
() => {
|
|
260
230
|
var _config$defaultValue;
|
|
261
|
-
|
|
262
231
|
var initialError = {};
|
|
263
|
-
|
|
264
232
|
for (var [name, message] of (_config$initialError = config === null || config === void 0 ? void 0 : config.initialError) !== null && _config$initialError !== void 0 ? _config$initialError : []) {
|
|
265
233
|
var _config$initialError;
|
|
266
|
-
|
|
267
234
|
var [key, ...paths] = getPaths(name);
|
|
268
|
-
|
|
269
235
|
if (typeof key === 'string') {
|
|
270
236
|
var _initialError$key;
|
|
271
|
-
|
|
272
237
|
var scopedName = getName(paths);
|
|
273
238
|
var entries = (_initialError$key = initialError[key]) !== null && _initialError$key !== void 0 ? _initialError$key : [];
|
|
274
|
-
|
|
275
239
|
if (scopedName === '' && entries.length > 0 && entries[0][0] !== '') {
|
|
276
240
|
initialError[key] = [[scopedName, message], ...entries];
|
|
277
241
|
} else {
|
|
@@ -279,7 +243,6 @@ function useFieldset(ref, config) {
|
|
|
279
243
|
}
|
|
280
244
|
}
|
|
281
245
|
}
|
|
282
|
-
|
|
283
246
|
return {
|
|
284
247
|
defaultValue: (_config$defaultValue = config === null || config === void 0 ? void 0 : config.defaultValue) !== null && _config$defaultValue !== void 0 ? _config$defaultValue : {},
|
|
285
248
|
initialError
|
|
@@ -287,17 +250,13 @@ function useFieldset(ref, config) {
|
|
|
287
250
|
});
|
|
288
251
|
var [error, setError] = useState(() => {
|
|
289
252
|
var result = {};
|
|
290
|
-
|
|
291
253
|
for (var [key, entries] of Object.entries(uncontrolledState.initialError)) {
|
|
292
254
|
var _entries$;
|
|
293
|
-
|
|
294
255
|
var [name, message] = (_entries$ = entries === null || entries === void 0 ? void 0 : entries[0]) !== null && _entries$ !== void 0 ? _entries$ : [];
|
|
295
|
-
|
|
296
256
|
if (name === '') {
|
|
297
257
|
result[key] = message !== null && message !== void 0 ? message : '';
|
|
298
258
|
}
|
|
299
259
|
}
|
|
300
|
-
|
|
301
260
|
return result;
|
|
302
261
|
});
|
|
303
262
|
useEffect(() => {
|
|
@@ -306,66 +265,53 @@ function useFieldset(ref, config) {
|
|
|
306
265
|
useEffect(() => {
|
|
307
266
|
var invalidHandler = event => {
|
|
308
267
|
var _configRef$current$na;
|
|
309
|
-
|
|
310
268
|
var form = getFormElement(ref.current);
|
|
311
269
|
var field = event.target;
|
|
312
270
|
var fieldsetName = (_configRef$current$na = configRef.current.name) !== null && _configRef$current$na !== void 0 ? _configRef$current$na : '';
|
|
313
|
-
|
|
314
271
|
if (!form || !isFieldElement(field) || field.form !== form || !field.name.startsWith(fieldsetName)) {
|
|
315
272
|
return;
|
|
316
273
|
}
|
|
274
|
+
var [key, ...paths] = getPaths(fieldsetName.length > 0 ? field.name.slice(fieldsetName.length + 1) : field.name);
|
|
317
275
|
|
|
318
|
-
|
|
319
|
-
|
|
276
|
+
// Update the error only if the field belongs to the fieldset
|
|
320
277
|
if (typeof key === 'string' && paths.length === 0) {
|
|
321
278
|
if (field.dataset.conformTouched) {
|
|
322
279
|
setError(prev => {
|
|
323
280
|
var _prev$key;
|
|
324
|
-
|
|
325
281
|
var prevMessage = (_prev$key = prev === null || prev === void 0 ? void 0 : prev[key]) !== null && _prev$key !== void 0 ? _prev$key : '';
|
|
326
|
-
|
|
327
282
|
if (prevMessage === field.validationMessage) {
|
|
328
283
|
return prev;
|
|
329
284
|
}
|
|
330
|
-
|
|
331
285
|
return _objectSpread2(_objectSpread2({}, prev), {}, {
|
|
332
286
|
[key]: field.validationMessage
|
|
333
287
|
});
|
|
334
288
|
});
|
|
335
289
|
}
|
|
336
|
-
|
|
337
290
|
event.preventDefault();
|
|
338
291
|
}
|
|
339
292
|
};
|
|
340
|
-
|
|
341
293
|
var submitHandler = event => {
|
|
342
294
|
var form = getFormElement(ref.current);
|
|
343
|
-
|
|
344
295
|
if (!form || event.target !== form) {
|
|
345
296
|
return;
|
|
346
297
|
}
|
|
298
|
+
|
|
347
299
|
/**
|
|
348
300
|
* Reset the error state of each field if its validity is changed.
|
|
349
301
|
*
|
|
350
302
|
* This is a workaround as no official way is provided to notify
|
|
351
303
|
* when the validity of the field is changed from `invalid` to `valid`.
|
|
352
304
|
*/
|
|
353
|
-
|
|
354
|
-
|
|
355
305
|
setError(prev => {
|
|
356
306
|
var _configRef$current$na2;
|
|
357
|
-
|
|
358
307
|
var next = prev;
|
|
359
308
|
var fieldsetName = (_configRef$current$na2 = configRef.current.name) !== null && _configRef$current$na2 !== void 0 ? _configRef$current$na2 : '';
|
|
360
|
-
|
|
361
309
|
for (var field of form.elements) {
|
|
362
310
|
if (isFieldElement(field) && field.name.startsWith(fieldsetName)) {
|
|
363
311
|
var _next$key, _next;
|
|
364
|
-
|
|
365
312
|
var key = fieldsetName ? field.name.slice(fieldsetName.length + 1) : field.name;
|
|
366
313
|
var prevMessage = (_next$key = (_next = next) === null || _next === void 0 ? void 0 : _next[key]) !== null && _next$key !== void 0 ? _next$key : '';
|
|
367
314
|
var nextMessage = field.validationMessage;
|
|
368
|
-
|
|
369
315
|
if (prevMessage !== '' && nextMessage === '') {
|
|
370
316
|
next = _objectSpread2(_objectSpread2({}, next), {}, {
|
|
371
317
|
[key]: ''
|
|
@@ -373,20 +319,15 @@ function useFieldset(ref, config) {
|
|
|
373
319
|
}
|
|
374
320
|
}
|
|
375
321
|
}
|
|
376
|
-
|
|
377
322
|
return next;
|
|
378
323
|
});
|
|
379
324
|
};
|
|
380
|
-
|
|
381
325
|
var resetHandler = event => {
|
|
382
326
|
var _fieldsetConfig$defau;
|
|
383
|
-
|
|
384
327
|
var form = getFormElement(ref.current);
|
|
385
|
-
|
|
386
328
|
if (!form || event.target !== form) {
|
|
387
329
|
return;
|
|
388
330
|
}
|
|
389
|
-
|
|
390
331
|
var fieldsetConfig = configRef.current;
|
|
391
332
|
setUncontrolledState({
|
|
392
333
|
// @ts-expect-error
|
|
@@ -394,9 +335,9 @@ function useFieldset(ref, config) {
|
|
|
394
335
|
initialError: {}
|
|
395
336
|
});
|
|
396
337
|
setError({});
|
|
397
|
-
};
|
|
398
|
-
|
|
338
|
+
};
|
|
399
339
|
|
|
340
|
+
// The invalid event does not bubble and so listening on the capturing pharse is needed
|
|
400
341
|
document.addEventListener('invalid', invalidHandler, true);
|
|
401
342
|
document.addEventListener('submit', submitHandler);
|
|
402
343
|
document.addEventListener('reset', resetHandler);
|
|
@@ -406,20 +347,18 @@ function useFieldset(ref, config) {
|
|
|
406
347
|
document.removeEventListener('reset', resetHandler);
|
|
407
348
|
};
|
|
408
349
|
}, [ref]);
|
|
350
|
+
|
|
409
351
|
/**
|
|
410
352
|
* This allows us constructing the field at runtime as we have no information
|
|
411
353
|
* about which fields would be available. The proxy will also help tracking
|
|
412
354
|
* the usage of each field for optimization in the future.
|
|
413
355
|
*/
|
|
414
|
-
|
|
415
356
|
return new Proxy({}, {
|
|
416
357
|
get(_target, key) {
|
|
417
358
|
var _fieldsetConfig$const, _error$key;
|
|
418
|
-
|
|
419
359
|
if (typeof key !== 'string') {
|
|
420
360
|
return;
|
|
421
361
|
}
|
|
422
|
-
|
|
423
362
|
var fieldsetConfig = config !== null && config !== void 0 ? config : {};
|
|
424
363
|
var constraint = (_fieldsetConfig$const = fieldsetConfig.constraint) === null || _fieldsetConfig$const === void 0 ? void 0 : _fieldsetConfig$const[key];
|
|
425
364
|
var field = {
|
|
@@ -433,10 +372,8 @@ function useFieldset(ref, config) {
|
|
|
433
372
|
};
|
|
434
373
|
return field;
|
|
435
374
|
}
|
|
436
|
-
|
|
437
375
|
});
|
|
438
376
|
}
|
|
439
|
-
|
|
440
377
|
/**
|
|
441
378
|
* Returns a list of key and config, with a group of helpers
|
|
442
379
|
* configuring buttons for list manipulation
|
|
@@ -447,21 +384,14 @@ function useFieldList(ref, config) {
|
|
|
447
384
|
var configRef = useRef(config);
|
|
448
385
|
var [uncontrolledState, setUncontrolledState] = useState(() => {
|
|
449
386
|
var _config$defaultValue2;
|
|
450
|
-
|
|
451
387
|
var initialError = [];
|
|
452
|
-
|
|
453
388
|
for (var [name, message] of (_config$initialError2 = config === null || config === void 0 ? void 0 : config.initialError) !== null && _config$initialError2 !== void 0 ? _config$initialError2 : []) {
|
|
454
389
|
var _config$initialError2;
|
|
455
|
-
|
|
456
390
|
var [index, ...paths] = getPaths(name);
|
|
457
|
-
|
|
458
391
|
if (typeof index === 'number') {
|
|
459
392
|
var _initialError$index;
|
|
460
|
-
|
|
461
393
|
var scopedName = getName(paths);
|
|
462
|
-
|
|
463
394
|
var _entries = (_initialError$index = initialError[index]) !== null && _initialError$index !== void 0 ? _initialError$index : [];
|
|
464
|
-
|
|
465
395
|
if (scopedName === '' && _entries.length > 0 && _entries[0][0] !== '') {
|
|
466
396
|
initialError[index] = [[scopedName, message], ..._entries];
|
|
467
397
|
} else {
|
|
@@ -469,7 +399,6 @@ function useFieldList(ref, config) {
|
|
|
469
399
|
}
|
|
470
400
|
}
|
|
471
401
|
}
|
|
472
|
-
|
|
473
402
|
return {
|
|
474
403
|
defaultValue: (_config$defaultValue2 = config.defaultValue) !== null && _config$defaultValue2 !== void 0 ? _config$defaultValue2 : [],
|
|
475
404
|
initialError
|
|
@@ -477,7 +406,6 @@ function useFieldList(ref, config) {
|
|
|
477
406
|
});
|
|
478
407
|
var [entries, setEntries] = useState(() => {
|
|
479
408
|
var _config$defaultValue3;
|
|
480
|
-
|
|
481
409
|
return Object.entries((_config$defaultValue3 = config.defaultValue) !== null && _config$defaultValue3 !== void 0 ? _config$defaultValue3 : [undefined]);
|
|
482
410
|
});
|
|
483
411
|
var list = entries.map((_ref3, index) => {
|
|
@@ -492,11 +420,11 @@ function useFieldList(ref, config) {
|
|
|
492
420
|
}
|
|
493
421
|
};
|
|
494
422
|
});
|
|
423
|
+
|
|
495
424
|
/***
|
|
496
425
|
* This use proxy to capture all information about the command and
|
|
497
426
|
* have it encoded in the value.
|
|
498
427
|
*/
|
|
499
|
-
|
|
500
428
|
var command = new Proxy({}, {
|
|
501
429
|
get(_target, type) {
|
|
502
430
|
return function () {
|
|
@@ -513,7 +441,6 @@ function useFieldList(ref, config) {
|
|
|
513
441
|
};
|
|
514
442
|
};
|
|
515
443
|
}
|
|
516
|
-
|
|
517
444
|
});
|
|
518
445
|
useEffect(() => {
|
|
519
446
|
configRef.current = config;
|
|
@@ -521,18 +448,14 @@ function useFieldList(ref, config) {
|
|
|
521
448
|
useEffect(() => {
|
|
522
449
|
var submitHandler = event => {
|
|
523
450
|
var form = getFormElement(ref.current);
|
|
524
|
-
|
|
525
451
|
if (!form || event.target !== form || !(event.submitter instanceof HTMLButtonElement) || event.submitter.name !== 'conform/list') {
|
|
526
452
|
return;
|
|
527
453
|
}
|
|
528
|
-
|
|
529
454
|
var command = parseListCommand(event.submitter.value);
|
|
530
|
-
|
|
531
455
|
if (command.scope !== configRef.current.name) {
|
|
532
456
|
// Ensure the scope of the listener are limited to specific field name
|
|
533
457
|
return;
|
|
534
458
|
}
|
|
535
|
-
|
|
536
459
|
setEntries(entries => {
|
|
537
460
|
switch (command.type) {
|
|
538
461
|
case 'append':
|
|
@@ -543,7 +466,6 @@ function useFieldList(ref, config) {
|
|
|
543
466
|
defaultValue: ["".concat(Date.now()), command.payload.defaultValue]
|
|
544
467
|
})
|
|
545
468
|
}));
|
|
546
|
-
|
|
547
469
|
default:
|
|
548
470
|
{
|
|
549
471
|
return updateList([...(entries !== null && entries !== void 0 ? entries : [])], command);
|
|
@@ -552,16 +474,12 @@ function useFieldList(ref, config) {
|
|
|
552
474
|
});
|
|
553
475
|
event.preventDefault();
|
|
554
476
|
};
|
|
555
|
-
|
|
556
477
|
var resetHandler = event => {
|
|
557
478
|
var _fieldConfig$defaultV, _fieldConfig$defaultV2;
|
|
558
|
-
|
|
559
479
|
var form = getFormElement(ref.current);
|
|
560
|
-
|
|
561
480
|
if (!form || event.target !== form) {
|
|
562
481
|
return;
|
|
563
482
|
}
|
|
564
|
-
|
|
565
483
|
var fieldConfig = configRef.current;
|
|
566
484
|
setUncontrolledState({
|
|
567
485
|
defaultValue: (_fieldConfig$defaultV = fieldConfig.defaultValue) !== null && _fieldConfig$defaultV !== void 0 ? _fieldConfig$defaultV : [],
|
|
@@ -569,7 +487,6 @@ function useFieldList(ref, config) {
|
|
|
569
487
|
});
|
|
570
488
|
setEntries(Object.entries((_fieldConfig$defaultV2 = fieldConfig.defaultValue) !== null && _fieldConfig$defaultV2 !== void 0 ? _fieldConfig$defaultV2 : [undefined]));
|
|
571
489
|
};
|
|
572
|
-
|
|
573
490
|
document.addEventListener('submit', submitHandler, true);
|
|
574
491
|
document.addEventListener('reset', resetHandler);
|
|
575
492
|
return () => {
|
|
@@ -577,10 +494,10 @@ function useFieldList(ref, config) {
|
|
|
577
494
|
document.removeEventListener('reset', resetHandler);
|
|
578
495
|
};
|
|
579
496
|
}, [ref]);
|
|
580
|
-
return [list,
|
|
497
|
+
return [list,
|
|
498
|
+
// @ts-expect-error proxy type
|
|
581
499
|
command];
|
|
582
500
|
}
|
|
583
|
-
|
|
584
501
|
/**
|
|
585
502
|
* Returns the properties required to configure a shadow input for validation.
|
|
586
503
|
* This is particular useful when integrating dropdown and datepicker whichs
|
|
@@ -590,7 +507,6 @@ function useFieldList(ref, config) {
|
|
|
590
507
|
*/
|
|
591
508
|
function useControlledInput(config) {
|
|
592
509
|
var _config$defaultValue4;
|
|
593
|
-
|
|
594
510
|
var ref = useRef(null);
|
|
595
511
|
var inputRef = useRef(null);
|
|
596
512
|
var configRef = useRef(config);
|
|
@@ -599,12 +515,10 @@ function useControlledInput(config) {
|
|
|
599
515
|
initialError: config.initialError
|
|
600
516
|
});
|
|
601
517
|
var [value, setValue] = useState("".concat((_config$defaultValue4 = config.defaultValue) !== null && _config$defaultValue4 !== void 0 ? _config$defaultValue4 : ''));
|
|
602
|
-
|
|
603
518
|
var handleChange = eventOrValue => {
|
|
604
519
|
if (!ref.current) {
|
|
605
520
|
return;
|
|
606
521
|
}
|
|
607
|
-
|
|
608
522
|
var newValue = typeof eventOrValue === 'string' ? eventOrValue : eventOrValue.target.value;
|
|
609
523
|
ref.current.value = newValue;
|
|
610
524
|
ref.current.dispatchEvent(new InputEvent('input', {
|
|
@@ -612,39 +526,31 @@ function useControlledInput(config) {
|
|
|
612
526
|
}));
|
|
613
527
|
setValue(newValue);
|
|
614
528
|
};
|
|
615
|
-
|
|
616
529
|
var handleBlur = () => {
|
|
617
530
|
var _ref$current;
|
|
618
|
-
|
|
619
531
|
(_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.dispatchEvent(new FocusEvent('blur', {
|
|
620
532
|
bubbles: true
|
|
621
533
|
}));
|
|
622
534
|
};
|
|
623
|
-
|
|
624
535
|
var handleInvalid = event => {
|
|
625
536
|
event.preventDefault();
|
|
626
537
|
};
|
|
627
|
-
|
|
628
538
|
useEffect(() => {
|
|
629
539
|
configRef.current = config;
|
|
630
540
|
});
|
|
631
541
|
useEffect(() => {
|
|
632
542
|
var resetHandler = event => {
|
|
633
543
|
var _configRef$current$de;
|
|
634
|
-
|
|
635
544
|
var form = getFormElement(ref.current);
|
|
636
|
-
|
|
637
545
|
if (!form || event.target !== form) {
|
|
638
546
|
return;
|
|
639
547
|
}
|
|
640
|
-
|
|
641
548
|
setUncontrolledState({
|
|
642
549
|
defaultValue: configRef.current.defaultValue,
|
|
643
550
|
initialError: configRef.current.initialError
|
|
644
551
|
});
|
|
645
552
|
setValue("".concat((_configRef$current$de = configRef.current.defaultValue) !== null && _configRef$current$de !== void 0 ? _configRef$current$de : ''));
|
|
646
553
|
};
|
|
647
|
-
|
|
648
554
|
document.addEventListener('reset', resetHandler);
|
|
649
555
|
return () => {
|
|
650
556
|
document.removeEventListener('reset', resetHandler);
|
|
@@ -663,13 +569,10 @@ function useControlledInput(config) {
|
|
|
663
569
|
whiteSpace: 'nowrap',
|
|
664
570
|
borderWidth: 0
|
|
665
571
|
},
|
|
666
|
-
|
|
667
572
|
onFocus() {
|
|
668
573
|
var _inputRef$current;
|
|
669
|
-
|
|
670
574
|
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
|
|
671
575
|
}
|
|
672
|
-
|
|
673
576
|
}, input(_objectSpread2(_objectSpread2({}, config), uncontrolledState), {
|
|
674
577
|
type: 'text'
|
|
675
578
|
})), {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@conform-to/react",
|
|
3
3
|
"description": "Conform view adapter for react",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "0.4.0
|
|
5
|
+
"version": "0.4.0",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"module": "module/index.js",
|
|
8
8
|
"repository": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"url": "https://github.com/edmundhung/conform/issues"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@conform-to/dom": "0.4.0
|
|
22
|
+
"@conform-to/dom": "0.4.0"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"react": ">=16.8"
|