remix-validated-form 4.1.4-beta.0 → 4.1.6
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/.turbo/turbo-build.log +2 -2
- package/browser/ValidatedForm.js +31 -36
- package/browser/hooks.js +13 -16
- package/browser/internal/customState.d.ts +105 -0
- package/browser/internal/customState.js +46 -0
- package/browser/internal/getInputProps.js +4 -14
- package/browser/internal/hooks.d.ts +14 -15
- package/browser/internal/hooks.js +37 -39
- package/browser/internal/logic/elementUtils.d.ts +3 -0
- package/browser/internal/logic/elementUtils.js +3 -0
- package/browser/internal/logic/setInputValueInForm.js +9 -52
- package/browser/internal/setFieldValue.d.ts +0 -0
- package/browser/internal/setFieldValue.js +0 -0
- package/browser/internal/setFormValues.d.ts +0 -0
- package/browser/internal/setFormValues.js +0 -0
- package/browser/internal/state.d.ts +339 -238
- package/browser/internal/state.js +59 -72
- package/browser/internal/watch.d.ts +18 -0
- package/browser/internal/watch.js +122 -0
- package/browser/unreleased/formStateHooks.d.ts +39 -0
- package/browser/unreleased/formStateHooks.js +54 -0
- package/browser/userFacingFormContext.js +9 -23
- package/build/ValidatedForm.js +30 -35
- package/build/hooks.js +11 -14
- package/build/internal/getInputProps.js +4 -14
- package/build/internal/hooks.d.ts +14 -15
- package/build/internal/hooks.js +39 -41
- package/build/internal/logic/elementUtils.d.ts +3 -0
- package/build/internal/logic/elementUtils.js +9 -0
- package/build/internal/logic/setInputValueInForm.js +12 -55
- package/build/internal/setFormValues.d.ts +0 -0
- package/build/internal/setFormValues.js +0 -0
- package/build/internal/state/controlledFields.js +11 -2
- package/build/internal/state.d.ts +339 -238
- package/build/internal/state.js +61 -77
- package/build/internal/watch.d.ts +20 -0
- package/build/internal/watch.js +126 -0
- package/build/unreleased/formStateHooks.d.ts +39 -0
- package/build/unreleased/formStateHooks.js +59 -0
- package/build/userFacingFormContext.js +9 -23
- package/package.json +1 -2
- package/src/ValidatedForm.tsx +48 -52
- package/src/hooks.ts +15 -26
- package/src/internal/getInputProps.ts +4 -14
- package/src/internal/hooks.ts +60 -72
- package/src/internal/hydratable.ts +28 -0
- package/src/internal/logic/getCheckboxChecked.ts +10 -0
- package/src/internal/logic/getRadioChecked.ts +7 -0
- package/src/internal/state/atomUtils.ts +13 -0
- package/src/internal/state.ts +99 -177
- package/src/unreleased/formStateHooks.ts +113 -0
- package/src/userFacingFormContext.ts +14 -53
@@ -1,22 +1,21 @@
|
|
1
1
|
import invariant from "tiny-invariant";
|
2
|
+
import { isCheckbox, isMultiselect, isRadio } from "./elementUtils";
|
2
3
|
import { getCheckboxChecked } from "./getCheckboxChecked";
|
3
4
|
/**
|
4
5
|
* Helper class to track the values being set on uncontrolled fields.
|
5
6
|
* HTML is super permissive with inputs that all share the same `name`.
|
6
|
-
*
|
7
|
-
* This class is strict in the sense that, if the user provides an array value,
|
8
|
-
* the values inside the array must be in the same order as the elements in the DOM.
|
9
|
-
* Doing this allows us to be flexible with what types of form controls the user is using.
|
10
|
-
*
|
11
|
-
* This is how HTML tracks inputs of the same name as well.
|
12
|
-
* `new FormData(formElement).getAll('myField')` will return values in DOM order.
|
13
7
|
*/
|
14
8
|
class Values {
|
15
9
|
constructor(values) {
|
16
10
|
this.hasSetRadioValue = false;
|
11
|
+
this.remove = (value) => {
|
12
|
+
const index = this.values.indexOf(value);
|
13
|
+
const deleted = this.values.splice(index, 1);
|
14
|
+
return deleted.length > 0;
|
15
|
+
};
|
17
16
|
this.bool = (value) => {
|
18
|
-
if (getCheckboxChecked(value, this.values
|
19
|
-
this.
|
17
|
+
if (getCheckboxChecked(value, this.values)) {
|
18
|
+
this.remove(value) || this.remove(true);
|
20
19
|
return true;
|
21
20
|
}
|
22
21
|
return false;
|
@@ -41,32 +40,6 @@ class Values {
|
|
41
40
|
this.values = unknownValues;
|
42
41
|
}
|
43
42
|
}
|
44
|
-
/**
|
45
|
-
* This subclass is order-permissive, meaning the user doesn't have to worry about
|
46
|
-
* the order in which the inputs occur in the DOM.
|
47
|
-
* This is useful for multiselects and checkbox groups and provides a better DX than
|
48
|
-
* the order-strict version.
|
49
|
-
*/
|
50
|
-
class PermissiveValues extends Values {
|
51
|
-
constructor() {
|
52
|
-
super(...arguments);
|
53
|
-
this.remove = (value) => {
|
54
|
-
const index = this.values.indexOf(value);
|
55
|
-
const deleted = this.values.splice(index, 1);
|
56
|
-
return deleted.length > 0;
|
57
|
-
};
|
58
|
-
this.bool = (value) => {
|
59
|
-
if (getCheckboxChecked(value, this.values)) {
|
60
|
-
this.remove(value) || this.remove(true);
|
61
|
-
return true;
|
62
|
-
}
|
63
|
-
return false;
|
64
|
-
};
|
65
|
-
}
|
66
|
-
}
|
67
|
-
const isMultiselect = (node) => node instanceof HTMLSelectElement && node.multiple;
|
68
|
-
const isCheckbox = (node) => node instanceof HTMLInputElement && node.type === "checkbox";
|
69
|
-
const isRadio = (node) => node instanceof HTMLInputElement && node.type === "radio";
|
70
43
|
const setElementValue = (element, values, field) => {
|
71
44
|
if (isMultiselect(element)) {
|
72
45
|
for (const option of element.options) {
|
@@ -86,34 +59,18 @@ const setElementValue = (element, values, field) => {
|
|
86
59
|
invariant(input.type !== "hidden", `Cannot set value on hidden input if it is not a controlled field. Field being updated was ${field}.`);
|
87
60
|
input.value = values.str();
|
88
61
|
};
|
89
|
-
const areElementsTheSameType = (nodes) => {
|
90
|
-
const getType = (node) => {
|
91
|
-
if (node instanceof HTMLInputElement)
|
92
|
-
return node.type;
|
93
|
-
if (node instanceof HTMLSelectElement)
|
94
|
-
return node.multiple ? "select" : "multiselect";
|
95
|
-
return null;
|
96
|
-
};
|
97
|
-
const firstElementInstance = nodes[0].constructor;
|
98
|
-
const firstElementType = getType(nodes[0]);
|
99
|
-
return nodes.every((element) => element.constructor === firstElementInstance &&
|
100
|
-
getType(element) === firstElementType);
|
101
|
-
};
|
102
62
|
export const setInputValueInForm = (formElement, name, value) => {
|
103
63
|
const controlElement = formElement.elements.namedItem(name);
|
104
64
|
if (!controlElement)
|
105
65
|
return;
|
66
|
+
const values = new Values(value);
|
106
67
|
if (controlElement instanceof RadioNodeList) {
|
107
|
-
const values = areElementsTheSameType([...controlElement])
|
108
|
-
? new PermissiveValues(value)
|
109
|
-
: new Values(value);
|
110
68
|
for (const element of controlElement) {
|
111
69
|
setElementValue(element, values, name);
|
112
70
|
}
|
113
71
|
values.warnIfLeftovers(name);
|
114
72
|
}
|
115
73
|
else {
|
116
|
-
const values = new PermissiveValues(value);
|
117
74
|
setElementValue(controlElement, values, name);
|
118
75
|
values.warnIfLeftovers(name);
|
119
76
|
}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|