xmlui 0.10.26 → 0.11.2

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 (61) hide show
  1. package/dist/lib/{index-DHXWMb-6.mjs → index-DyhCY6Ga.js} +263 -643
  2. package/dist/lib/index.css +1 -1
  3. package/dist/lib/{initMock-TxnkId6_.mjs → initMock-DN7MXrdn.js} +1 -1
  4. package/dist/lib/{language-server-web-worker.mjs → language-server-web-worker.js} +1 -1
  5. package/dist/lib/{language-server.mjs → language-server.js} +1 -1
  6. package/dist/lib/{metadata-utils-DXUdlyja.mjs → metadata-utils-D27cn-XB.js} +1 -1
  7. package/dist/lib/{server-common-CtpN0Z4h.mjs → server-common-2DaoOOL5.js} +625 -616
  8. package/dist/lib/testing.d.ts +2011 -0
  9. package/dist/lib/testing.js +2386 -0
  10. package/dist/lib/vite-xmlui-plugin/index.js +13968 -0
  11. package/dist/lib/vite-xmlui-plugin/package.json +3 -0
  12. package/dist/lib/xmlui-parser-BZZ430Wm.js +523 -0
  13. package/dist/lib/xmlui-parser.d.ts +2 -1
  14. package/dist/lib/{xmlui-parser.mjs → xmlui-parser.js} +2 -2
  15. package/dist/lib/{xmlui-serializer-uCYa8_tZ.mjs → xmlui-serializer-D9D2mQ8m.js} +1 -1
  16. package/dist/lib/xmlui.d.ts +1 -0
  17. package/dist/lib/{xmlui.mjs → xmlui.js} +24 -23
  18. package/dist/metadata/{collectedComponentMetadata-BgHIc2Iu.mjs → collectedComponentMetadata-BNSnCrzh.js} +698 -567
  19. package/dist/metadata/{initMock-B3UDa-rw.mjs → initMock-CVnDRyRf.js} +1 -1
  20. package/dist/metadata/style.css +1 -1
  21. package/dist/metadata/{xmlui-metadata.mjs → xmlui-metadata.js} +1 -1
  22. package/dist/metadata/xmlui-metadata.umd.cjs +207 -0
  23. package/dist/scripts/bin/bootstrap.cjs +4 -0
  24. package/dist/scripts/bin/index.js +85 -13
  25. package/dist/scripts/package.json +31 -24
  26. package/dist/scripts/src/components/App/App.spec.js +27 -15
  27. package/dist/scripts/src/components/Avatar/Avatar.spec.js +0 -29
  28. package/dist/scripts/src/components/Button/Button.spec.js +0 -29
  29. package/dist/scripts/src/components/Charts/BarChart/BarChartNative.js +2 -0
  30. package/dist/scripts/src/components/Charts/LineChart/LineChartNative.js +2 -2
  31. package/dist/scripts/src/components/Charts/Tooltip/TooltipContent.spec.js +8 -6
  32. package/dist/scripts/src/components/Form/Form.js +19 -0
  33. package/dist/scripts/src/components/Form/Form.spec.js +444 -0
  34. package/dist/scripts/src/components/Form/FormNative.js +46 -15
  35. package/dist/scripts/src/components/Form/formActions.js +3 -2
  36. package/dist/scripts/src/components/FormItem/FormItem.js +10 -2
  37. package/dist/scripts/src/components/FormItem/FormItem.spec.js +159 -0
  38. package/dist/scripts/src/components/FormItem/FormItemNative.js +6 -5
  39. package/dist/scripts/src/components/Heading/Heading.spec.js +34 -47
  40. package/dist/scripts/src/components/Queue/Queue.js +1 -16
  41. package/dist/scripts/src/components/Queue/QueueNative.js +60 -2
  42. package/dist/scripts/src/components/TableOfContents/TableOfContents.js +7 -5
  43. package/dist/scripts/src/components-core/appContext/misc-utils.js +2 -1
  44. package/dist/scripts/src/components-core/devtools/InspectorDialog.js +2 -2
  45. package/dist/scripts/src/components-core/script-runner/eval-tree-async.js +2 -0
  46. package/dist/scripts/src/components-core/utils/base64-utils.js +2 -0
  47. package/dist/scripts/src/components-core/utils/misc.js +44 -0
  48. package/dist/scripts/src/language-server/server-common.js +2 -2
  49. package/dist/scripts/src/language-server/{xmlui-metadata-generated.mjs → xmlui-metadata-generated.js} +625 -615
  50. package/dist/scripts/src/testing/drivers/index.js +9 -0
  51. package/dist/scripts/src/testing/index.js +69 -0
  52. package/dist/standalone/xmlui-standalone.es.d.ts +32 -16
  53. package/dist/standalone/xmlui-standalone.umd.js +36 -36
  54. package/package.json +46 -39
  55. package/dist/metadata/xmlui-metadata.umd.js +0 -207
  56. package/dist/scripts/bin/bootstrap.js +0 -11
  57. /package/dist/lib/{apiInterceptorWorker-QiltRtq1.mjs → apiInterceptorWorker-QiltRtq1.js} +0 -0
  58. /package/dist/lib/{syntax-monaco.mjs → syntax-monaco.js} +0 -0
  59. /package/dist/lib/{syntax-textmate.mjs → syntax-textmate.js} +0 -0
  60. /package/dist/lib/{transform-Tooy42EB.mjs → transform-Tooy42EB.js} +0 -0
  61. /package/dist/metadata/{apiInterceptorWorker-Dql7QGw2.mjs → apiInterceptorWorker-Dql7QGw2.js} +0 -0
