remix-validated-form 4.1.4 → 4.1.5

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.
Files changed (52) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/browser/ValidatedForm.js +31 -36
  3. package/browser/hooks.js +13 -16
  4. package/browser/internal/customState.d.ts +105 -0
  5. package/browser/internal/customState.js +46 -0
  6. package/browser/internal/getInputProps.js +4 -14
  7. package/browser/internal/hooks.d.ts +14 -15
  8. package/browser/internal/hooks.js +36 -38
  9. package/browser/internal/logic/elementUtils.d.ts +3 -0
  10. package/browser/internal/logic/elementUtils.js +3 -0
  11. package/browser/internal/logic/setInputValueInForm.js +9 -52
  12. package/browser/internal/setFieldValue.d.ts +0 -0
  13. package/browser/internal/setFieldValue.js +0 -0
  14. package/browser/internal/setFormValues.d.ts +0 -0
  15. package/browser/internal/setFormValues.js +0 -0
  16. package/browser/internal/state.d.ts +339 -238
  17. package/browser/internal/state.js +59 -72
  18. package/browser/internal/watch.d.ts +18 -0
  19. package/browser/internal/watch.js +122 -0
  20. package/browser/unreleased/formStateHooks.d.ts +39 -0
  21. package/browser/unreleased/formStateHooks.js +54 -0
  22. package/browser/userFacingFormContext.js +9 -23
  23. package/build/ValidatedForm.js +30 -35
  24. package/build/hooks.js +11 -14
  25. package/build/internal/getInputProps.js +4 -14
  26. package/build/internal/hooks.d.ts +14 -15
  27. package/build/internal/hooks.js +38 -40
  28. package/build/internal/logic/elementUtils.d.ts +3 -0
  29. package/build/internal/logic/elementUtils.js +9 -0
  30. package/build/internal/logic/setInputValueInForm.js +12 -55
  31. package/build/internal/setFormValues.d.ts +0 -0
  32. package/build/internal/setFormValues.js +0 -0
  33. package/build/internal/state/controlledFields.js +11 -2
  34. package/build/internal/state.d.ts +339 -238
  35. package/build/internal/state.js +61 -77
  36. package/build/internal/watch.d.ts +20 -0
  37. package/build/internal/watch.js +126 -0
  38. package/build/unreleased/formStateHooks.d.ts +39 -0
  39. package/build/unreleased/formStateHooks.js +59 -0
  40. package/build/userFacingFormContext.js +9 -23
  41. package/package.json +1 -2
  42. package/src/ValidatedForm.tsx +48 -52
  43. package/src/hooks.ts +15 -26
  44. package/src/internal/getInputProps.ts +4 -14
  45. package/src/internal/hooks.ts +59 -71
  46. package/src/internal/hydratable.ts +28 -0
  47. package/src/internal/logic/getCheckboxChecked.ts +10 -0
  48. package/src/internal/logic/getRadioChecked.ts +7 -0
  49. package/src/internal/state/atomUtils.ts +13 -0
  50. package/src/internal/state.ts +99 -177
  51. package/src/unreleased/formStateHooks.ts +113 -0
  52. 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[0])) {
19
- this.values.shift();
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