@homebound/form-state 2.19.0 → 2.20.1
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/dist/FormStateApp.d.ts +2 -3
- package/dist/FormStateApp.js +8 -47
- package/dist/FormStateApp.test.js +14 -14
- package/dist/config.d.ts +6 -6
- package/dist/fields/fragmentField.js +3 -3
- package/dist/fields/listField.js +12 -12
- package/dist/fields/objectField.d.ts +4 -4
- package/dist/fields/objectField.js +10 -10
- package/dist/fields/valueField.d.ts +13 -0
- package/dist/fields/valueField.js +48 -14
- package/dist/formState.stories.d.ts +2 -4
- package/dist/formState.stories.js +1 -1
- package/dist/formState.test.js +146 -79
- package/dist/formStateDomain.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/proxies.d.ts +5 -0
- package/dist/proxies.js +21 -0
- package/dist/rules.d.ts +1 -1
- package/dist/rules.js +1 -1
- package/dist/setupTests.js +2 -2
- package/dist/useFormState.d.ts +4 -4
- package/dist/useFormState.js +13 -13
- package/dist/useFormState.test.js +141 -169
- package/dist/useFormStates.d.ts +3 -3
- package/dist/useFormStates.js +7 -7
- package/dist/useFormStates.test.js +56 -63
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +8 -8
- package/dist/utils.test.js +49 -49
- package/package.json +44 -40
|
@@ -16,32 +16,31 @@ describe("useFormState", () => {
|
|
|
16
16
|
const config = { firstName: { type: "value" } };
|
|
17
17
|
// And we have query data that may or may not be defined
|
|
18
18
|
const data = { firstName: "bob" };
|
|
19
|
-
const form = useFormState_1.useFormState({
|
|
19
|
+
const form = (0, useFormState_1.useFormState)({
|
|
20
20
|
config,
|
|
21
21
|
// Then the lambda is passed the "de-undefined" data, i.e. `d.firstName` is not a compile error
|
|
22
22
|
init: { input: data, map: (d) => ({ firstName: d.firstName }) },
|
|
23
23
|
});
|
|
24
|
-
return jsx_runtime_1.jsx("div", { children: form.firstName.value }
|
|
24
|
+
return (0, jsx_runtime_1.jsx)("div", { children: form.firstName.value });
|
|
25
25
|
}
|
|
26
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
26
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
27
27
|
expect(r.baseElement).toHaveTextContent("bob");
|
|
28
28
|
});
|
|
29
29
|
it("memoizes on init.input being an array", async () => {
|
|
30
30
|
const config = { firstName: { type: "value" } };
|
|
31
31
|
function TestComponent() {
|
|
32
|
-
const [, setTick] = react_2.useState(0);
|
|
33
|
-
const form = useFormState_1.useFormState({
|
|
32
|
+
const [, setTick] = (0, react_2.useState)(0);
|
|
33
|
+
const form = (0, useFormState_1.useFormState)({
|
|
34
34
|
config,
|
|
35
35
|
init: { input: ["a", "b"], map: ([a, b]) => ({ firstName: a + b }) },
|
|
36
36
|
});
|
|
37
37
|
const onClick = () => [form.firstName.set("fred"), setTick(1)];
|
|
38
|
-
return (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("button", { "data-testid": "change", onClick: onClick },
|
|
39
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0)] }, void 0));
|
|
38
|
+
return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("button", { "data-testid": "change", onClick: onClick }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value })] }));
|
|
40
39
|
}
|
|
41
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
42
|
-
expect(r.firstName
|
|
43
|
-
rtl_utils_1.click(r.change);
|
|
44
|
-
expect(r.firstName
|
|
40
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
41
|
+
expect(r.firstName).toHaveTextContent("ab");
|
|
42
|
+
(0, rtl_utils_1.click)(r.change);
|
|
43
|
+
expect(r.firstName).toHaveTextContent("fred");
|
|
45
44
|
});
|
|
46
45
|
it("uses default if init.input is undefined", async () => {
|
|
47
46
|
// Given a component
|
|
@@ -49,13 +48,13 @@ describe("useFormState", () => {
|
|
|
49
48
|
const config = { firstName: { type: "value" } };
|
|
50
49
|
// And we have query data that may or may not be defined (but is actually undefined)
|
|
51
50
|
const data = Math.random() >= 0 ? undefined : { firstName: "bob" };
|
|
52
|
-
const form = useFormState_1.useFormState({
|
|
51
|
+
const form = (0, useFormState_1.useFormState)({
|
|
53
52
|
config,
|
|
54
53
|
init: { input: data, map: (d) => ({ firstName: d.firstName }) },
|
|
55
54
|
});
|
|
56
|
-
return jsx_runtime_1.jsx("div", { children: form.firstName.value }
|
|
55
|
+
return (0, jsx_runtime_1.jsx)("div", { children: form.firstName.value });
|
|
57
56
|
}
|
|
58
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
57
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
59
58
|
// Then we init.map wasn't called, and we used {} instead
|
|
60
59
|
expect(r.baseElement.textContent).toEqual("");
|
|
61
60
|
});
|
|
@@ -68,7 +67,7 @@ describe("useFormState", () => {
|
|
|
68
67
|
};
|
|
69
68
|
// And we have query data that may or may not be defined (but is actually undefined)
|
|
70
69
|
const data = Math.random() >= 0 ? undefined : { firstName: "bob" };
|
|
71
|
-
const form = useFormState_1.useFormState({
|
|
70
|
+
const form = (0, useFormState_1.useFormState)({
|
|
72
71
|
config,
|
|
73
72
|
// And we pass `ifUndefined`
|
|
74
73
|
init: {
|
|
@@ -77,10 +76,9 @@ describe("useFormState", () => {
|
|
|
77
76
|
ifUndefined: { firstName: "default" },
|
|
78
77
|
},
|
|
79
78
|
});
|
|
80
|
-
return (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div",
|
|
81
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "changedValue" }, { children: JSON.stringify(form.changedValue) }), void 0)] }, void 0));
|
|
79
|
+
return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "changedValue", children: JSON.stringify(form.changedValue) })] }));
|
|
82
80
|
}
|
|
83
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
81
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
84
82
|
// Then we use the ifUndefined value
|
|
85
83
|
expect(r.firstName.textContent).toEqual("default");
|
|
86
84
|
expect(r.changedValue.textContent).toEqual(JSON.stringify({ firstName: "default" }));
|
|
@@ -88,33 +86,32 @@ describe("useFormState", () => {
|
|
|
88
86
|
it("uses init if set as a value", async () => {
|
|
89
87
|
const config = { firstName: { type: "value" } };
|
|
90
88
|
function TestComponent() {
|
|
91
|
-
const [, setTick] = react_2.useState(0);
|
|
92
|
-
const form = useFormState_1.useFormState({
|
|
89
|
+
const [, setTick] = (0, react_2.useState)(0);
|
|
90
|
+
const form = (0, useFormState_1.useFormState)({
|
|
93
91
|
config,
|
|
94
92
|
// That's using a raw init value
|
|
95
93
|
init: { firstName: "bob" },
|
|
96
94
|
});
|
|
97
|
-
return (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("button", { "data-testid": "change", onClick: () => {
|
|
95
|
+
return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("button", { "data-testid": "change", onClick: () => {
|
|
98
96
|
// When that value changes
|
|
99
97
|
form.firstName.set("fred");
|
|
100
98
|
// And also we re-render the component
|
|
101
99
|
setTick(1);
|
|
102
|
-
} },
|
|
103
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0)] }, void 0));
|
|
100
|
+
} }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value })] }));
|
|
104
101
|
}
|
|
105
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
106
|
-
expect(r.firstName
|
|
107
|
-
rtl_utils_1.click(r.change);
|
|
102
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
103
|
+
expect(r.firstName).toHaveTextContent("bob");
|
|
104
|
+
(0, rtl_utils_1.click)(r.change);
|
|
108
105
|
// Then the change didn't get dropped due to init being unstable
|
|
109
|
-
expect(r.firstName
|
|
106
|
+
expect(r.firstName).toHaveTextContent("fred");
|
|
110
107
|
});
|
|
111
108
|
it("doesn't required an init value", async () => {
|
|
112
109
|
function TestComponent() {
|
|
113
110
|
const config = { firstName: { type: "value" } };
|
|
114
|
-
const form = useFormState_1.useFormState({ config });
|
|
115
|
-
return jsx_runtime_1.jsx("div", { children: form.firstName.value }
|
|
111
|
+
const form = (0, useFormState_1.useFormState)({ config });
|
|
112
|
+
return (0, jsx_runtime_1.jsx)("div", { children: form.firstName.value });
|
|
116
113
|
}
|
|
117
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
114
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
118
115
|
expect(r.baseElement.textContent).toEqual("");
|
|
119
116
|
});
|
|
120
117
|
it("keeps local changed values when a query refreshes", async () => {
|
|
@@ -156,63 +153,53 @@ describe("useFormState", () => {
|
|
|
156
153
|
],
|
|
157
154
|
};
|
|
158
155
|
// And we start out with data1
|
|
159
|
-
const [data, setData] = react_2.useState(data1);
|
|
160
|
-
const form = useFormState_1.useFormState({ config, init: { input: data, map: (d) => d } });
|
|
156
|
+
const [data, setData] = (0, react_2.useState)(data1);
|
|
157
|
+
const form = (0, useFormState_1.useFormState)({ config, init: { input: data, map: (d) => d } });
|
|
161
158
|
function makeLocalChanges() {
|
|
162
159
|
form.firstName.value = "local";
|
|
163
160
|
form.address.street.value = "local";
|
|
164
161
|
form.books.rows[0].title.value = "local";
|
|
165
162
|
}
|
|
166
|
-
return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div",
|
|
167
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "lastName" }, { children: form.lastName.value }), void 0),
|
|
168
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "street" }, { children: form.address.street.value }), void 0),
|
|
169
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "city" }, { children: form.address.city.value }), void 0),
|
|
170
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "title1" }, { children: form.books.rows[0].title.value }), void 0),
|
|
171
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "title2" }, { children: form.books.rows[1].title.value }), void 0),
|
|
172
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "booksLength" }, { children: form.books.rows.length }), void 0),
|
|
173
|
-
jsx_runtime_1.jsx("button", { "data-testid": "makeLocalChanges", onClick: makeLocalChanges }, void 0),
|
|
174
|
-
jsx_runtime_1.jsx("button", { "data-testid": "refreshData", onClick: () => setData(data2) }, void 0),
|
|
175
|
-
jsx_runtime_1.jsx("button", { "data-testid": "saveData", onClick: () => setData(data3) }, void 0),
|
|
176
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "changedValue" }, { children: JSON.stringify(form.changedValue) }), void 0)] }, void 0)) }, void 0));
|
|
163
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "lastName", children: form.lastName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "street", children: form.address.street.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "city", children: form.address.city.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "title1", children: form.books.rows[0].title.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "title2", children: form.books.rows[1].title.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "booksLength", children: form.books.rows.length }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "makeLocalChanges", onClick: makeLocalChanges }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "refreshData", onClick: () => setData(data2) }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "saveData", onClick: () => setData(data3) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "changedValue", children: JSON.stringify(form.changedValue) })] })) }));
|
|
177
164
|
}
|
|
178
165
|
// And we start out with the initial query data
|
|
179
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
180
|
-
expect(r.firstName
|
|
181
|
-
expect(r.street
|
|
182
|
-
expect(r.title1
|
|
166
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
167
|
+
expect(r.firstName.textContent).toEqual("f1");
|
|
168
|
+
expect(r.street.textContent).toEqual("s1");
|
|
169
|
+
expect(r.title1.textContent).toEqual("a1");
|
|
183
170
|
// When we make some local changes
|
|
184
|
-
rtl_utils_1.click(r.makeLocalChanges);
|
|
171
|
+
(0, rtl_utils_1.click)(r.makeLocalChanges);
|
|
185
172
|
// Then we see them
|
|
186
|
-
expect(r.firstName
|
|
187
|
-
expect(r.street
|
|
188
|
-
expect(r.title1
|
|
189
|
-
expect(JSON.parse(r.changedValue
|
|
173
|
+
expect(r.firstName.textContent).toEqual("local");
|
|
174
|
+
expect(r.street.textContent).toEqual("local");
|
|
175
|
+
expect(r.title1.textContent).toEqual("local");
|
|
176
|
+
expect(JSON.parse(r.changedValue.textContent)).toEqual({
|
|
190
177
|
id: "a:1",
|
|
191
178
|
address: { id: "address:1", street: "local" },
|
|
192
179
|
books: [{ id: "b:1", title: "local" }, { id: "b:2" }],
|
|
193
180
|
firstName: "local",
|
|
194
181
|
});
|
|
195
182
|
// And when the new query is ran i.e. due to a cache refresh
|
|
196
|
-
rtl_utils_1.click(r.refreshData);
|
|
183
|
+
(0, rtl_utils_1.click)(r.refreshData);
|
|
197
184
|
// Then we kept our local changes
|
|
198
|
-
expect(r.firstName
|
|
199
|
-
expect(r.street
|
|
200
|
-
expect(r.title1
|
|
185
|
+
expect(r.firstName.textContent).toEqual("local");
|
|
186
|
+
expect(r.street.textContent).toEqual("local");
|
|
187
|
+
expect(r.title1.textContent).toEqual("local");
|
|
201
188
|
// But we also see the new data for fields we have not changed
|
|
202
|
-
expect(r.lastName
|
|
203
|
-
expect(r.city
|
|
204
|
-
expect(r.title2
|
|
205
|
-
expect(r.booksLength
|
|
206
|
-
expect(JSON.parse(r.changedValue
|
|
189
|
+
expect(r.lastName.textContent).toEqual("l2");
|
|
190
|
+
expect(r.city.textContent).toEqual("c2");
|
|
191
|
+
expect(r.title2.textContent).toEqual("b2");
|
|
192
|
+
expect(r.booksLength.textContent).toEqual("3");
|
|
193
|
+
expect(JSON.parse(r.changedValue.textContent)).toEqual({
|
|
207
194
|
id: "a:1",
|
|
208
195
|
address: { id: "address:1", street: "local" },
|
|
209
196
|
books: [{ id: "b:1", title: "local" }, { id: "b:2" }, { id: "b:3" }],
|
|
210
197
|
firstName: "local",
|
|
211
198
|
});
|
|
212
199
|
// And then when our mutation results come back
|
|
213
|
-
rtl_utils_1.click(r.saveData);
|
|
200
|
+
(0, rtl_utils_1.click)(r.saveData);
|
|
214
201
|
// Then changedValue doesn't show our local changes anymore
|
|
215
|
-
expect(JSON.parse(r.changedValue
|
|
202
|
+
expect(JSON.parse(r.changedValue.textContent)).toEqual({
|
|
216
203
|
id: "a:1",
|
|
217
204
|
});
|
|
218
205
|
});
|
|
@@ -232,29 +219,26 @@ describe("useFormState", () => {
|
|
|
232
219
|
books: [{ title: "a2" }],
|
|
233
220
|
};
|
|
234
221
|
// And we start out with data1
|
|
235
|
-
const [data, setData] = react_2.useState(data1);
|
|
236
|
-
const form = useFormState_1.useFormState({
|
|
222
|
+
const [data, setData] = (0, react_2.useState)(data1);
|
|
223
|
+
const form = (0, useFormState_1.useFormState)({
|
|
237
224
|
config,
|
|
238
225
|
init: { input: data, map: (d) => d },
|
|
239
226
|
// And the form is read only
|
|
240
227
|
readOnly: true,
|
|
241
228
|
});
|
|
242
|
-
return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div",
|
|
243
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "street" }, { children: form.address.street.value }), void 0),
|
|
244
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "title1" }, { children: form.books.rows[0].title.value }), void 0),
|
|
245
|
-
jsx_runtime_1.jsx("button", { "data-testid": "refreshData", onClick: () => setData(data2) }, void 0)] }, void 0)) }, void 0));
|
|
229
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "street", children: form.address.street.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "title1", children: form.books.rows[0].title.value }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "refreshData", onClick: () => setData(data2) })] })) }));
|
|
246
230
|
}
|
|
247
231
|
// And we start out with the initial query data
|
|
248
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
249
|
-
expect(r.firstName
|
|
250
|
-
expect(r.street
|
|
251
|
-
expect(r.title1
|
|
232
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
233
|
+
expect(r.firstName.textContent).toEqual("f1");
|
|
234
|
+
expect(r.street.textContent).toEqual("s1");
|
|
235
|
+
expect(r.title1.textContent).toEqual("a1");
|
|
252
236
|
// When the new query is ran i.e. due to a cache refresh
|
|
253
|
-
rtl_utils_1.click(r.refreshData);
|
|
237
|
+
(0, rtl_utils_1.click)(r.refreshData);
|
|
254
238
|
// Then we see the latest data
|
|
255
|
-
expect(r.firstName
|
|
256
|
-
expect(r.street
|
|
257
|
-
expect(r.title1
|
|
239
|
+
expect(r.firstName.textContent).toEqual("f2");
|
|
240
|
+
expect(r.street.textContent).toEqual("s2");
|
|
241
|
+
expect(r.title1.textContent).toEqual("a2");
|
|
258
242
|
});
|
|
259
243
|
it("useFormState can accept new data with computed fields", async () => {
|
|
260
244
|
// Given a component
|
|
@@ -273,59 +257,54 @@ describe("useFormState", () => {
|
|
|
273
257
|
const data1 = { firstName: "f1", lastName: "l1" };
|
|
274
258
|
const data2 = { firstName: "f2", lastName: "l2" };
|
|
275
259
|
// And we start out with data1
|
|
276
|
-
const [data, setData] = react_2.useState(data1);
|
|
277
|
-
const author = react_2.useMemo(() => new AuthorRow(data.firstName, data.lastName), [data]);
|
|
278
|
-
const config = react_2.useMemo(() => ({
|
|
260
|
+
const [data, setData] = (0, react_2.useState)(data1);
|
|
261
|
+
const author = (0, react_2.useMemo)(() => new AuthorRow(data.firstName, data.lastName), [data]);
|
|
262
|
+
const config = (0, react_2.useMemo)(() => ({
|
|
279
263
|
firstName: { type: "value" },
|
|
280
264
|
lastName: { type: "value" },
|
|
281
265
|
fullName: { type: "value", computed: true },
|
|
282
266
|
}), []);
|
|
283
|
-
const form = useFormState_1.useFormState({ config, init: { input: author, map: (a) => a } });
|
|
284
|
-
return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div",
|
|
285
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "fullName" }, { children: form.fullName.value }), void 0),
|
|
286
|
-
jsx_runtime_1.jsx("button", { "data-testid": "refreshData", onClick: () => setData(data2) }, void 0)] }, void 0)) }, void 0));
|
|
267
|
+
const form = (0, useFormState_1.useFormState)({ config, init: { input: author, map: (a) => a } });
|
|
268
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "fullName", children: form.fullName.value }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "refreshData", onClick: () => setData(data2) })] })) }));
|
|
287
269
|
}
|
|
288
270
|
// And we start out with the initial query data
|
|
289
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
290
|
-
expect(r.firstName
|
|
291
|
-
expect(r.fullName
|
|
271
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
272
|
+
expect(r.firstName.textContent).toEqual("f1");
|
|
273
|
+
expect(r.fullName.textContent).toEqual("f1 l1");
|
|
292
274
|
// When the new query is ran i.e. due to a cache refresh
|
|
293
|
-
rtl_utils_1.click(r.refreshData);
|
|
294
|
-
expect(r.firstName
|
|
295
|
-
expect(r.fullName
|
|
275
|
+
(0, rtl_utils_1.click)(r.refreshData);
|
|
276
|
+
expect(r.firstName.textContent).toEqual("f2");
|
|
277
|
+
expect(r.fullName.textContent).toEqual("f2 l2");
|
|
296
278
|
});
|
|
297
279
|
it("can trigger auto save for fields in list that were initially undefined", async () => {
|
|
298
280
|
const autoSave = jest.fn();
|
|
299
281
|
// Given a component
|
|
300
282
|
function TestComponent() {
|
|
301
283
|
// When the data is initially undefined
|
|
302
|
-
const [data, setData] = react_2.useState();
|
|
284
|
+
const [data, setData] = (0, react_2.useState)();
|
|
303
285
|
const data2 = { books: [{ title: "Title 1" }] };
|
|
304
|
-
const form = useFormState_1.useFormState({
|
|
286
|
+
const form = (0, useFormState_1.useFormState)({
|
|
305
287
|
config: authorWithBooksConfig,
|
|
306
288
|
init: { input: data, map: (d) => d, ifUndefined: { books: [] } },
|
|
307
289
|
autoSave,
|
|
308
290
|
});
|
|
309
|
-
return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("button", { "data-testid": "refreshData", onClick: () => setData(data2) },
|
|
310
|
-
jsx_runtime_1.jsx("button", { "data-testid": "add", onClick: () => form.books.add({ title: "New Book" }) }, void 0),
|
|
311
|
-
jsx_runtime_1.jsx("button", { "data-testid": "blurBookOne", onClick: () => focusAndBlur(form.books.rows[0].title) }, void 0),
|
|
312
|
-
jsx_runtime_1.jsx("button", { "data-testid": "blurBookTwo", onClick: () => focusAndBlur(form.books.rows[1].title) }, void 0)] }, void 0)) }, void 0));
|
|
291
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("button", { "data-testid": "refreshData", onClick: () => setData(data2) }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "add", onClick: () => form.books.add({ title: "New Book" }) }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "blurBookOne", onClick: () => focusAndBlur(form.books.rows[0].title) }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "blurBookTwo", onClick: () => focusAndBlur(form.books.rows[1].title) })] })) }));
|
|
313
292
|
}
|
|
314
293
|
// Given a formState with `onBlur` set
|
|
315
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
294
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
316
295
|
// When the data/child is now available
|
|
317
|
-
rtl_utils_1.click(r.refreshData);
|
|
296
|
+
(0, rtl_utils_1.click)(r.refreshData);
|
|
318
297
|
// And the field is blurred
|
|
319
|
-
await rtl_utils_1.clickAndWait(r.blurBookOne);
|
|
298
|
+
await (0, rtl_utils_1.clickAndWait)(r.blurBookOne);
|
|
320
299
|
// Then we don't auto-save because nothing has changed
|
|
321
300
|
expect(autoSave).toBeCalledTimes(0);
|
|
322
301
|
// And when adding a new book
|
|
323
|
-
await rtl_utils_1.clickAndWait(r.add);
|
|
302
|
+
await (0, rtl_utils_1.clickAndWait)(r.add);
|
|
324
303
|
// We autoSave the new row right away (because we don't have any validation rules
|
|
325
304
|
// that say the new row can't be empty)
|
|
326
305
|
expect(autoSave).toBeCalledTimes(1);
|
|
327
306
|
// And the new book is blurred
|
|
328
|
-
await rtl_utils_1.clickAndWait(r.blurBookTwo);
|
|
307
|
+
await (0, rtl_utils_1.clickAndWait)(r.blurBookTwo);
|
|
329
308
|
// Then we auto save again
|
|
330
309
|
expect(autoSave).toBeCalledTimes(2);
|
|
331
310
|
});
|
|
@@ -335,7 +314,7 @@ describe("useFormState", () => {
|
|
|
335
314
|
function TestComponent() {
|
|
336
315
|
const config = authorConfig;
|
|
337
316
|
const data = { firstName: "f1", lastName: "f1" };
|
|
338
|
-
const form = useFormState_1.useFormState({
|
|
317
|
+
const form = (0, useFormState_1.useFormState)({
|
|
339
318
|
config,
|
|
340
319
|
init: data,
|
|
341
320
|
// And there is reactive business logic in the `autoSave` method
|
|
@@ -344,11 +323,11 @@ describe("useFormState", () => {
|
|
|
344
323
|
autoSaves++;
|
|
345
324
|
},
|
|
346
325
|
});
|
|
347
|
-
return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx("button", { "data-testid": "setFirst", onClick: () => form.firstName.set("f2") }
|
|
326
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("button", { "data-testid": "setFirst", onClick: () => form.firstName.set("f2") }) }));
|
|
348
327
|
}
|
|
349
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
328
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
350
329
|
// When we change firstName
|
|
351
|
-
await rtl_utils_1.clickAndWait(r.setFirst);
|
|
330
|
+
await (0, rtl_utils_1.clickAndWait)(r.setFirst);
|
|
352
331
|
// When autoSave didn't infinite loop
|
|
353
332
|
expect(autoSaves).toEqual(1);
|
|
354
333
|
});
|
|
@@ -358,20 +337,20 @@ describe("useFormState", () => {
|
|
|
358
337
|
function TestComponent() {
|
|
359
338
|
const config = authorConfig;
|
|
360
339
|
const data = { firstName: "f1", lastName: "f1" };
|
|
361
|
-
const form = useFormState_1.useFormState({
|
|
340
|
+
const form = (0, useFormState_1.useFormState)({
|
|
362
341
|
config,
|
|
363
342
|
init: data,
|
|
364
343
|
autoSave: (form) => autoSave(form.changedValue),
|
|
365
344
|
});
|
|
366
|
-
return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx("button", { "data-testid": "set", onClick: () => {
|
|
345
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("button", { "data-testid": "set", onClick: () => {
|
|
367
346
|
// And it sets two fields in a single callback
|
|
368
347
|
form.firstName.set("f2");
|
|
369
348
|
form.lastName.set("l2");
|
|
370
|
-
} }
|
|
349
|
+
} }) }));
|
|
371
350
|
}
|
|
372
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
351
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
373
352
|
// When we change both
|
|
374
|
-
await rtl_utils_1.clickAndWait(r.set);
|
|
353
|
+
await (0, rtl_utils_1.clickAndWait)(r.set);
|
|
375
354
|
// Then we only call autoSave once
|
|
376
355
|
expect(autoSave).toBeCalledTimes(1);
|
|
377
356
|
expect(autoSave).toBeCalledWith({ firstName: "f2", lastName: "l2" });
|
|
@@ -385,8 +364,8 @@ describe("useFormState", () => {
|
|
|
385
364
|
};
|
|
386
365
|
// Given a component using `getObjectState` for lazily creating ObjectStates
|
|
387
366
|
function TestComponent() {
|
|
388
|
-
const [apiData, setApiData] = react_2.useState({ id: "a:1", firstName: "Brandon", lastName: "Dow" });
|
|
389
|
-
const state = useFormState_1.useFormState({ config, autoSave, init: { input: apiData, map: (v) => v } });
|
|
367
|
+
const [apiData, setApiData] = (0, react_2.useState)({ id: "a:1", firstName: "Brandon", lastName: "Dow" });
|
|
368
|
+
const state = (0, useFormState_1.useFormState)({ config, autoSave, init: { input: apiData, map: (v) => v } });
|
|
390
369
|
async function autoSave(form) {
|
|
391
370
|
autoSaveStub(form.changedValue);
|
|
392
371
|
const changed = form.changedValue;
|
|
@@ -394,34 +373,32 @@ describe("useFormState", () => {
|
|
|
394
373
|
await Promise.resolve(1);
|
|
395
374
|
setApiData((prevState) => ({ ...prevState, ...changed }));
|
|
396
375
|
}
|
|
397
|
-
return (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsxs("div",
|
|
398
|
-
jsx_runtime_1.jsx("button", { "data-testid": "focusSetAndSaveField", onClick: () => {
|
|
376
|
+
return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { "data-testid": "name", children: [apiData.firstName, " ", apiData.lastName] }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "focusSetAndSaveField", onClick: () => {
|
|
399
377
|
state.firstName.focus();
|
|
400
378
|
state.firstName.set("Foo");
|
|
401
379
|
state.firstName.maybeAutoSave();
|
|
402
380
|
state.firstName.blur();
|
|
403
|
-
} },
|
|
404
|
-
jsx_runtime_1.jsx("button", { "data-testid": "focusSetAndSaveFieldLastName", onClick: () => {
|
|
381
|
+
} }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "focusSetAndSaveFieldLastName", onClick: () => {
|
|
405
382
|
state.lastName.focus();
|
|
406
383
|
state.lastName.set("Bar");
|
|
407
384
|
state.lastName.maybeAutoSave();
|
|
408
|
-
} }
|
|
385
|
+
} })] }));
|
|
409
386
|
}
|
|
410
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
387
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
411
388
|
// And triggering the auto save behavior before awaiting the initial promise to
|
|
412
389
|
// resolve so we have pending changes.
|
|
413
|
-
rtl_utils_1.click(r.focusSetAndSaveField
|
|
390
|
+
(0, rtl_utils_1.click)(r.focusSetAndSaveField, { allowAsync: true });
|
|
414
391
|
// Let the initial autoSave be called
|
|
415
|
-
react_1.act(() => {
|
|
392
|
+
(0, react_1.act)(() => {
|
|
416
393
|
jest.runOnlyPendingTimers();
|
|
417
394
|
});
|
|
418
|
-
expect(r.name
|
|
395
|
+
expect(r.name).toHaveTextContent("Brandon Dow");
|
|
419
396
|
expect(autoSaveStub).toBeCalledTimes(1);
|
|
420
397
|
expect(autoSaveStub).toBeCalledWith({ id: "a:1", firstName: "Foo" });
|
|
421
398
|
// And while that is in flight, trigger another user action
|
|
422
|
-
rtl_utils_1.click(r.focusSetAndSaveFieldLastName
|
|
399
|
+
(0, rtl_utils_1.click)(r.focusSetAndSaveFieldLastName, { allowAsync: true });
|
|
423
400
|
// (Use `wait` so that our timer flushes before the Promise.resolve(1) is ran)
|
|
424
|
-
await rtl_utils_1.wait();
|
|
401
|
+
await (0, rtl_utils_1.wait)();
|
|
425
402
|
// Then expect the auto save to only have been called twice. Once with each changedValues.
|
|
426
403
|
expect(autoSaveStub).toBeCalledTimes(2);
|
|
427
404
|
expect(autoSaveStub).toBeCalledWith({ id: "a:1", firstName: "Foo" });
|
|
@@ -436,20 +413,20 @@ describe("useFormState", () => {
|
|
|
436
413
|
};
|
|
437
414
|
// Given a component that is using autoSave
|
|
438
415
|
function TestComponent() {
|
|
439
|
-
const fs = useFormState_1.useFormState({
|
|
416
|
+
const fs = (0, useFormState_1.useFormState)({
|
|
440
417
|
config,
|
|
441
418
|
addRules(fs) {
|
|
442
419
|
// And also has calculated values
|
|
443
|
-
mobx_1.reaction(() => fs.firstName.value, (curr) => (fs.lastName.value = curr));
|
|
420
|
+
(0, mobx_1.reaction)(() => fs.firstName.value, (curr) => (fs.lastName.value = curr));
|
|
444
421
|
},
|
|
445
422
|
autoSave: (fs) => autoSaveStub(fs.changedValue),
|
|
446
423
|
init: { id: "a:1" },
|
|
447
424
|
});
|
|
448
|
-
return jsx_runtime_1.jsx(FormStateApp_1.TextField, { field: fs.firstName }
|
|
425
|
+
return (0, jsx_runtime_1.jsx)(FormStateApp_1.TextField, { field: fs.firstName });
|
|
449
426
|
}
|
|
450
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
427
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
451
428
|
// When the user sets one field
|
|
452
|
-
await rtl_utils_1.typeAndWait(r.firstName, "first");
|
|
429
|
+
await (0, rtl_utils_1.typeAndWait)(r.firstName, "first");
|
|
453
430
|
// Then we only called autoSave once
|
|
454
431
|
expect(autoSaveStub).toBeCalledTimes(1);
|
|
455
432
|
expect(autoSaveStub).toBeCalledWith({ id: "a:1", firstName: "first", lastName: "first" });
|
|
@@ -457,82 +434,77 @@ describe("useFormState", () => {
|
|
|
457
434
|
it("sets loading if opts.loading is true", async () => {
|
|
458
435
|
const config = { firstName: { type: "value" } };
|
|
459
436
|
function TestComponent({ loading }) {
|
|
460
|
-
const form = useFormState_1.useFormState({ config, loading });
|
|
461
|
-
return jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => jsx_runtime_1.jsx("div",
|
|
437
|
+
const form = (0, useFormState_1.useFormState)({ config, loading });
|
|
438
|
+
return (0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => (0, jsx_runtime_1.jsx)("div", { "data-testid": "loading", children: String(form.loading) }) });
|
|
462
439
|
}
|
|
463
440
|
// And we initially pass in `init.query.loading: true`
|
|
464
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, { loading: true }
|
|
441
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { loading: true }));
|
|
465
442
|
// Then the form is marked as loading
|
|
466
|
-
expect(r.loading
|
|
443
|
+
expect(r.loading).toHaveTextContent("true");
|
|
467
444
|
// And when the query is not loading
|
|
468
|
-
await r.rerender(jsx_runtime_1.jsx(TestComponent, { loading: false }
|
|
445
|
+
await r.rerender((0, jsx_runtime_1.jsx)(TestComponent, { loading: false }));
|
|
469
446
|
// Then the form is marked as not loading
|
|
470
|
-
expect(r.loading
|
|
447
|
+
expect(r.loading).toHaveTextContent("false");
|
|
471
448
|
});
|
|
472
449
|
it("sets loading if input.data is undefined", async () => {
|
|
473
450
|
const config = { firstName: { type: "value" } };
|
|
474
451
|
function TestComponent({ data }) {
|
|
475
|
-
const form = useFormState_1.useFormState({ config, init: { input: data, map: (d) => d } });
|
|
476
|
-
return jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => jsx_runtime_1.jsx("div",
|
|
452
|
+
const form = (0, useFormState_1.useFormState)({ config, init: { input: data, map: (d) => d } });
|
|
453
|
+
return (0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => (0, jsx_runtime_1.jsx)("div", { "data-testid": "loading", children: String(form.loading) }) });
|
|
477
454
|
}
|
|
478
455
|
// And we initially pass in `init.input: undefined`
|
|
479
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, { data: undefined }
|
|
456
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { data: undefined }));
|
|
480
457
|
// Then the form is marked as loading
|
|
481
|
-
expect(r.loading
|
|
458
|
+
expect(r.loading).toHaveTextContent("true");
|
|
482
459
|
// And when the data is no longer undefined
|
|
483
|
-
await r.rerender(jsx_runtime_1.jsx(TestComponent, { data: { firstName: "first" } }
|
|
460
|
+
await r.rerender((0, jsx_runtime_1.jsx)(TestComponent, { data: { firstName: "first" } }));
|
|
484
461
|
// Then the form is marked as not loading
|
|
485
|
-
expect(r.loading
|
|
462
|
+
expect(r.loading).toHaveTextContent("false");
|
|
486
463
|
});
|
|
487
464
|
it("sets loading if query.loading is true", async () => {
|
|
488
465
|
const config = { firstName: { type: "value" } };
|
|
489
466
|
function TestComponent({ loading, data }) {
|
|
490
|
-
const form = useFormState_1.useFormState({ config, init: { query: { data, loading, error: null }, map: (d) => d } });
|
|
491
|
-
return jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => jsx_runtime_1.jsx("div",
|
|
467
|
+
const form = (0, useFormState_1.useFormState)({ config, init: { query: { data, loading, error: null }, map: (d) => d } });
|
|
468
|
+
return (0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => (0, jsx_runtime_1.jsx)("div", { "data-testid": "loading", children: String(form.loading) }) });
|
|
492
469
|
}
|
|
493
470
|
// And we initially pass in `init.query.loading: true`
|
|
494
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, { loading: true, data: undefined }
|
|
471
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { loading: true, data: undefined }));
|
|
495
472
|
// Then the form is marked as loading
|
|
496
|
-
expect(r.loading
|
|
473
|
+
expect(r.loading).toHaveTextContent("true");
|
|
497
474
|
// And when the query is not loading
|
|
498
|
-
await r.rerender(jsx_runtime_1.jsx(TestComponent, { loading: false, data: { firstName: "first" } }
|
|
475
|
+
await r.rerender((0, jsx_runtime_1.jsx)(TestComponent, { loading: false, data: { firstName: "first" } }));
|
|
499
476
|
// Then the form is marked as not loading
|
|
500
|
-
expect(r.loading
|
|
477
|
+
expect(r.loading).toHaveTextContent("false");
|
|
501
478
|
});
|
|
502
479
|
it("treats the id changing as a whole new entity instead of a delete", async () => {
|
|
503
480
|
const config = { firstName: { type: "value" } };
|
|
504
481
|
function TestComponent() {
|
|
505
482
|
// Given an initial author a1
|
|
506
|
-
const [author, setAuthor] = react_2.useState({ id: "a:1", firstName: "a1" });
|
|
507
|
-
const form = useFormState_1.useFormState({ config, init: { input: author, map: (a) => a } });
|
|
508
|
-
return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div",
|
|
509
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "dirty" }, { children: String(form.firstName.dirty) }), void 0),
|
|
510
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "originalValue" }, { children: String(form.firstName.originalValue) }), void 0),
|
|
511
|
-
jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "objectValue" }, { children: String(form.value.firstName) }), void 0),
|
|
512
|
-
jsx_runtime_1.jsx("div", { "data-testid": "a1", onClick: () => setAuthor({ id: "a:1", firstName: "a1" }) }, void 0),
|
|
513
|
-
jsx_runtime_1.jsx("div", { "data-testid": "a2", onClick: () => setAuthor({ id: "a:2", firstName: undefined }) }, void 0)] }, void 0)) }, void 0));
|
|
483
|
+
const [author, setAuthor] = (0, react_2.useState)({ id: "a:1", firstName: "a1" });
|
|
484
|
+
const form = (0, useFormState_1.useFormState)({ config, init: { input: author, map: (a) => a } });
|
|
485
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "value", children: String(form.firstName.value) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "dirty", children: String(form.firstName.dirty) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "originalValue", children: String(form.firstName.originalValue) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "objectValue", children: String(form.value.firstName) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "a1", onClick: () => setAuthor({ id: "a:1", firstName: "a1" }) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "a2", onClick: () => setAuthor({ id: "a:2", firstName: undefined }) })] })) }));
|
|
514
486
|
}
|
|
515
|
-
const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}
|
|
487
|
+
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
|
|
516
488
|
// And the value is initially a1/and not dirty
|
|
517
|
-
expect(r.value
|
|
518
|
-
expect(r.dirty
|
|
519
|
-
expect(r.originalValue
|
|
520
|
-
expect(r.objectValue
|
|
489
|
+
expect(r.value).toHaveTextContent("a1");
|
|
490
|
+
expect(r.dirty).toHaveTextContent("false");
|
|
491
|
+
expect(r.originalValue).toHaveTextContent("a1");
|
|
492
|
+
expect(r.objectValue).toHaveTextContent("a1");
|
|
521
493
|
// When we switch to a completely separate author
|
|
522
|
-
rtl_utils_1.click(r.a2);
|
|
494
|
+
(0, rtl_utils_1.click)(r.a2);
|
|
523
495
|
// Then it switches to the next author
|
|
524
|
-
expect(r.value
|
|
496
|
+
expect(r.value).toHaveTextContent("undefined");
|
|
525
497
|
// And the field is not dirty (which had been the case before this bug fix)
|
|
526
|
-
expect(r.dirty
|
|
527
|
-
expect(r.originalValue
|
|
528
|
-
expect(r.objectValue
|
|
498
|
+
expect(r.dirty).toHaveTextContent("false");
|
|
499
|
+
expect(r.originalValue).toHaveTextContent("undefined");
|
|
500
|
+
expect(r.objectValue).toHaveTextContent("undefined");
|
|
529
501
|
// And when we switch back to the original author
|
|
530
|
-
rtl_utils_1.click(r.a1);
|
|
502
|
+
(0, rtl_utils_1.click)(r.a1);
|
|
531
503
|
// It again restores the value and does not think an edit was WIP
|
|
532
|
-
expect(r.value
|
|
533
|
-
expect(r.dirty
|
|
534
|
-
expect(r.originalValue
|
|
535
|
-
expect(r.objectValue
|
|
504
|
+
expect(r.value).toHaveTextContent("a1");
|
|
505
|
+
expect(r.dirty).toHaveTextContent("false");
|
|
506
|
+
expect(r.originalValue).toHaveTextContent("a1");
|
|
507
|
+
expect(r.objectValue).toHaveTextContent("a1");
|
|
536
508
|
});
|
|
537
509
|
});
|
|
538
510
|
const authorConfig = {
|
package/dist/useFormStates.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ObjectConfig } from "./config";
|
|
2
2
|
import { ObjectState } from "./fields/objectField";
|
|
3
|
-
export
|
|
4
|
-
|
|
3
|
+
export type ObjectStateCache<T, I> = Record<string, [ObjectState<T>, I]>;
|
|
4
|
+
type UseFormStatesOpts<T, I> = {
|
|
5
5
|
/**
|
|
6
6
|
* The config to use for each form state.
|
|
7
7
|
*
|
|
@@ -40,7 +40,7 @@ declare type UseFormStatesOpts<T, I> = {
|
|
|
40
40
|
*/
|
|
41
41
|
readOnly?: boolean;
|
|
42
42
|
};
|
|
43
|
-
|
|
43
|
+
type UseFormStatesHook<T, I> = {
|
|
44
44
|
getFormState: (input: I, opts?: {
|
|
45
45
|
readOnly?: boolean;
|
|
46
46
|
}) => ObjectState<T>;
|