@@ -97,6 +97,334 @@ fixtures_1.test.describe("Basic Functionality", () => {
97
97
  yield (0, fixtures_1.expect)(buttons.last()).toHaveText("Cancel");
98
98
  }));
99
99
  // =============================================================================
100
+ // HIDE BUTTON ROW TESTS
101
+ // =============================================================================
102
+ fixtures_1.test.describe("hideButtonRow property", () => {
103
+ (0, fixtures_1.test)("hides button row when set to true", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
104
+ yield initTestBed(`<Form hideButtonRow="true"/>`);
105
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
106
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
107
+ }));
108
+ (0, fixtures_1.test)("shows button row when set to false", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
109
+ yield initTestBed(`<Form hideButtonRow="false"/>`);
110
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
111
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
112
+ }));
113
+ (0, fixtures_1.test)("shows button row by default when property not set", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
114
+ yield initTestBed(`<Form/>`);
115
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
116
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
117
+ }));
118
+ (0, fixtures_1.test)("hides custom button row template when set to true", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
119
+ yield initTestBed(`
120
+ <Form hideButtonRow="true">
121
+ <property name="buttonRowTemplate">
122
+ <Button label="Custom Save" type="submit" testId="customSave" />
123
+ <Button label="Custom Cancel" type="button" testId="customCancel" />
124
+ </property>
125
+ </Form>
126
+ `);
127
+ yield (0, fixtures_1.expect)(page.getByTestId("customSave")).not.toBeVisible();
128
+ yield (0, fixtures_1.expect)(page.getByTestId("customCancel")).not.toBeVisible();
129
+ }));
130
+ (0, fixtures_1.test)("overrides hideButtonRowUntilDirty when both are set", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
131
+ yield initTestBed(`
132
+ <Form hideButtonRow="true" hideButtonRowUntilDirty="true">
133
+ <FormItem label="Name" bindTo="name" testId="nameField" />
134
+ </Form>
135
+ `);
136
+ // Button row should be hidden even before making changes
137
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
138
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
139
+ // Make the form dirty
140
+ const driver = yield createFormItemDriver("nameField");
141
+ const input = yield createTextBoxDriver(driver.input);
142
+ yield input.field.fill("John");
143
+ // Button row should still be hidden even after making changes
144
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
145
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
146
+ }));
147
+ (0, fixtures_1.test)("handles null value gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
148
+ yield initTestBed(`<Form hideButtonRow="{null}"/>`);
149
+ // Should show button row (default behavior)
150
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
151
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
152
+ }));
153
+ (0, fixtures_1.test)("handles undefined value gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
154
+ yield initTestBed(`<Form hideButtonRow="{undefined}"/>`);
155
+ // Should show button row (default behavior)
156
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
157
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
158
+ }));
159
+ (0, fixtures_1.test)("handles string 'true' value", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
160
+ yield initTestBed(`<Form hideButtonRow="true"/>`);
161
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
162
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
163
+ }));
164
+ (0, fixtures_1.test)("handles string 'false' value", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
165
+ yield initTestBed(`<Form hideButtonRow="false"/>`);
166
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
167
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
168
+ }));
169
+ (0, fixtures_1.test)("form submission still works with hidden button row via external submit", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
170
+ const { testStateDriver } = yield initTestBed(`
171
+ <Fragment>
172
+ <Form id="testForm" hideButtonRow="true" onSubmit="arg => testState = arg">
173
+ <FormItem label="Name" bindTo="name" testId="nameField" />
174
+ <Button type="submit" label="External Submit" testId="externalSubmit" />
175
+ </Form>
176
+ </Fragment>
177
+ `);
178
+ const driver = yield createFormItemDriver("nameField");
179
+ const input = yield createTextBoxDriver(driver.input);
180
+ yield input.field.fill("John Doe");
181
+ yield page.getByTestId("externalSubmit").click();
182
+ const submittedData = yield testStateDriver.testState();
183
+ (0, fixtures_1.expect)(submittedData).toEqual({ name: "John Doe" });
184
+ }));
185
+ });
186
+ // =============================================================================
187
+ // HIDE BUTTON ROW UNTIL DIRTY TESTS
188
+ // =============================================================================
189
+ fixtures_1.test.describe("hideButtonRowUntilDirty property", () => {
190
+ (0, fixtures_1.test)("hides button row initially when form is not dirty", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
191
+ yield initTestBed(`
192
+ <Form hideButtonRowUntilDirty="true">
193
+ <FormItem label="Name" bindTo="name" testId="nameField" />
194
+ </Form>
195
+ `);
196
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
197
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
198
+ }));
199
+ (0, fixtures_1.test)("shows button row when form becomes dirty", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
200
+ yield initTestBed(`
201
+ <Form hideButtonRowUntilDirty="true">
202
+ <FormItem label="Name" bindTo="name" testId="nameField" />
203
+ </Form>
204
+ `);
205
+ // Initially hidden
206
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
207
+ // Make form dirty
208
+ const driver = yield createFormItemDriver("nameField");
209
+ const input = yield createTextBoxDriver(driver.input);
210
+ yield input.field.fill("John");
211
+ // Now visible
212
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
213
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
214
+ }));
215
+ (0, fixtures_1.test)("keeps button row visible after form becomes dirty", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
216
+ yield initTestBed(`
217
+ <Form hideButtonRowUntilDirty="true">
218
+ <FormItem label="Name" bindTo="name" testId="nameField" />
219
+ </Form>
220
+ `);
221
+ const driver = yield createFormItemDriver("nameField");
222
+ const input = yield createTextBoxDriver(driver.input);
223
+ // Make form dirty
224
+ yield input.field.fill("John");
225
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
226
+ // Clear the input (form is still dirty)
227
+ yield input.field.clear();
228
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
229
+ }));
230
+ (0, fixtures_1.test)("shows button row by default when property set to false", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, }) {
231
+ yield initTestBed(`
232
+ <Form hideButtonRowUntilDirty="false">
233
+ <FormItem label="Name" bindTo="name" testId="nameField" />
234
+ </Form>
235
+ `);
236
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
237
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
238
+ }));
239
+ (0, fixtures_1.test)("shows button row by default when property not set", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
240
+ yield initTestBed(`
241
+ <Form>
242
+ <FormItem label="Name" bindTo="name" testId="nameField" />
243
+ </Form>
244
+ `);
245
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
246
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
247
+ }));
248
+ (0, fixtures_1.test)("works with multiple form items", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
249
+ yield initTestBed(`
250
+ <Form hideButtonRowUntilDirty="true">
251
+ <FormItem label="Name" bindTo="name" testId="nameField" />
252
+ <FormItem label="Email" bindTo="email" testId="emailField" />
253
+ </Form>
254
+ `);
255
+ // Initially hidden
256
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
257
+ // Modify second field
258
+ const emailDriver = yield createFormItemDriver("emailField");
259
+ const emailInput = yield createTextBoxDriver(emailDriver.input);
260
+ yield emailInput.field.fill("test@example.com");
261
+ // Now visible
262
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
263
+ }));
264
+ (0, fixtures_1.test)("hides custom button row template until dirty", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
265
+ yield initTestBed(`
266
+ <Form hideButtonRowUntilDirty="true">
267
+ <FormItem label="Name" bindTo="name" testId="nameField" />
268
+ <property name="buttonRowTemplate">
269
+ <Button label="Custom Save" type="submit" testId="customSave" />
270
+ </property>
271
+ </Form>
272
+ `);
273
+ // Initially hidden
274
+ yield (0, fixtures_1.expect)(page.getByTestId("customSave")).not.toBeVisible();
275
+ // Make form dirty
276
+ const driver = yield createFormItemDriver("nameField");
277
+ const input = yield createTextBoxDriver(driver.input);
278
+ yield input.field.fill("John");
279
+ // Now visible
280
+ yield (0, fixtures_1.expect)(page.getByTestId("customSave")).toBeVisible();
281
+ }));
282
+ (0, fixtures_1.test)("handles null value gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
283
+ yield initTestBed(`
284
+ <Form hideButtonRowUntilDirty="{null}">
285
+ <FormItem label="Name" bindTo="name" testId="nameField" />
286
+ </Form>
287
+ `);
288
+ // Should show button row (default behavior)
289
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
290
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
291
+ }));
292
+ (0, fixtures_1.test)("handles undefined value gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
293
+ yield initTestBed(`
294
+ <Form hideButtonRowUntilDirty="{undefined}">
295
+ <FormItem label="Name" bindTo="name" testId="nameField" />
296
+ </Form>
297
+ `);
298
+ // Should show button row (default behavior)
299
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
300
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
301
+ }));
302
+ (0, fixtures_1.test)("works with form initialized with data", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
303
+ yield initTestBed(`
304
+ <Form hideButtonRowUntilDirty="true" data="{{ name: 'Initial' }}">
305
+ <FormItem label="Name" bindTo="name" testId="nameField" />
306
+ </Form>
307
+ `);
308
+ // Initially hidden (form has data but is not dirty)
309
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
310
+ // Make form dirty
311
+ const driver = yield createFormItemDriver("nameField");
312
+ const input = yield createTextBoxDriver(driver.input);
313
+ yield input.field.fill("Modified");
314
+ // Now visible
315
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
316
+ }));
317
+ (0, fixtures_1.test)("button row appears when checkbox is checked", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
318
+ yield initTestBed(`
319
+ <Form hideButtonRowUntilDirty="true">
320
+ <FormItem label="Accept Terms" bindTo="terms" type="checkbox" />
321
+ </Form>
322
+ `);
323
+ // Initially hidden
324
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
325
+ // Check the checkbox
326
+ const checkbox = page.getByRole("checkbox");
327
+ yield checkbox.check();
328
+ // Now visible
329
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
330
+ }));
331
+ (0, fixtures_1.test)("button row appears when slider value changes", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
332
+ yield initTestBed(`
333
+ <Form hideButtonRowUntilDirty="true">
334
+ <FormItem label="Volume" bindTo="volume" type="slider" testId="volumeField" />
335
+ </Form>
336
+ `);
337
+ // Initially hidden
338
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
339
+ // Move the slider using keyboard
340
+ const slider = page.getByRole("slider");
341
+ yield slider.press("ArrowRight");
342
+ // Now visible
343
+ yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
344
+ }));
345
+ });
346
+ // =============================================================================
347
+ // ENABLE SUBMIT PROPERTY TESTS
348
+ // =============================================================================
349
+ fixtures_1.test.describe("enableSubmit property", () => {
350
+ (0, fixtures_1.test)("disables submit button when set to false", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
351
+ yield initTestBed(`<Form enableSubmit="false"/>`);
352
+ const saveButton = page.getByRole("button", { name: "Save" });
353
+ yield (0, fixtures_1.expect)(saveButton).toBeVisible();
354
+ yield (0, fixtures_1.expect)(saveButton).toBeDisabled();
355
+ }));
356
+ (0, fixtures_1.test)("enables submit button when set to true", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
357
+ yield initTestBed(`<Form enableSubmit="true"/>`);
358
+ const saveButton = page.getByRole("button", { name: "Save" });
359
+ yield (0, fixtures_1.expect)(saveButton).toBeVisible();
360
+ yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
361
+ }));
362
+ (0, fixtures_1.test)("submit button is enabled by default when property not set", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, }) {
363
+ yield initTestBed(`<Form/>`);
364
+ const saveButton = page.getByRole("button", { name: "Save" });
365
+ yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
366
+ }));
367
+ (0, fixtures_1.test)("prevents form submission when set to false", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
368
+ const { testStateDriver } = yield initTestBed(`
369
+ <Form enableSubmit="false" onSubmit="arg => testState = arg">
370
+ <FormItem label="Name" bindTo="name" testId="nameField" />
371
+ </Form>
372
+ `);
373
+ const saveButton = page.getByRole("button", { name: "Save" });
374
+ yield (0, fixtures_1.expect)(saveButton).toBeDisabled();
375
+ // Verify form does not submit (button is disabled, so click won't work)
376
+ yield saveButton.click({ force: true }); // Force click on disabled button
377
+ // testState should remain null since submit was prevented
378
+ yield fixtures_1.expect.poll(testStateDriver.testState).toBeNull();
379
+ }));
380
+ (0, fixtures_1.test)("allows form submission when set to true", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
381
+ const { testStateDriver } = yield initTestBed(`
382
+ <Form enableSubmit="true" onSubmit="arg => testState = arg">
383
+ <FormItem label="Name" bindTo="name" testId="nameField" />
384
+ </Form>
385
+ `);
386
+ const driver = yield createFormItemDriver("nameField");
387
+ const input = yield createTextBoxDriver(driver.input);
388
+ yield input.field.fill("John Doe");
389
+ const saveButton = page.getByRole("button", { name: "Save" });
390
+ yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
391
+ yield saveButton.click();
392
+ const submittedData = yield testStateDriver.testState();
393
+ (0, fixtures_1.expect)(submittedData).toEqual({ name: "John Doe" });
394
+ }));
395
+ (0, fixtures_1.test)("handles null value gracefully (defaults to enabled)", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
396
+ yield initTestBed(`<Form enableSubmit="{null}"/>`);
397
+ const saveButton = page.getByRole("button", { name: "Save" });
398
+ yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
399
+ }));
400
+ (0, fixtures_1.test)("handles string 'true' value", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
401
+ yield initTestBed(`<Form enableSubmit="true"/>`);
402
+ const saveButton = page.getByRole("button", { name: "Save" });
403
+ yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
404
+ }));
405
+ (0, fixtures_1.test)("handles string 'false' value", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
406
+ yield initTestBed(`<Form enableSubmit="false"/>`);
407
+ const saveButton = page.getByRole("button", { name: "Save" });
408
+ yield (0, fixtures_1.expect)(saveButton).toBeDisabled();
409
+ }));
410
+ (0, fixtures_1.test)("does not affect cancel button", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
411
+ yield initTestBed(`<Form enableSubmit="false"/>`);
412
+ const cancelButton = page.getByRole("button", { name: "Cancel" });
413
+ yield (0, fixtures_1.expect)(cancelButton).toBeEnabled();
414
+ }));
415
+ (0, fixtures_1.test)("works with custom submit button label", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
416
+ yield initTestBed(`<Form enableSubmit="false" saveLabel="Submit Now"/>`);
417
+ const submitButton = page.getByRole("button", { name: "Submit Now" });
418
+ yield (0, fixtures_1.expect)(submitButton).toBeDisabled();
419
+ }));
420
+ (0, fixtures_1.test)("works together with form disabled state", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
421
+ yield initTestBed(`<Form enabled="false" enableSubmit="true"/>`);
422
+ const saveButton = page.getByRole("button", { name: "Save" });
423
+ // Form disabled takes precedence
424
+ yield (0, fixtures_1.expect)(saveButton).toBeDisabled();
425
+ }));
426
+ });
427
+ // =============================================================================
100
428
  // DATA PROPERTY TESTS
