@conform-to/dom 1.8.1 → 1.9.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/README.md +1 -1
- package/dist/dom.d.ts +32 -2
- package/dist/dom.js +111 -24
- package/dist/dom.mjs +104 -22
- package/dist/form.js +51 -40
- package/dist/form.mjs +49 -38
- package/dist/formdata.d.ts +122 -75
- package/dist/formdata.js +341 -241
- package/dist/formdata.mjs +328 -225
- package/dist/future/index.d.ts +5 -0
- package/dist/future/index.js +38 -0
- package/dist/future/index.mjs +3 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -9
- package/dist/index.mjs +2 -2
- package/dist/submission.d.ts +13 -0
- package/dist/submission.js +81 -15
- package/dist/submission.mjs +77 -13
- package/dist/types.d.ts +99 -0
- package/dist/util.d.ts +11 -0
- package/dist/util.js +67 -0
- package/dist/util.mjs +65 -1
- package/package.json +8 -1
package/dist/form.js
CHANGED
|
@@ -37,13 +37,13 @@ function createFormMeta(options, isResetting) {
|
|
|
37
37
|
return result;
|
|
38
38
|
}
|
|
39
39
|
function getDefaultKey(defaultValue, prefix) {
|
|
40
|
-
return Object.entries(
|
|
40
|
+
return Object.entries(submission.flatten(defaultValue, {
|
|
41
41
|
prefix
|
|
42
42
|
})).reduce((result, _ref2) => {
|
|
43
43
|
var [key, value] = _ref2;
|
|
44
44
|
if (Array.isArray(value)) {
|
|
45
45
|
for (var i = 0; i < value.length; i++) {
|
|
46
|
-
result[formdata.
|
|
46
|
+
result[formdata.appendPathSegment(key, i)] = util.generateId();
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
return result;
|
|
@@ -76,7 +76,7 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
76
76
|
validated,
|
|
77
77
|
value
|
|
78
78
|
} = intent.payload;
|
|
79
|
-
var _name2 = formdata.
|
|
79
|
+
var _name2 = formdata.appendPathSegment(intent.payload.name, intent.payload.index);
|
|
80
80
|
if (typeof value !== 'undefined') {
|
|
81
81
|
updateValue(meta, _name2 !== null && _name2 !== void 0 ? _name2 : '', value);
|
|
82
82
|
}
|
|
@@ -88,8 +88,8 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
88
88
|
meta.validated = {};
|
|
89
89
|
}
|
|
90
90
|
if (validated) {
|
|
91
|
-
if (
|
|
92
|
-
Object.assign(meta.validated,
|
|
91
|
+
if (util.isPlainObject(value) || Array.isArray(value)) {
|
|
92
|
+
Object.assign(meta.validated, submission.flatten(value, {
|
|
93
93
|
resolve() {
|
|
94
94
|
return true;
|
|
95
95
|
},
|
|
@@ -105,8 +105,8 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
105
105
|
}
|
|
106
106
|
case 'reset':
|
|
107
107
|
{
|
|
108
|
-
var _name3 = formdata.
|
|
109
|
-
var _value = formdata.
|
|
108
|
+
var _name3 = formdata.appendPathSegment(intent.payload.name, intent.payload.index);
|
|
109
|
+
var _value = formdata.getValueAtPath(meta.defaultValue, _name3);
|
|
110
110
|
updateValue(meta, _name3, _value);
|
|
111
111
|
if (_name3) {
|
|
112
112
|
submission.setState(meta.validated, _name3, () => undefined);
|
|
@@ -124,7 +124,7 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
124
124
|
meta.initialValue = util.clone(meta.initialValue);
|
|
125
125
|
meta.key = util.clone(meta.key);
|
|
126
126
|
submission.setListState(meta.key, intent, defaultValue => {
|
|
127
|
-
if (!Array.isArray(defaultValue) && !
|
|
127
|
+
if (!Array.isArray(defaultValue) && !util.isPlainObject(defaultValue)) {
|
|
128
128
|
return util.generateId();
|
|
129
129
|
}
|
|
130
130
|
return Object.assign(getDefaultKey(defaultValue), {
|
|
@@ -159,9 +159,9 @@ function updateValue(meta, name, value) {
|
|
|
159
159
|
meta.initialValue = util.clone(meta.initialValue);
|
|
160
160
|
meta.value = util.clone(meta.value);
|
|
161
161
|
meta.key = util.clone(meta.key);
|
|
162
|
-
formdata.
|
|
163
|
-
formdata.
|
|
164
|
-
if (
|
|
162
|
+
formdata.setValueAtPath(meta.initialValue, name, () => value);
|
|
163
|
+
formdata.setValueAtPath(meta.value, name, () => value);
|
|
164
|
+
if (util.isPlainObject(value) || Array.isArray(value)) {
|
|
165
165
|
submission.setState(meta.key, name, () => undefined);
|
|
166
166
|
Object.assign(meta.key, getDefaultKey(value, name));
|
|
167
167
|
}
|
|
@@ -180,16 +180,16 @@ function createStateProxy(fn) {
|
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
182
|
function createValueProxy(value) {
|
|
183
|
-
var val =
|
|
183
|
+
var val = submission.normalize(value);
|
|
184
184
|
return createStateProxy((name, proxy) => {
|
|
185
185
|
if (name === '') {
|
|
186
186
|
return val;
|
|
187
187
|
}
|
|
188
|
-
var
|
|
189
|
-
var basename = formdata.
|
|
190
|
-
var key = formdata.
|
|
188
|
+
var path = formdata.getPathSegments(name);
|
|
189
|
+
var basename = formdata.formatPathSegments(path.slice(0, -1));
|
|
190
|
+
var key = formdata.formatPathSegments(path.slice(-1));
|
|
191
191
|
var parentValue = proxy[basename];
|
|
192
|
-
return formdata.
|
|
192
|
+
return formdata.getValueAtPath(parentValue, key);
|
|
193
193
|
});
|
|
194
194
|
}
|
|
195
195
|
function createConstraintProxy(constraint) {
|
|
@@ -197,15 +197,20 @@ function createConstraintProxy(constraint) {
|
|
|
197
197
|
var _result;
|
|
198
198
|
var result = constraint[name];
|
|
199
199
|
if (!result) {
|
|
200
|
-
var
|
|
201
|
-
for (var i =
|
|
202
|
-
var
|
|
203
|
-
|
|
204
|
-
|
|
200
|
+
var path = formdata.getPathSegments(name);
|
|
201
|
+
for (var i = path.length - 1; i >= 0; i--) {
|
|
202
|
+
var segment = path[i];
|
|
203
|
+
|
|
204
|
+
// Try searching a less specific path for the constraint
|
|
205
|
+
// e.g. `array[0].anotherArray[1].key` -> `array[0].anotherArray[].key` -> `array[].anotherArray[].key`
|
|
206
|
+
if (typeof segment === 'number') {
|
|
207
|
+
// This overrides the current number segment with an empty string
|
|
208
|
+
// which will be treated as an empty bracket
|
|
209
|
+
path[i] = '';
|
|
205
210
|
break;
|
|
206
211
|
}
|
|
207
212
|
}
|
|
208
|
-
var alternative = formdata.
|
|
213
|
+
var alternative = formdata.formatPathSegments(path);
|
|
209
214
|
if (name !== alternative) {
|
|
210
215
|
result = proxy[alternative];
|
|
211
216
|
}
|
|
@@ -216,15 +221,15 @@ function createConstraintProxy(constraint) {
|
|
|
216
221
|
function createKeyProxy(key) {
|
|
217
222
|
return createStateProxy((name, proxy) => {
|
|
218
223
|
var currentKey = key[name];
|
|
219
|
-
var
|
|
220
|
-
if (
|
|
224
|
+
var segments = formdata.getPathSegments(name);
|
|
225
|
+
if (segments.length === 0) {
|
|
221
226
|
return currentKey;
|
|
222
227
|
}
|
|
223
|
-
var parentKey = proxy[formdata.
|
|
228
|
+
var parentKey = proxy[formdata.formatPathSegments(segments.slice(0, -1))];
|
|
224
229
|
if (typeof parentKey === 'undefined') {
|
|
225
230
|
return currentKey;
|
|
226
231
|
}
|
|
227
|
-
return "".concat(parentKey, "/").concat(currentKey !== null && currentKey !== void 0 ? currentKey :
|
|
232
|
+
return "".concat(parentKey, "/").concat(currentKey !== null && currentKey !== void 0 ? currentKey : segments.at(-1));
|
|
228
233
|
});
|
|
229
234
|
}
|
|
230
235
|
function createValidProxy(error) {
|
|
@@ -575,19 +580,22 @@ function createFormContext(options) {
|
|
|
575
580
|
switch (intent.type) {
|
|
576
581
|
case 'update':
|
|
577
582
|
{
|
|
578
|
-
var _name5 = formdata.
|
|
579
|
-
var
|
|
583
|
+
var _name5 = formdata.appendPathSegment(intent.payload.name, intent.payload.index);
|
|
584
|
+
var baseSegments = formdata.getPathSegments(_name5);
|
|
580
585
|
for (var element of formElement.elements) {
|
|
581
586
|
if (dom.isFieldElement(element)) {
|
|
582
|
-
var paths = formdata.
|
|
587
|
+
var paths = formdata.getRelativePath(element.name, baseSegments);
|
|
583
588
|
if (paths) {
|
|
584
|
-
var value = formdata.
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
589
|
+
var value = formdata.getValueAtPath(intent.payload.value, paths);
|
|
590
|
+
var inputValue = typeof value === 'string' || Array.isArray(value) && value.every(item => typeof item === 'string') ? value : undefined;
|
|
591
|
+
if (typeof inputValue !== 'undefined' || _name5 === '' && paths.length > 1) {
|
|
592
|
+
dom.updateField(element, {
|
|
593
|
+
value: inputValue !== null && inputValue !== void 0 ? inputValue : null
|
|
594
|
+
});
|
|
588
595
|
|
|
589
|
-
|
|
590
|
-
|
|
596
|
+
// Update the element attribute to notify useControl / useInputControl hook
|
|
597
|
+
element.dataset.conform = util.generateId();
|
|
598
|
+
}
|
|
591
599
|
}
|
|
592
600
|
}
|
|
593
601
|
}
|
|
@@ -595,14 +603,17 @@ function createFormContext(options) {
|
|
|
595
603
|
}
|
|
596
604
|
case 'reset':
|
|
597
605
|
{
|
|
598
|
-
var prefix = formdata.
|
|
606
|
+
var prefix = formdata.appendPathSegment(intent.payload.name, intent.payload.index);
|
|
599
607
|
for (var _element of formElement.elements) {
|
|
600
608
|
if (dom.isFieldElement(_element) && _element.name && formdata.isPrefix(_element.name, prefix)) {
|
|
601
|
-
var _value2 = formdata.
|
|
602
|
-
var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 :
|
|
609
|
+
var _value2 = formdata.getValueAtPath(meta.defaultValue, _element.name);
|
|
610
|
+
var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 : undefined;
|
|
611
|
+
if (typeof defaultValue === 'undefined' && !_element.dataset.conform && 'defaultValue' in _element && !dom.isDirtyInput(_element)) {
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
603
614
|
dom.updateField(_element, {
|
|
604
|
-
defaultValue,
|
|
605
|
-
value: defaultValue
|
|
615
|
+
defaultValue: defaultValue,
|
|
616
|
+
value: defaultValue !== null && defaultValue !== void 0 ? defaultValue : null
|
|
606
617
|
});
|
|
607
618
|
|
|
608
619
|
// Update the element attribute to notify useControl / useInputControl hook
|
package/dist/form.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
-
import {
|
|
3
|
-
import { getFormAction, getFormEncType, getFormMethod, isFieldElement, requestSubmit, updateField } from './dom.mjs';
|
|
4
|
-
import { generateId, clone, invariant } from './util.mjs';
|
|
5
|
-
import { serialize, setListState, setListValue, setState, INTENT, serializeIntent, root, getSubmissionContext } from './submission.mjs';
|
|
2
|
+
import { appendPathSegment, getValueAtPath, isPrefix, setValueAtPath, getFormData, getPathSegments, getRelativePath, formatPathSegments } from './formdata.mjs';
|
|
3
|
+
import { getFormAction, getFormEncType, getFormMethod, isFieldElement, requestSubmit, isDirtyInput, updateField } from './dom.mjs';
|
|
4
|
+
import { generateId, clone, isPlainObject, invariant } from './util.mjs';
|
|
5
|
+
import { serialize, flatten, setListState, setListValue, setState, normalize, INTENT, serializeIntent, root, getSubmissionContext } from './submission.mjs';
|
|
6
6
|
|
|
7
7
|
function createFormMeta(options, isResetting) {
|
|
8
8
|
var _lastResult$initialVa, _options$constraint, _lastResult$state$val, _lastResult$state, _ref;
|
|
@@ -39,7 +39,7 @@ function getDefaultKey(defaultValue, prefix) {
|
|
|
39
39
|
var [key, value] = _ref2;
|
|
40
40
|
if (Array.isArray(value)) {
|
|
41
41
|
for (var i = 0; i < value.length; i++) {
|
|
42
|
-
result[
|
|
42
|
+
result[appendPathSegment(key, i)] = generateId();
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
return result;
|
|
@@ -72,7 +72,7 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
72
72
|
validated,
|
|
73
73
|
value
|
|
74
74
|
} = intent.payload;
|
|
75
|
-
var _name2 =
|
|
75
|
+
var _name2 = appendPathSegment(intent.payload.name, intent.payload.index);
|
|
76
76
|
if (typeof value !== 'undefined') {
|
|
77
77
|
updateValue(meta, _name2 !== null && _name2 !== void 0 ? _name2 : '', value);
|
|
78
78
|
}
|
|
@@ -101,8 +101,8 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
101
101
|
}
|
|
102
102
|
case 'reset':
|
|
103
103
|
{
|
|
104
|
-
var _name3 =
|
|
105
|
-
var _value =
|
|
104
|
+
var _name3 = appendPathSegment(intent.payload.name, intent.payload.index);
|
|
105
|
+
var _value = getValueAtPath(meta.defaultValue, _name3);
|
|
106
106
|
updateValue(meta, _name3, _value);
|
|
107
107
|
if (_name3) {
|
|
108
108
|
setState(meta.validated, _name3, () => undefined);
|
|
@@ -155,8 +155,8 @@ function updateValue(meta, name, value) {
|
|
|
155
155
|
meta.initialValue = clone(meta.initialValue);
|
|
156
156
|
meta.value = clone(meta.value);
|
|
157
157
|
meta.key = clone(meta.key);
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
setValueAtPath(meta.initialValue, name, () => value);
|
|
159
|
+
setValueAtPath(meta.value, name, () => value);
|
|
160
160
|
if (isPlainObject(value) || Array.isArray(value)) {
|
|
161
161
|
setState(meta.key, name, () => undefined);
|
|
162
162
|
Object.assign(meta.key, getDefaultKey(value, name));
|
|
@@ -181,11 +181,11 @@ function createValueProxy(value) {
|
|
|
181
181
|
if (name === '') {
|
|
182
182
|
return val;
|
|
183
183
|
}
|
|
184
|
-
var
|
|
185
|
-
var basename =
|
|
186
|
-
var key =
|
|
184
|
+
var path = getPathSegments(name);
|
|
185
|
+
var basename = formatPathSegments(path.slice(0, -1));
|
|
186
|
+
var key = formatPathSegments(path.slice(-1));
|
|
187
187
|
var parentValue = proxy[basename];
|
|
188
|
-
return
|
|
188
|
+
return getValueAtPath(parentValue, key);
|
|
189
189
|
});
|
|
190
190
|
}
|
|
191
191
|
function createConstraintProxy(constraint) {
|
|
@@ -193,15 +193,20 @@ function createConstraintProxy(constraint) {
|
|
|
193
193
|
var _result;
|
|
194
194
|
var result = constraint[name];
|
|
195
195
|
if (!result) {
|
|
196
|
-
var
|
|
197
|
-
for (var i =
|
|
198
|
-
var
|
|
199
|
-
|
|
200
|
-
|
|
196
|
+
var path = getPathSegments(name);
|
|
197
|
+
for (var i = path.length - 1; i >= 0; i--) {
|
|
198
|
+
var segment = path[i];
|
|
199
|
+
|
|
200
|
+
// Try searching a less specific path for the constraint
|
|
201
|
+
// e.g. `array[0].anotherArray[1].key` -> `array[0].anotherArray[].key` -> `array[].anotherArray[].key`
|
|
202
|
+
if (typeof segment === 'number') {
|
|
203
|
+
// This overrides the current number segment with an empty string
|
|
204
|
+
// which will be treated as an empty bracket
|
|
205
|
+
path[i] = '';
|
|
201
206
|
break;
|
|
202
207
|
}
|
|
203
208
|
}
|
|
204
|
-
var alternative =
|
|
209
|
+
var alternative = formatPathSegments(path);
|
|
205
210
|
if (name !== alternative) {
|
|
206
211
|
result = proxy[alternative];
|
|
207
212
|
}
|
|
@@ -212,15 +217,15 @@ function createConstraintProxy(constraint) {
|
|
|
212
217
|
function createKeyProxy(key) {
|
|
213
218
|
return createStateProxy((name, proxy) => {
|
|
214
219
|
var currentKey = key[name];
|
|
215
|
-
var
|
|
216
|
-
if (
|
|
220
|
+
var segments = getPathSegments(name);
|
|
221
|
+
if (segments.length === 0) {
|
|
217
222
|
return currentKey;
|
|
218
223
|
}
|
|
219
|
-
var parentKey = proxy[
|
|
224
|
+
var parentKey = proxy[formatPathSegments(segments.slice(0, -1))];
|
|
220
225
|
if (typeof parentKey === 'undefined') {
|
|
221
226
|
return currentKey;
|
|
222
227
|
}
|
|
223
|
-
return "".concat(parentKey, "/").concat(currentKey !== null && currentKey !== void 0 ? currentKey :
|
|
228
|
+
return "".concat(parentKey, "/").concat(currentKey !== null && currentKey !== void 0 ? currentKey : segments.at(-1));
|
|
224
229
|
});
|
|
225
230
|
}
|
|
226
231
|
function createValidProxy(error) {
|
|
@@ -571,19 +576,22 @@ function createFormContext(options) {
|
|
|
571
576
|
switch (intent.type) {
|
|
572
577
|
case 'update':
|
|
573
578
|
{
|
|
574
|
-
var _name5 =
|
|
575
|
-
var
|
|
579
|
+
var _name5 = appendPathSegment(intent.payload.name, intent.payload.index);
|
|
580
|
+
var baseSegments = getPathSegments(_name5);
|
|
576
581
|
for (var element of formElement.elements) {
|
|
577
582
|
if (isFieldElement(element)) {
|
|
578
|
-
var paths =
|
|
583
|
+
var paths = getRelativePath(element.name, baseSegments);
|
|
579
584
|
if (paths) {
|
|
580
|
-
var value =
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
585
|
+
var value = getValueAtPath(intent.payload.value, paths);
|
|
586
|
+
var inputValue = typeof value === 'string' || Array.isArray(value) && value.every(item => typeof item === 'string') ? value : undefined;
|
|
587
|
+
if (typeof inputValue !== 'undefined' || _name5 === '' && paths.length > 1) {
|
|
588
|
+
updateField(element, {
|
|
589
|
+
value: inputValue !== null && inputValue !== void 0 ? inputValue : null
|
|
590
|
+
});
|
|
584
591
|
|
|
585
|
-
|
|
586
|
-
|
|
592
|
+
// Update the element attribute to notify useControl / useInputControl hook
|
|
593
|
+
element.dataset.conform = generateId();
|
|
594
|
+
}
|
|
587
595
|
}
|
|
588
596
|
}
|
|
589
597
|
}
|
|
@@ -591,14 +599,17 @@ function createFormContext(options) {
|
|
|
591
599
|
}
|
|
592
600
|
case 'reset':
|
|
593
601
|
{
|
|
594
|
-
var prefix =
|
|
602
|
+
var prefix = appendPathSegment(intent.payload.name, intent.payload.index);
|
|
595
603
|
for (var _element of formElement.elements) {
|
|
596
604
|
if (isFieldElement(_element) && _element.name && isPrefix(_element.name, prefix)) {
|
|
597
|
-
var _value2 =
|
|
598
|
-
var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 :
|
|
605
|
+
var _value2 = getValueAtPath(meta.defaultValue, _element.name);
|
|
606
|
+
var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 : undefined;
|
|
607
|
+
if (typeof defaultValue === 'undefined' && !_element.dataset.conform && 'defaultValue' in _element && !isDirtyInput(_element)) {
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
599
610
|
updateField(_element, {
|
|
600
|
-
defaultValue,
|
|
601
|
-
value: defaultValue
|
|
611
|
+
defaultValue: defaultValue,
|
|
612
|
+
value: defaultValue !== null && defaultValue !== void 0 ? defaultValue : null
|
|
602
613
|
});
|
|
603
614
|
|
|
604
615
|
// Update the element attribute to notify useControl / useInputControl hook
|
package/dist/formdata.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { FormError, FormValue, JsonPrimitive, Serialize, SerializedValue, Submission, SubmissionResult } from './types';
|
|
2
|
+
export declare const DEFAULT_INTENT_NAME = "__INTENT__";
|
|
1
3
|
/**
|
|
2
4
|
* Construct a form data with the submitter value.
|
|
3
5
|
* It utilizes the submitter argument on the FormData constructor from modern browsers
|
|
@@ -5,96 +7,83 @@
|
|
|
5
7
|
*
|
|
6
8
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData#parameters
|
|
7
9
|
*/
|
|
8
|
-
export declare function getFormData(form: HTMLFormElement, submitter?:
|
|
10
|
+
export declare function getFormData(form: HTMLFormElement, submitter?: HTMLElement | null): FormData;
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Convert a string path into an array of segments.
|
|
13
|
+
*
|
|
11
14
|
* @example
|
|
12
15
|
* ```js
|
|
13
|
-
*
|
|
16
|
+
* getPathSegments("object.key"); // → ['object', 'key']
|
|
17
|
+
* getPathSegments("array[0].content"); // → ['array', 0, 'content']
|
|
18
|
+
* getPathSegments("todos[]"); // → ['todos', '']
|
|
14
19
|
* ```
|
|
15
20
|
*/
|
|
16
|
-
export declare function
|
|
21
|
+
export declare function getPathSegments(path: string | undefined): Array<string | number>;
|
|
17
22
|
/**
|
|
18
|
-
* Returns a formatted name from the
|
|
23
|
+
* Returns a formatted name from the path segments based on the dot and bracket notation.
|
|
24
|
+
*
|
|
19
25
|
* @example
|
|
20
26
|
* ```js
|
|
21
|
-
*
|
|
27
|
+
* formatPathSegments(['object', 'key']); // → "object.key"
|
|
28
|
+
* formatPathSegments(['array', 0, 'content']); // → "array[0].content"
|
|
29
|
+
* formatPathSegments(['todos', '']); // → "todos[]"
|
|
22
30
|
* ```
|
|
23
31
|
*/
|
|
24
|
-
export declare function
|
|
32
|
+
export declare function formatPathSegments(segments: Readonly<Array<string | number>>): string;
|
|
25
33
|
/**
|
|
26
|
-
*
|
|
34
|
+
* Append one more segment onto an existing path string.
|
|
35
|
+
*
|
|
36
|
+
* - segment = `undefined` ⇒ no-op
|
|
37
|
+
* - segment = `""` ⇒ empty brackets "[]"
|
|
38
|
+
* - segment = `number` ⇒ bracket notation "[n]"
|
|
39
|
+
* - segment = `string` ⇒ dot-notation ".prop"
|
|
27
40
|
*/
|
|
28
|
-
export declare function
|
|
41
|
+
export declare function appendPathSegment(path: string | undefined, segment: string | number | undefined): string;
|
|
29
42
|
/**
|
|
30
|
-
*
|
|
43
|
+
* Returns true if `prefix` is a valid leading path of `name`.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```js
|
|
47
|
+
* isPrefix("foo.bar.baz", "foo.bar") // → true
|
|
48
|
+
* isPrefix("foo.bar[3].baz", "foo.bar[3]") // → true
|
|
49
|
+
* isPrefix("foo.bar[3].baz", "foo.bar") // → true
|
|
50
|
+
* isPrefix("foo.bar[3].baz", "foo.baz") // → false
|
|
51
|
+
* isPrefix("foo", "foo.bar") // → false
|
|
52
|
+
* ```
|
|
31
53
|
*/
|
|
32
54
|
export declare function isPrefix(name: string, prefix: string): boolean;
|
|
33
55
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Check if the value is a plain object
|
|
48
|
-
*/
|
|
49
|
-
export declare function isPlainObject(obj: unknown): obj is Record<string | number | symbol, unknown>;
|
|
50
|
-
type GlobalConstructors = {
|
|
51
|
-
[K in keyof typeof globalThis]: (typeof globalThis)[K] extends new (...args: any) => any ? K : never;
|
|
52
|
-
}[keyof typeof globalThis];
|
|
53
|
-
export declare function isGlobalInstance<ClassName extends GlobalConstructors>(obj: unknown, className: ClassName): obj is InstanceType<(typeof globalThis)[ClassName]>;
|
|
54
|
-
/**
|
|
55
|
-
* Normalize value by removing empty object or array, empty string and null values
|
|
56
|
-
*/
|
|
57
|
-
export declare function normalize<Type extends Record<string, unknown>>(value: Type, acceptFile?: boolean): Type | undefined;
|
|
58
|
-
export declare function normalize<Type extends Array<unknown>>(value: Type, acceptFile?: boolean): Type | undefined;
|
|
59
|
-
export declare function normalize(value: unknown, acceptFile?: boolean): unknown | undefined;
|
|
60
|
-
/**
|
|
61
|
-
* Flatten a tree into a dictionary
|
|
56
|
+
* Return the segments of `fullPathStr` that come after the `baseSegments` prefix.
|
|
57
|
+
*
|
|
58
|
+
* @param fullPathStr Full path as a dot/bracket string
|
|
59
|
+
* @param basePath Base path, already parsed into segments
|
|
60
|
+
* @returns The “tail” segments, or `null` if `fullPathStr` isn’t nested under `baseSegments`
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```js
|
|
64
|
+
* getRelativePath("foo.bar[0].qux", ["foo","bar"]) // → [0, "qux"]
|
|
65
|
+
* getRelativePath("a.b.c.d", ["a","b"]) // → ["c","d"]
|
|
66
|
+
* getRelativePath("foo", ["foo","bar"]) // → null
|
|
67
|
+
* ```
|
|
62
68
|
*/
|
|
63
|
-
export declare function
|
|
64
|
-
resolve?: (data: unknown) => unknown;
|
|
65
|
-
prefix?: string;
|
|
66
|
-
}): Record<string, unknown>;
|
|
67
|
-
export declare function deepEqual(left: unknown, right: unknown): boolean;
|
|
68
|
-
export type JsonPrimitive = string | number | boolean | null;
|
|
69
|
+
export declare function getRelativePath(name: string, basePath: Array<string | number>): Array<string | number> | null;
|
|
69
70
|
/**
|
|
70
|
-
*
|
|
71
|
-
* It may contains JSON primitives if the value is updated based on a form intent.
|
|
71
|
+
* Assign a value to a target object by following the path segments.
|
|
72
72
|
*/
|
|
73
|
-
export
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
export declare function setValueAtPath<T extends Record<string, any>>(target: T, pathOrSegments: string | Array<string | number>, valueOrFn: unknown | ((current: unknown) => unknown), options?: {
|
|
74
|
+
clone?: boolean;
|
|
75
|
+
silent?: boolean;
|
|
76
|
+
}): T;
|
|
76
77
|
/**
|
|
77
|
-
*
|
|
78
|
+
* Retrive the value from a target object by following the path segments.
|
|
78
79
|
*/
|
|
79
|
-
export
|
|
80
|
-
/**
|
|
81
|
-
* The form value structured following the naming convention.
|
|
82
|
-
*/
|
|
83
|
-
value: Record<string, FormValue<ValueType>>;
|
|
84
|
-
/**
|
|
85
|
-
* The field names that are included in the FormData or URLSearchParams.
|
|
86
|
-
*/
|
|
87
|
-
fields: string[];
|
|
88
|
-
/**
|
|
89
|
-
* The intent of the submission. This is usally included by specifying a name and value on a submit button.
|
|
90
|
-
*/
|
|
91
|
-
intent: string | null;
|
|
92
|
-
};
|
|
80
|
+
export declare function getValueAtPath(target: unknown, pathOrSegments: string | Array<string | number>): unknown;
|
|
93
81
|
/**
|
|
94
82
|
* Parse `FormData` or `URLSearchParams` into a submission object.
|
|
95
83
|
* This function structures the form values based on the naming convention.
|
|
96
|
-
* It also includes all the field names and the intent
|
|
84
|
+
* It also includes all the field names and extracts the intent from the submission.
|
|
97
85
|
*
|
|
86
|
+
* @see https://conform.guide/api/react/future/parseSubmission
|
|
98
87
|
* @example
|
|
99
88
|
* ```ts
|
|
100
89
|
* const formData = new FormData();
|
|
@@ -104,7 +93,7 @@ export type Submission<ValueType extends FormDataEntryValue = FormDataEntryValue
|
|
|
104
93
|
*
|
|
105
94
|
* parseSubmission(formData)
|
|
106
95
|
* // {
|
|
107
|
-
* //
|
|
96
|
+
* // payload: { email: 'test@example.com', password: 'secret' },
|
|
108
97
|
* // fields: ['email', 'password'],
|
|
109
98
|
* // intent: null,
|
|
110
99
|
* // }
|
|
@@ -113,7 +102,7 @@ export type Submission<ValueType extends FormDataEntryValue = FormDataEntryValue
|
|
|
113
102
|
* formData.append('intent', 'login');
|
|
114
103
|
* parseSubmission(formData, { intentName: 'intent' })
|
|
115
104
|
* // {
|
|
116
|
-
* //
|
|
105
|
+
* // payload: { email: 'test@example.com', password: 'secret' },
|
|
117
106
|
* // fields: ['email', 'password'],
|
|
118
107
|
* // intent: 'login',
|
|
119
108
|
* // }
|
|
@@ -121,18 +110,61 @@ export type Submission<ValueType extends FormDataEntryValue = FormDataEntryValue
|
|
|
121
110
|
*/
|
|
122
111
|
export declare function parseSubmission(formData: FormData | URLSearchParams, options?: {
|
|
123
112
|
/**
|
|
124
|
-
* The name of the submit button that
|
|
125
|
-
*
|
|
113
|
+
* The name of the submit button field that indicates the submission intent.
|
|
114
|
+
* Defaults to `__INTENT__`.
|
|
126
115
|
*/
|
|
127
116
|
intentName?: string;
|
|
128
117
|
/**
|
|
129
|
-
* A
|
|
118
|
+
* A function to exclude specific form fields from being parsed.
|
|
130
119
|
* Return `true` to skip the entry.
|
|
131
120
|
*/
|
|
132
121
|
skipEntry?: (name: string) => boolean;
|
|
133
122
|
}): Submission;
|
|
134
|
-
|
|
135
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Creates a SubmissionResult object from a submission, adding validation results and intended values.
|
|
125
|
+
* This function will remove all files in the submission payload by default since
|
|
126
|
+
* file inputs cannot be initialized with files.
|
|
127
|
+
* You can specify `keepFiles: true` to keep the files if needed.
|
|
128
|
+
*
|
|
129
|
+
* @see https://conform.guide/api/react/future/report
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* // Report the submission with the field errors
|
|
133
|
+
* report(submission, {
|
|
134
|
+
* error: {
|
|
135
|
+
* fieldErrors: {
|
|
136
|
+
* email: ['Invalid email format'],
|
|
137
|
+
* password: ['Password is required'],
|
|
138
|
+
* },
|
|
139
|
+
* })
|
|
140
|
+
*
|
|
141
|
+
* // Report the submission with a form error
|
|
142
|
+
* report(submission, {
|
|
143
|
+
* error: {
|
|
144
|
+
* formErrors: ['Invalid credentials'],
|
|
145
|
+
* },
|
|
146
|
+
* })
|
|
147
|
+
*
|
|
148
|
+
* // Reset the form
|
|
149
|
+
* report(submission, {
|
|
150
|
+
* reset: true,
|
|
151
|
+
* })
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export declare function report<ErrorShape = string>(submission: Submission, options?: {
|
|
155
|
+
keepFiles?: false;
|
|
156
|
+
error?: Partial<FormError<ErrorShape>> | null;
|
|
157
|
+
intendedValue?: Record<string, FormValue> | null;
|
|
158
|
+
hideFields?: string[];
|
|
159
|
+
reset?: boolean;
|
|
160
|
+
}): SubmissionResult<ErrorShape, Exclude<JsonPrimitive | FormDataEntryValue, File>>;
|
|
161
|
+
export declare function report<ErrorShape = string>(submission: Submission, options: {
|
|
162
|
+
keepFiles: true;
|
|
163
|
+
error?: Partial<FormError<ErrorShape>> | null;
|
|
164
|
+
intendedValue?: Record<string, FormValue> | null;
|
|
165
|
+
hideFields?: string[];
|
|
166
|
+
reset?: boolean;
|
|
167
|
+
}): SubmissionResult<ErrorShape>;
|
|
136
168
|
/**
|
|
137
169
|
* A utility function that checks whether the current form data differs from the default values.
|
|
138
170
|
*
|
|
@@ -160,7 +192,7 @@ export declare function isDirty(
|
|
|
160
192
|
* - A `URLSearchParams` object
|
|
161
193
|
* - A plain object that was parsed from form data (i.e. `submission.payload`)
|
|
162
194
|
*/
|
|
163
|
-
formData: FormData | URLSearchParams | FormValue
|
|
195
|
+
formData: FormData | URLSearchParams | FormValue | null, options?: {
|
|
164
196
|
/**
|
|
165
197
|
* An object representing the default values of the form to compare against.
|
|
166
198
|
* Defaults to an empty object if not provided.
|
|
@@ -185,7 +217,7 @@ formData: FormData | URLSearchParams | FormValue<FormDataEntryValue> | null, opt
|
|
|
185
217
|
* - Date:
|
|
186
218
|
* - Converted to ISO string using `.toISOString()`
|
|
187
219
|
*/
|
|
188
|
-
serialize?: (value: unknown, defaultSerialize:
|
|
220
|
+
serialize?: (value: unknown, defaultSerialize: Serialize) => SerializedValue | undefined;
|
|
189
221
|
/**
|
|
190
222
|
* A function to exclude specific fields from the comparison.
|
|
191
223
|
* Useful for ignoring hidden inputs like CSRF tokens or internal fields added by frameworks
|
|
@@ -200,5 +232,20 @@ formData: FormData | URLSearchParams | FormValue<FormDataEntryValue> | null, opt
|
|
|
200
232
|
*/
|
|
201
233
|
skipEntry?: (name: string) => boolean;
|
|
202
234
|
}): boolean | undefined;
|
|
203
|
-
|
|
235
|
+
/**
|
|
236
|
+
* Convert an unknown value into something acceptable for HTML form submission.
|
|
237
|
+
* Returns `undefined` when the value cannot be represented in form data.
|
|
238
|
+
*
|
|
239
|
+
* Input -> Output:
|
|
240
|
+
* - string -> string
|
|
241
|
+
* - null -> '' (empty string)
|
|
242
|
+
* - boolean -> 'on' | '' (checked semantics)
|
|
243
|
+
* - number | bigint -> value.toString()
|
|
244
|
+
* - Date -> value.toISOString()
|
|
245
|
+
* - File -> File
|
|
246
|
+
* - FileList -> File[]
|
|
247
|
+
* - Array -> string[] or File[] if all items serialize to the same kind; otherwise undefined
|
|
248
|
+
* - anything else -> undefined
|
|
249
|
+
*/
|
|
250
|
+
export declare function serialize(value: unknown): SerializedValue | undefined;
|
|
204
251
|
//# sourceMappingURL=formdata.d.ts.map
|