@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.
@@ -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 }, void 0);
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, {}, void 0));
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 }, void 0),
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, {}, void 0));
42
- expect(r.firstName()).toHaveTextContent("ab");
43
- rtl_utils_1.click(r.change);
44
- expect(r.firstName()).toHaveTextContent("fred");
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 }, void 0);
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, {}, void 0));
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", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0),
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, {}, void 0));
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
- } }, void 0),
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, {}, void 0));
106
- expect(r.firstName()).toHaveTextContent("bob");
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()).toHaveTextContent("fred");
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 }, void 0);
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, {}, void 0));
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", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0),
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, {}, void 0));
180
- expect(r.firstName().textContent).toEqual("f1");
181
- expect(r.street().textContent).toEqual("s1");
182
- expect(r.title1().textContent).toEqual("a1");
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().textContent).toEqual("local");
187
- expect(r.street().textContent).toEqual("local");
188
- expect(r.title1().textContent).toEqual("local");
189
- expect(JSON.parse(r.changedValue().textContent)).toEqual({
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().textContent).toEqual("local");
199
- expect(r.street().textContent).toEqual("local");
200
- expect(r.title1().textContent).toEqual("local");
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().textContent).toEqual("l2");
203
- expect(r.city().textContent).toEqual("c2");
204
- expect(r.title2().textContent).toEqual("b2");
205
- expect(r.booksLength().textContent).toEqual("3");
206
- expect(JSON.parse(r.changedValue().textContent)).toEqual({
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().textContent)).toEqual({
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", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0),
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, {}, void 0));
249
- expect(r.firstName().textContent).toEqual("f1");
250
- expect(r.street().textContent).toEqual("s1");
251
- expect(r.title1().textContent).toEqual("a1");
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().textContent).toEqual("f2");
256
- expect(r.street().textContent).toEqual("s2");
257
- expect(r.title1().textContent).toEqual("a2");
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", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0),
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, {}, void 0));
290
- expect(r.firstName().textContent).toEqual("f1");
291
- expect(r.fullName().textContent).toEqual("f1 l1");
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().textContent).toEqual("f2");
295
- expect(r.fullName().textContent).toEqual("f2 l2");
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) }, void 0),
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, {}, void 0));
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") }, void 0) }, void 0));
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, {}, void 0));
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
- } }, void 0) }, void 0));
349
+ } }) }));
371
350
  }
372
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
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", Object.assign({ "data-testid": "name" }, { children: [apiData.firstName, " ", apiData.lastName] }), void 0),
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
- } }, void 0),
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
- } }, void 0)] }, void 0));
385
+ } })] }));
409
386
  }
410
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
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(), { allowAsync: true });
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()).toHaveTextContent("Brandon Dow");
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(), { allowAsync: true });
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 }, void 0);
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, {}, void 0));
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", Object.assign({ "data-testid": "loading" }, { children: String(form.loading) }), void 0) }, void 0);
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 }, void 0));
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()).toHaveTextContent("true");
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 }, void 0));
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()).toHaveTextContent("false");
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", Object.assign({ "data-testid": "loading" }, { children: String(form.loading) }), void 0) }, void 0);
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 }, void 0));
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()).toHaveTextContent("true");
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" } }, void 0));
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()).toHaveTextContent("false");
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", Object.assign({ "data-testid": "loading" }, { children: String(form.loading) }), void 0) }, void 0);
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 }, void 0));
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()).toHaveTextContent("true");
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" } }, void 0));
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()).toHaveTextContent("false");
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", Object.assign({ "data-testid": "value" }, { children: String(form.firstName.value) }), void 0),
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, {}, void 0));
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()).toHaveTextContent("a1");
518
- expect(r.dirty()).toHaveTextContent("false");
519
- expect(r.originalValue()).toHaveTextContent("a1");
520
- expect(r.objectValue()).toHaveTextContent("a1");
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()).toHaveTextContent("undefined");
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()).toHaveTextContent("false");
527
- expect(r.originalValue()).toHaveTextContent("undefined");
528
- expect(r.objectValue()).toHaveTextContent("undefined");
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()).toHaveTextContent("a1");
533
- expect(r.dirty()).toHaveTextContent("false");
534
- expect(r.originalValue()).toHaveTextContent("a1");
535
- expect(r.objectValue()).toHaveTextContent("a1");
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 = {
@@ -1,7 +1,7 @@
1
1
  import { ObjectConfig } from "./config";
2
2
  import { ObjectState } from "./fields/objectField";
3
- export declare type ObjectStateCache<T, I> = Record<string, [ObjectState<T>, I]>;
4
- declare type UseFormStatesOpts<T, I> = {
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
- declare type UseFormStatesHook<T, I> = {
43
+ type UseFormStatesHook<T, I> = {
44
44
  getFormState: (input: I, opts?: {
45
45
  readOnly?: boolean;
46
46
  }) => ObjectState<T>;