101
429
  // =============================================================================
102
430
  fixtures_1.test.describe("data property", () => {
@@ -366,6 +694,122 @@ fixtures_1.test.describe("Basic Functionality", () => {
366
694
  yield page.getByRole("button", { name: "Reset" }).click();
367
695
  yield (0, fixtures_1.expect)(nameInput.field).toHaveValue("Initial");
368
696
  }));
697
+ (0, fixtures_1.test)("validate method returns validation results without submitting", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
698
+ const { testStateDriver } = yield initTestBed(`
699
+ <Form id="testForm">
700
+ <FormItem label="Name" bindTo="name" required="true" testId="nameField" />
701
+ <FormItem label="Email" bindTo="email" testId="emailField" />
702
+ <Button onClick="testState = testForm.validate()" label="Validate" testId="validateBtn" />
703
+ </Form>
704
+ `);
705
+ // Click validate button without filling required field
706
+ yield page.getByTestId("validateBtn").click();
707
+ // Wait for validation to complete
708
+ yield page.waitForTimeout(100);
709
+ const result = yield testStateDriver.testState();
710
+ (0, fixtures_1.expect)(result).toBeTruthy();
711
+ (0, fixtures_1.expect)(result.isValid).toBe(false);
712
+ (0, fixtures_1.expect)(result.errors).toBeDefined();
713
+ (0, fixtures_1.expect)(result.errors.length).toBeGreaterThan(0);
714
+ }));
715
+ (0, fixtures_1.test)("validate method returns isValid true when all validations pass", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
716
+ const { testStateDriver } = yield initTestBed(`
717
+ <Form id="testForm">
718
+ <FormItem label="Name" bindTo="name" required="true" testId="nameField" />
719
+ <Button onClick="testState = testForm.validate()" label="Validate" testId="validateBtn" />
720
+ </Form>
721
+ `);
722
+ // Fill the required field
723
+ const nameDriver = yield createFormItemDriver("nameField");
724
+ const nameInput = yield createTextBoxDriver(nameDriver.input);
725
+ yield nameInput.field.fill("John Doe");
726
+ // Click validate button
727
+ yield page.getByTestId("validateBtn").click();
728
+ // Wait for validation to complete
729
+ yield page.waitForTimeout(100);
730
+ const result = yield testStateDriver.testState();
731
+ (0, fixtures_1.expect)(result).toBeTruthy();
732
+ (0, fixtures_1.expect)(result.isValid).toBe(true);
733
+ (0, fixtures_1.expect)(result.errors.length).toBe(0);
734
+ }));
735
+ (0, fixtures_1.test)("validate method returns cleaned form data", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
736
+ const { testStateDriver } = yield initTestBed(`
737
+ <Form id="testForm">
738
+ <FormItem label="Name" bindTo="name" testId="nameField" />
739
+ <FormItem label="Age" bindTo="age" type="integer" testId="ageField" />
740
+ <Button onClick="testState = testForm.validate()" label="Validate" testId="validateBtn" />
741
+ </Form>
742
+ `);
743
+ // Fill form fields
744
+ const nameDriver = yield createFormItemDriver("nameField");
745
+ const nameInput = yield createTextBoxDriver(nameDriver.input);
746
+ yield nameInput.field.fill("John Doe");
747
+ const ageDriver = yield createFormItemDriver("ageField");
748
+ const ageInput = yield createTextBoxDriver(ageDriver.input);
749
+ yield ageInput.field.fill("30");
750
+ // Click validate button
751
+ yield page.getByTestId("validateBtn").click();
752
+ // Wait for validation to complete
753
+ yield page.waitForTimeout(100);
754
+ const result = yield testStateDriver.testState();
755
+ (0, fixtures_1.expect)(result).toBeTruthy();
756
+ (0, fixtures_1.expect)(result.data).toEqual({ name: "John Doe", age: "30" });
757
+ }));
758
+ (0, fixtures_1.test)("validate method displays validation errors on form", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, }) {
759
+ yield initTestBed(`
760
+ <Form id="testForm">
761
+ <FormItem label="Name" bindTo="name" required="true" testId="nameField" />
762
+ <Button onClick="testForm.validate()" label="Validate" testId="validateBtn" />
763
+ </Form>
764
+ `);
765
+ // Click validate without filling required field
766
+ yield page.getByTestId("validateBtn").click();
767
+ // Validation error should be displayed
768
+ const nameField = page.getByTestId("nameField");
769
+ yield (0, fixtures_1.expect)(nameField).toContainText("This field is required");
770
+ }));
771
+ (0, fixtures_1.test)("validate method does not trigger form submission", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
772
+ const { testStateDriver } = yield initTestBed(`
773
+ <Form id="testForm" onSubmit="testState = 'submitted'">
774
+ <FormItem label="Name" bindTo="name" testId="nameField" />
775
+ <Button onClick="testForm.validate()" label="Validate" testId="validateBtn" />
776
+ </Form>
777
+ `);
778
+ // Fill form
779
+ const nameDriver = yield createFormItemDriver("nameField");
780
+ const nameInput = yield createTextBoxDriver(nameDriver.input);
781
+ yield nameInput.field.fill("John");
782
+ // Click validate button
783
+ yield page.getByTestId("validateBtn").click();
784
+ // Wait a bit
785
+ yield page.waitForTimeout(200);
786
+ // testState should remain null (not 'submitted')
787
+ yield fixtures_1.expect.poll(testStateDriver.testState).toBeNull();
788
+ }));
789
+ (0, fixtures_1.test)("validate method returns complete validation results object", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
790
+ const { testStateDriver } = yield initTestBed(`
791
+ <Form id="testForm">
792
+ <FormItem label="Name" bindTo="name" required="true" testId="nameField" />
793
+ <FormItem label="Email" bindTo="email" testId="emailField" />
794
+ <Button onClick="testState = testForm.validate()" label="Validate" testId="validateBtn" />
795
+ </Form>
796
+ `);
797
+ // Fill only email (name is required)
798
+ const emailDriver = yield createFormItemDriver("emailField");
799
+ const emailInput = yield createTextBoxDriver(emailDriver.input);
800
+ yield emailInput.field.fill("test@example.com");
801
+ // Click validate button
802
+ yield page.getByTestId("validateBtn").click();
803
+ // Wait for validation to complete
804
+ yield page.waitForTimeout(100);
805
+ const result = yield testStateDriver.testState();
806
+ (0, fixtures_1.expect)(result).toBeTruthy();
807
+ (0, fixtures_1.expect)(result.isValid).toBeDefined();
808
+ (0, fixtures_1.expect)(result.data).toBeDefined();
809
+ (0, fixtures_1.expect)(result.errors).toBeDefined();
810
+ (0, fixtures_1.expect)(result.warnings).toBeDefined();
811
+ (0, fixtures_1.expect)(result.validationResults).toBeDefined();
812
+ }));
369
813
  });
370
814
  // =============================================================================
371
815
  // CONTEXT VARIABLE TESTS
@@ -68,14 +68,24 @@ const formReducer = (0, immer_1.default)((state, action) => {
68
68
  }
69
69
  switch (action.type) {
70
70
  case formActions_1.FormActionKind.FIELD_INITIALIZED: {
71
- if (!state.interactionFlags[uid].isDirty || action.payload.force) {
71
+ // Only set the value if initialValue is defined and field is not dirty (or force is true)
72
+ if (action.payload.value !== undefined && (!state.interactionFlags[uid].isDirty || action.payload.force)) {
72
73
  (0, lodash_es_1.set)(state.subject, uid, action.payload.value);
73
74
  }
75
+ // Track noSubmit flag - if multiple FormItems reference the same bindTo,
76
+ // and any of them has noSubmit: true, the field should NOT be submitted.
77
+ if (state.noSubmitFields[uid] === true || action.payload.noSubmit === true) {
78
+ state.noSubmitFields[uid] = true;
79
+ }
80
+ else {
81
+ state.noSubmitFields[uid] = false;
82
+ }
74
83
  break;
75
84
  }
76
85
  case formActions_1.FormActionKind.FIELD_REMOVED: {
77
86
  delete state.validationResults[uid];
78
87
  delete state.interactionFlags[uid];
88
+ delete state.noSubmitFields[uid];
79
89
  break;
80
90
  }
81
91
  case formActions_1.FormActionKind.FIELD_VALUE_CHANGED: {
@@ -180,6 +190,7 @@ const initialState = {
180
190
  validationResults: {},
181
191
  generalValidationResults: [],
182
192
  interactionFlags: {},
193
+ noSubmitFields: {},
183
194
  submitInProgress: false,
184
195
  resetVersion: 0,
185
196
  };
@@ -192,18 +203,21 @@ exports.defaultProps = {
192
203
  keepModalOpenOnSubmit: false,
193
204
  swapCancelAndSave: false,
194
205
  hideButtonRowUntilDirty: false,
206
+ hideButtonRow: false,
207
+ enableSubmit: true,
195
208
  };
196
209
  // --- Remove the properties from formState.subject where the property name ends with UNBOUND_FIELD_SUFFIX
197
- function cleanUpSubject(subject) {
210
+ // --- or where the field has noSubmit set to true
211
+ function cleanUpSubject(subject, noSubmitFields) {
198
212
  return Object.entries(subject || {}).reduce((acc, [key, value]) => {
199
- if (!key.endsWith(formActions_1.UNBOUND_FIELD_SUFFIX)) {
213
+ if (!key.endsWith(formActions_1.UNBOUND_FIELD_SUFFIX) && !noSubmitFields[key]) {
200
214
  acc[key] = value;
201
215
  }
202
216
  return acc;
203
217
  }, {});
204
218
  }
205
219
  const Form = (0, react_2.forwardRef)(function (_a, ref) {
206
- var { formState, dispatch, initialValue = constants_1.EMPTY_OBJECT, children, style, className, enabled = true, cancelLabel = exports.defaultProps.cancelLabel, saveLabel = exports.defaultProps.saveLabel, saveInProgressLabel = exports.defaultProps.saveInProgressLabel, swapCancelAndSave, onWillSubmit, onSubmit, onCancel, onReset, onSuccess, buttonRow, id, registerComponentApi, itemLabelBreak = exports.defaultProps.itemLabelBreak, itemLabelWidth, itemLabelPosition = exports.defaultProps.itemLabelPosition, keepModalOpenOnSubmit = exports.defaultProps.keepModalOpenOnSubmit, hideButtonRowUntilDirty } = _a, rest = __rest(_a, ["formState", "dispatch", "initialValue", "children", "style", "className", "enabled", "cancelLabel", "saveLabel", "saveInProgressLabel", "swapCancelAndSave", "onWillSubmit", "onSubmit", "onCancel", "onReset", "onSuccess", "buttonRow", "id", "registerComponentApi", "itemLabelBreak", "itemLabelWidth", "itemLabelPosition", "keepModalOpenOnSubmit", "hideButtonRowUntilDirty"]);
220
+ var { formState, dispatch, initialValue = constants_1.EMPTY_OBJECT, children, style, className, enabled = true, cancelLabel = exports.defaultProps.cancelLabel, saveLabel = exports.defaultProps.saveLabel, saveInProgressLabel = exports.defaultProps.saveInProgressLabel, swapCancelAndSave, onWillSubmit, onSubmit, onCancel, onReset, onSuccess, buttonRow, id, registerComponentApi, itemLabelBreak = exports.defaultProps.itemLabelBreak, itemLabelWidth, itemLabelPosition = exports.defaultProps.itemLabelPosition, keepModalOpenOnSubmit = exports.defaultProps.keepModalOpenOnSubmit, hideButtonRowUntilDirty, hideButtonRow = exports.defaultProps.hideButtonRow, enableSubmit = exports.defaultProps.enableSubmit } = _a, rest = __rest(_a, ["formState", "dispatch", "initialValue", "children", "style", "className", "enabled", "cancelLabel", "saveLabel", "saveInProgressLabel", "swapCancelAndSave", "onWillSubmit", "onSubmit", "onCancel", "onReset", "onSuccess", "buttonRow", "id", "registerComponentApi", "itemLabelBreak", "itemLabelWidth", "itemLabelPosition", "keepModalOpenOnSubmit", "hideButtonRowUntilDirty", "hideButtonRow", "enableSubmit"]);
207
221
  const formRef = (0, react_2.useRef)(null);
208
222
  const [confirmSubmitModalVisible, setConfirmSubmitModalVisible] = (0, react_2.useState)(false);
209
223
  const requestModalFormClose = (0, ModalVisibilityContext_1.useModalFormClose)();
@@ -243,6 +257,22 @@ const Form = (0, react_2.forwardRef)(function (_a, ref) {
243
257
  onCancel === null || onCancel === void 0 ? void 0 : onCancel();
244
258
  void requestModalFormClose();
245
259
  });
260
+ const doValidate = (0, misc_1.useEvent)(() => __awaiter(this, void 0, void 0, function* () {
261
+ // Trigger validation display on all fields
262
+ dispatch((0, formActions_1.triedToSubmit)());
263
+ // Get validation results grouped by severity
264
+ const { error, warning } = (0, Validations_1.groupInvalidValidationResultsBySeverity)(Object.values(formState.validationResults));
265
+ // Prepare cleaned data
266
+ const cleanedData = cleanUpSubject(formState.subject, formState.noSubmitFields);
267
+ // Return validation result
268
+ return {
269
+ isValid: error.length === 0,
270
+ data: cleanedData,
271
+ errors: error,
272
+ warnings: warning,
273
+ validationResults: formState.validationResults,
274
+ };
275
+ }));
246
276
  const doSubmit = (0, misc_1.useEvent)((event) => __awaiter(this, void 0, void 0, function* () {
247
277
  var _a;
248
278
  /* console.log(`🚀 Form submit started`);
@@ -258,19 +288,19 @@ const Form = (0, react_2.forwardRef)(function (_a, ref) {
258
288
  return;
259
289
  }
260
290
  setConfirmSubmitModalVisible(false);
261
- dispatch((0, formActions_1.triedToSubmit)());
262
- const { error, warning } = (0, Validations_1.groupInvalidValidationResultsBySeverity)(Object.values(formState.validationResults));
263
- if (error.length) {
291
+ // Use the extracted validation logic
292
+ const validationResult = yield doValidate();
293
+ if (!validationResult.isValid) {
264
294
  return;
265
295
  }
266
- if (warning.length && !confirmSubmitModalVisible) {
296
+ if (validationResult.warnings.length > 0 && !confirmSubmitModalVisible) {
267
297
  setConfirmSubmitModalVisible(true);
268
298
  return;
269
299
  }
270
300
  const prevFocused = document.activeElement;
271
301
  dispatch((0, formActions_1.formSubmitting)());
272
302
  try {
273
- const filteredSubject = cleanUpSubject(formState.subject);
303
+ const filteredSubject = validationResult.data;
274
304
  const canSubmit = yield (onWillSubmit === null || onWillSubmit === void 0 ? void 0 : onWillSubmit(filteredSubject));
275
305
  if (canSubmit === false) {
276
306
  // --- We do not reset the form but allow the next submit.
@@ -352,18 +382,19 @@ const Form = (0, react_2.forwardRef)(function (_a, ref) {
352
382
  });
353
383
  });
354
384
  const cancelButton = cancelLabel === "" ? null : ((0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-part-id": PART_CANCEL_BUTTON, type: "button", themeColor: "secondary", variant: "ghost", onClick: doCancel, children: cancelLabel }, "cancel"));
355
- const submitButton = (0, react_2.useMemo)(() => ((0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-part-id": PART_SUBMIT_BUTTON, type: "submit", disabled: !isEnabled, children: formState.submitInProgress ? saveInProgressLabel : saveLabel }, "submit")), [isEnabled, formState.submitInProgress, saveInProgressLabel, saveLabel]);
385
+ const submitButton = (0, react_2.useMemo)(() => ((0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-part-id": PART_SUBMIT_BUTTON, type: "submit", disabled: !isEnabled || !enableSubmit, children: formState.submitInProgress ? saveInProgressLabel : saveLabel }, "submit")), [isEnabled, enableSubmit, formState.submitInProgress, saveInProgressLabel, saveLabel]);
356
386
  (0, react_2.useEffect)(() => {
357
387
  registerComponentApi === null || registerComponentApi === void 0 ? void 0 : registerComponentApi({
358
388
  reset: doReset,
359
389
  update: updateData,
390
+ validate: doValidate,
360
391
  });
361
- }, [doReset, updateData, registerComponentApi]);
392
+ }, [doReset, updateData, doValidate, registerComponentApi]);
362
393
  let safeButtonRow = ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: buttonRow || ((0, jsx_runtime_1.jsxs)("div", { className: Form_module_scss_1.default.buttonRow, children: [swapCancelAndSave && [submitButton, cancelButton], !swapCancelAndSave && [cancelButton, submitButton]] })) }));
363
394
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, react_1.createElement)("form", Object.assign({}, rest, { style: style, className: (0, classnames_1.default)(Form_module_scss_1.default.wrapper, className), onSubmit: doSubmit, onReset: doReset, id: id, key: formState.resetVersion, ref: formRef }),
364
395
  (0, jsx_runtime_1.jsx)(ValidationSummary_1.ValidationSummary, { generalValidationResults: formState.generalValidationResults }),
365
396
  (0, jsx_runtime_1.jsx)(FormContext_1.FormContext.Provider, { value: formContextValue, children: children }),
366
- (!hideButtonRowUntilDirty || isDirty) && safeButtonRow), confirmSubmitModalVisible && ((0, jsx_runtime_1.jsx)(ModalDialogNative_1.ModalDialog, { onClose: () => setConfirmSubmitModalVisible(false), isInitiallyOpen: true, title: "Are you sure want to move forward?", children: (0, jsx_runtime_1.jsxs)(StackNative_1.Stack, { orientation: "vertical", style: { gap: "0.5rem" }, children: [(0, jsx_runtime_1.jsx)(TextNative_1.Text, { children: "The following warnings were found during validation. Please make sure you are willing to move forward despite these issues." }), (0, jsx_runtime_1.jsx)(ValidationSummary_1.ValidationSummary, { generalValidationResults: formState.generalValidationResults, fieldValidationResults: formState.validationResults }), (0, jsx_runtime_1.jsxs)(StackNative_1.Stack, { orientation: "horizontal", horizontalAlignment: "end", style: { gap: "1em" }, children: [(0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { variant: "ghost", themeColor: "secondary", onClick: () => setConfirmSubmitModalVisible(false), children: "No" }), (0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { onClick: () => doSubmit(), autoFocus: true, children: "Yes, proceed" })] })] }) }))] }));
397
+ !hideButtonRow && (!hideButtonRowUntilDirty || isDirty) && safeButtonRow), confirmSubmitModalVisible && ((0, jsx_runtime_1.jsx)(ModalDialogNative_1.ModalDialog, { onClose: () => setConfirmSubmitModalVisible(false), isInitiallyOpen: true, title: "Are you sure want to move forward?", children: (0, jsx_runtime_1.jsxs)(StackNative_1.Stack, { orientation: "vertical", style: { gap: "0.5rem" }, children: [(0, jsx_runtime_1.jsx)(TextNative_1.Text, { children: "The following warnings were found during validation. Please make sure you are willing to move forward despite these issues." }), (0, jsx_runtime_1.jsx)(ValidationSummary_1.ValidationSummary, { generalValidationResults: formState.generalValidationResults, fieldValidationResults: formState.validationResults }), (0, jsx_runtime_1.jsxs)(StackNative_1.Stack, { orientation: "horizontal", horizontalAlignment: "end", style: { gap: "1em" }, children: [(0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { variant: "ghost", themeColor: "secondary", onClick: () => setConfirmSubmitModalVisible(false), children: "No" }), (0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { onClick: () => doSubmit(), autoFocus: true, children: "Yes, proceed" })] })] }) }))] }));
367
398
  });
368
399
  Form.displayName = "Form";
369
400
  exports.FormWithContextVar = (0, react_2.forwardRef)(function ({ node, renderChild, extractValue, style, className, lookupEventHandler, registerComponentApi, }, ref) {
@@ -383,8 +414,8 @@ exports.FormWithContextVar = (0, react_2.forwardRef)(function ({ node, renderChi
383
414
  });
384
415
  });
385
416
  };
386
- return Object.assign(Object.assign({}, cleanUpSubject(formState.subject)), { update: updateData });
387
- }, [formState.subject]);
417
+ return Object.assign(Object.assign({}, cleanUpSubject(formState.subject, formState.noSubmitFields)), { update: updateData });
418
+ }, [formState.subject, formState.noSubmitFields]);
388
419
  const nodeWithItem = (0, react_2.useMemo)(() => {
389
420
  return {
390
421
  type: "Fragment",
@@ -403,7 +434,7 @@ exports.FormWithContextVar = (0, react_2.forwardRef)(function ({ node, renderChi
403
434
  extractValue.asOptionalString(node.props._data_url);
404
435
  const itemLabelWidth = extractValue.asOptionalString(node.props.itemLabelWidth);
405
436
  const { cssProps: itemLabelWidthCssProps } = (0, layout_resolver_1.resolveLayoutProps)({ width: itemLabelWidth });
406
- return ((0, jsx_runtime_1.jsx)(react_slot_1.Slot, { ref: ref, style: style, children: (0, jsx_runtime_1.jsx)(Form, { keepModalOpenOnSubmit: extractValue.asOptionalBoolean(node.props.keepModalOpenOnSubmit), itemLabelPosition: extractValue.asOptionalString(node.props.itemLabelPosition), itemLabelBreak: extractValue.asOptionalBoolean(node.props.itemLabelBreak), itemLabelWidth: itemLabelWidthCssProps.width, hideButtonRowUntilDirty: extractValue.asOptionalBoolean(node.props.hideButtonRowUntilDirty), formState: formState, dispatch: dispatch, id: node.uid, className: className, cancelLabel: extractValue(node.props.cancelLabel), saveLabel: extractValue(node.props.saveLabel), saveInProgressLabel: extractValue(node.props.saveInProgressLabel), swapCancelAndSave: extractValue.asOptionalBoolean(node.props.swapCancelAndSave, false), onWillSubmit: lookupEventHandler("willSubmit", {
437
+ return ((0, jsx_runtime_1.jsx)(react_slot_1.Slot, { ref: ref, style: style, children: (0, jsx_runtime_1.jsx)(Form, { keepModalOpenOnSubmit: extractValue.asOptionalBoolean(node.props.keepModalOpenOnSubmit), itemLabelPosition: extractValue.asOptionalString(node.props.itemLabelPosition), itemLabelBreak: extractValue.asOptionalBoolean(node.props.itemLabelBreak), itemLabelWidth: itemLabelWidthCssProps.width, hideButtonRowUntilDirty: extractValue.asOptionalBoolean(node.props.hideButtonRowUntilDirty), hideButtonRow: extractValue.asOptionalBoolean(node.props.hideButtonRow), enableSubmit: extractValue.asOptionalBoolean(node.props.enableSubmit), formState: formState, dispatch: dispatch, id: node.uid, className: className, cancelLabel: extractValue(node.props.cancelLabel), saveLabel: extractValue(node.props.saveLabel), saveInProgressLabel: extractValue(node.props.saveInProgressLabel), swapCancelAndSave: extractValue.asOptionalBoolean(node.props.swapCancelAndSave, false), onWillSubmit: lookupEventHandler("willSubmit", {
407
438
  context: {
408
439
  $data,
409
440
  },
@@ -27,13 +27,14 @@ var FormActionKind;
27
27
  FormActionKind["SUBMITTED"] = "FormActionKind:SUBMITTED";
28
28
  FormActionKind["RESET"] = "FormActionKind:RESET";
29
29
  })(FormActionKind || (exports.FormActionKind = FormActionKind = {}));
30
- function fieldInitialized(uid, value, force = false) {
30
+ function fieldInitialized(uid, value, force = false, noSubmit = false) {
31
31
  return {
32
32
  type: FormActionKind.FIELD_INITIALIZED,
33
33
  payload: {
34
34
  uid,
35
35
  value,
36
- force
36
+ force,
37
+ noSubmit
37
38
  },
38
39
  };
39
40
  }