From 0fa222c21b8361ebf0396791d06ef7f39228944c Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Wed, 7 Apr 2021 17:25:00 +0200 Subject: [PATCH 1/2] chore(form-integrations): test all registrations --- .../test/dialog-integrations.js | 20 ----- .../test/dialog-integrations.test.js | 86 +++++++++++++++++++ .../test/form-integrations.test.js | 71 +++++++++++++++ 3 files changed, 157 insertions(+), 20 deletions(-) delete mode 100644 packages/form-integrations/test/dialog-integrations.js create mode 100644 packages/form-integrations/test/dialog-integrations.test.js diff --git a/packages/form-integrations/test/dialog-integrations.js b/packages/form-integrations/test/dialog-integrations.js deleted file mode 100644 index e661f544b..000000000 --- a/packages/form-integrations/test/dialog-integrations.js +++ /dev/null @@ -1,20 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import './helpers/umbrella-form.js'; -import '@lion/dialog/lion-dialog.js'; - -/** - * @typedef {import('./helpers/umbrella-form.js').UmbrellaForm} UmbrellaForm - * @typedef {import('@lion/dialog/').LionDialog} LionDialog - */ - -// Test umbrella form inside dialog -describe('Form inside dialog Integrations', () => { - it('"Successfully spawns all form components inside a dialog', async () => { - expect( - await fixture(html` - - - `), - ).to.not.throw(); - }); -}); diff --git a/packages/form-integrations/test/dialog-integrations.test.js b/packages/form-integrations/test/dialog-integrations.test.js new file mode 100644 index 000000000..3297c2428 --- /dev/null +++ b/packages/form-integrations/test/dialog-integrations.test.js @@ -0,0 +1,86 @@ +import { expect, fixture, html } from '@open-wc/testing'; +import './helpers/umbrella-form.js'; +import '@lion/dialog/define'; + +/** + * @typedef {import('./helpers/umbrella-form.js').UmbrellaForm} UmbrellaForm + * @typedef {import('@lion/dialog').LionDialog} LionDialog + * @typedef {import('@lion/form').LionForm} LionForm + */ + +// Test umbrella form inside dialog +describe('Form inside dialog Integrations', () => { + it('"Successfully registers all form components inside a dialog', async () => { + const el = /** @type {LionDialog} */ await fixture(html` + + + `); + + // @ts-ignore + const formEl = /** @type {LionForm} */ (el._overlayCtrl.contentNode._lionFormNode); + const getTagNames = (/** @type {HTMLElement} */ elm) => [ + elm.tagName.toLowerCase(), + // @ts-ignore + ...(elm.formElements ? elm.formElements.map(getTagNames).flat() : []), + ]; + + // @ts-ignore + const registeredEls = formEl.formElements.map(getTagNames).flat(); + + // TODO: fix registration of lion-switch and lion-input-stepper + expect(registeredEls).to.eql([ + 'lion-fieldset', + 'lion-input', + 'lion-input', + + 'lion-input-date', + + 'lion-input-datepicker', + + 'lion-textarea', + + 'lion-input-amount', + + 'lion-input-iban', + + 'lion-input-email', + + 'lion-checkbox-group', + 'lion-checkbox', + 'lion-checkbox', + 'lion-checkbox', + + 'lion-radio-group', + 'lion-radio', + 'lion-radio', + 'lion-radio', + + 'lion-listbox', + 'lion-option', + 'lion-option', + 'lion-option', + + 'lion-combobox', + 'lion-option', + 'lion-option', + 'lion-option', + 'lion-option', + 'lion-option', + 'lion-option', + + 'lion-select-rich', + 'lion-option', + 'lion-option', + 'lion-option', + 'lion-select', + + 'lion-input-range', + + 'lion-checkbox-group', + 'lion-checkbox', + // 'lion-switch', + // 'lion-input-stepper', + 'lion-textarea', + ]); + }); +}); diff --git a/packages/form-integrations/test/form-integrations.test.js b/packages/form-integrations/test/form-integrations.test.js index 2780cdb21..354dd5eac 100644 --- a/packages/form-integrations/test/form-integrations.test.js +++ b/packages/form-integrations/test/form-integrations.test.js @@ -85,4 +85,75 @@ describe('Form Integrations', () => { expect(el._lionFormNode.dirty).to.be.false; }); }); + + it('"Successfully registers all form components', async () => { + const el = /** @type {UmbrellaForm} */ await fixture(html``); + + // @ts-ignore + const formEl = /** @type {LionForm} */ (el._lionFormNode); + const getTagNames = (/** @type {HTMLElement} */ elm) => [ + elm.tagName.toLowerCase(), + // @ts-ignore + ...(elm.formElements ? elm.formElements.map(getTagNames).flat() : []), + ]; + + // @ts-ignore + const registeredEls = formEl.formElements.map(getTagNames).flat(); + + // TODO: fix registration of lion-switch and lion-input-stepper + expect(registeredEls).to.eql([ + 'lion-fieldset', + 'lion-input', + 'lion-input', + + 'lion-input-date', + + 'lion-input-datepicker', + + 'lion-textarea', + + 'lion-input-amount', + + 'lion-input-iban', + + 'lion-input-email', + + 'lion-checkbox-group', + 'lion-checkbox', + 'lion-checkbox', + 'lion-checkbox', + + 'lion-radio-group', + 'lion-radio', + 'lion-radio', + 'lion-radio', + + 'lion-listbox', + 'lion-option', + 'lion-option', + 'lion-option', + + 'lion-combobox', + 'lion-option', + 'lion-option', + 'lion-option', + 'lion-option', + 'lion-option', + 'lion-option', + + 'lion-select-rich', + 'lion-option', + 'lion-option', + 'lion-option', + 'lion-select', + + 'lion-input-range', + + 'lion-checkbox-group', + 'lion-checkbox', + // 'lion-switch', + // 'lion-input-stepper', + 'lion-textarea', + ]); + }); }); From 6ae7a5e352dbfb4210d5c248e58e3fdfdf8deca5 Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Thu, 8 Apr 2021 09:57:15 +0200 Subject: [PATCH 2/2] fix(form-core): add clear() to choice-group; test integratoons --- .changeset/thirty-eagles-prove.md | 6 + .../src/choice-group/ChoiceGroupMixin.js | 8 + .../choice-group/ChoiceGroupMixin.suite.js | 17 ++ .../choice-group/ChoiceGroupMixinTypes.d.ts | 2 + .../test/dialog-integrations.test.js | 81 ++++----- .../test/form-group-methods.test.js | 161 ++++++++++++++++++ .../test/form-integrations.test.js | 79 ++++----- .../form-integrations/test/form-reset.test.js | 143 ---------------- .../form-integrations/test/helpers/helpers.js | 40 +++++ .../test/helpers/umbrella-form.js | 16 +- .../test/model-value-consistency.test.js | 5 + 11 files changed, 316 insertions(+), 242 deletions(-) create mode 100644 .changeset/thirty-eagles-prove.md create mode 100644 packages/form-integrations/test/form-group-methods.test.js delete mode 100644 packages/form-integrations/test/form-reset.test.js create mode 100644 packages/form-integrations/test/helpers/helpers.js diff --git a/.changeset/thirty-eagles-prove.md b/.changeset/thirty-eagles-prove.md new file mode 100644 index 000000000..782599177 --- /dev/null +++ b/.changeset/thirty-eagles-prove.md @@ -0,0 +1,6 @@ +--- +'@lion/form-core': patch +'@lion/form-integrations': patch +--- + +Add `clear()` interface to choiceGroups diff --git a/packages/form-core/src/choice-group/ChoiceGroupMixin.js b/packages/form-core/src/choice-group/ChoiceGroupMixin.js index 9b8774137..a0bcd03ea 100644 --- a/packages/form-core/src/choice-group/ChoiceGroupMixin.js +++ b/packages/form-core/src/choice-group/ChoiceGroupMixin.js @@ -187,6 +187,14 @@ const ChoiceGroupMixinImplementation = superclass => super.addFormElement(child, indexToInsertAt); } + clear() { + if (this.multipleChoice) { + this.modelValue = []; + } else { + this.modelValue = ''; + } + } + /** * @override from FormControlMixin * @protected diff --git a/packages/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.js b/packages/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.js index 8d6cb2533..9ae787d41 100644 --- a/packages/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.js +++ b/packages/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.js @@ -507,6 +507,23 @@ export function runChoiceGroupMixinSuite({ parentTagString, childTagString, choi } }); + it('can be cleared', async () => { + const el = /** @type {ChoiceInputGroup} */ (await fixture(html` + <${parentTag} name="gender[]"> + <${childTag} .choiceValue=${'male'}> + <${childTag} .choiceValue=${'female'}> + + `)); + el.formElements[0].checked = true; + el.clear(); + + if (cfg.choiceType === 'single') { + expect(el.serializedValue).to.deep.equal(''); + } else { + expect(el.serializedValue).to.deep.equal([]); + } + }); + describe('multipleChoice', () => { it('has a single modelValue representing all currently checked values', async () => { const el = /** @type {ChoiceInputGroup} */ (await fixture(html` diff --git a/packages/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts b/packages/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts index 4808f3d06..54c0c3ee1 100644 --- a/packages/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts +++ b/packages/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts @@ -28,6 +28,8 @@ export declare class ChoiceGroupHost { addFormElement(child: FormControlHost, indexToInsertAt: number): void; + clear(): void; + protected _triggerInitialModelValueChangedEvent(): void; _getFromAllFormElements(property: string, filterCondition: Function): void; diff --git a/packages/form-integrations/test/dialog-integrations.test.js b/packages/form-integrations/test/dialog-integrations.test.js index 3297c2428..a46106082 100644 --- a/packages/form-integrations/test/dialog-integrations.test.js +++ b/packages/form-integrations/test/dialog-integrations.test.js @@ -1,4 +1,5 @@ import { expect, fixture, html } from '@open-wc/testing'; +import { getAllTagNames } from './helpers/helpers.js'; import './helpers/umbrella-form.js'; import '@lion/dialog/define'; @@ -10,7 +11,7 @@ import '@lion/dialog/define'; // Test umbrella form inside dialog describe('Form inside dialog Integrations', () => { - it('"Successfully registers all form components inside a dialog', async () => { + it('Successfully registers all form components inside a dialog', async () => { const el = /** @type {LionDialog} */ await fixture(html` @@ -18,68 +19,54 @@ describe('Form inside dialog Integrations', () => { // @ts-ignore const formEl = /** @type {LionForm} */ (el._overlayCtrl.contentNode._lionFormNode); - const getTagNames = (/** @type {HTMLElement} */ elm) => [ - elm.tagName.toLowerCase(), - // @ts-ignore - ...(elm.formElements ? elm.formElements.map(getTagNames).flat() : []), - ]; + await formEl.registrationComplete; + const registeredEls = getAllTagNames(formEl); - // @ts-ignore - const registeredEls = formEl.formElements.map(getTagNames).flat(); - - // TODO: fix registration of lion-switch and lion-input-stepper expect(registeredEls).to.eql([ + // [1] In a dialog, these are registered before the rest (which is in chronological dom order) + // Ideally, this should be the same. It would be once the platform allows to create dialogs + // that don't need to move content to the body + 'lion-checkbox-group', + ' lion-checkbox', + 'lion-switch', + // [2] 'the rest' (chronologically ordered registrations) 'lion-fieldset', - 'lion-input', - 'lion-input', - + ' lion-input', + ' lion-input', 'lion-input-date', - 'lion-input-datepicker', - 'lion-textarea', - 'lion-input-amount', - 'lion-input-iban', - 'lion-input-email', - 'lion-checkbox-group', - 'lion-checkbox', - 'lion-checkbox', - 'lion-checkbox', - + ' lion-checkbox', + ' lion-checkbox', + ' lion-checkbox', 'lion-radio-group', - 'lion-radio', - 'lion-radio', - 'lion-radio', - + ' lion-radio', + ' lion-radio', + ' lion-radio', 'lion-listbox', - 'lion-option', - 'lion-option', - 'lion-option', - + ' lion-option', + ' lion-option', + ' lion-option', 'lion-combobox', - 'lion-option', - 'lion-option', - 'lion-option', - 'lion-option', - 'lion-option', - 'lion-option', - + ' lion-option', + ' lion-option', + ' lion-option', + ' lion-option', + ' lion-option', + ' lion-option', 'lion-select-rich', - 'lion-option', - 'lion-option', - 'lion-option', + ' lion-option', + ' lion-option', + ' lion-option', 'lion-select', - 'lion-input-range', - - 'lion-checkbox-group', - 'lion-checkbox', - // 'lion-switch', - // 'lion-input-stepper', + // [3] this is where [1] should have been inserted + // [4] more of 'the rest' (chronologically ordered registrations) + 'lion-input-stepper', 'lion-textarea', ]); }); diff --git a/packages/form-integrations/test/form-group-methods.test.js b/packages/form-integrations/test/form-group-methods.test.js new file mode 100644 index 000000000..86020e0af --- /dev/null +++ b/packages/form-integrations/test/form-group-methods.test.js @@ -0,0 +1,161 @@ +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; +import './helpers/umbrella-form.js'; +import { getAllFieldsAndFormGroups } from './helpers/helpers.js'; + +/** + * @typedef {import('@lion/form-core').LionField} LionField + * @typedef {import('@lion/button').LionButton} LionButton + * @typedef {import('./helpers/umbrella-form.js').UmbrellaForm} UmbrellaForm + */ + +const fullyPrefilledSerializedValue = { + full_name: { first_name: 'Lorem', last_name: 'Ipsum' }, + date: '2000-12-12', + datepicker: '2020-12-12', + bio: 'Lorem', + money: '12313.12', + iban: '123456', + email: 'a@b.com', + checkers: ['foo', 'bar'], + dinosaurs: 'brontosaurus', + favoriteFruit: 'Banana', + favoriteMovie: 'Rocky', + favoriteColor: 'hotpink', + lyrics: '1', + notifications: { + checked: true, + value: 'Lorem', + }, + range: 2.3, + rsvp: 'Lorem', + terms: ['agreed'], + comments: 'Lorem', +}; + +const fullyChangedSerializedValue = { + full_name: { first_name: 'LoremChanged', last_name: 'IpsumChanged' }, + date: '1999-12-12', + datepicker: '1986-12-12', + bio: 'LoremChanged', + money: '9912313.12', + iban: '99123456', + email: 'aChanged@b.com', + checkers: ['foo'], + dinosaurs: '', + favoriteFruit: '', + favoriteMovie: '', + favoriteColor: '', + lyrics: '2', + notifications: { + checked: false, + value: 'Lorem', + }, + range: 3.3, + rsvp: 'LoremChanged', + terms: [], + comments: 'LoremChanged', +}; + +describe(`Submitting/Resetting/Clearing Form`, async () => { + it('pressing submit button of a form should make submitted true for all fields', async () => { + const el = /** @type {UmbrellaForm} */ (await fixture(html``)); + await el.updateComplete; + const formEl = el._lionFormNode; + + const allElements = getAllFieldsAndFormGroups(formEl); + + allElements.forEach((/** @type {LionField} */ field) => { + if (field.tagName === 'LION-SWITCH') { + // TODO: remove this when this is fixed: https://github.com/ing-bank/lion/issues/1204 + return; + } + // TODO: prefer submitted 'false' over 'undefined' + expect(Boolean(field.submitted)).to.be.false; + }); + /** @type {LionButton} */ (formEl.querySelector('#submit_button')).click(); + await elementUpdated(formEl); + await el.updateComplete; + allElements.forEach((/** @type {LionField} */ field) => { + expect(field.submitted).to.be.true; + }); + }); + + it('calling resetGroup() should reset all metadata (interaction states and initial values)', async () => { + const el = /** @type {UmbrellaForm} */ (await fixture( + html``, + )); + await el.updateComplete; + const formEl = el._lionFormNode; + + /** @type {LionButton} */ (formEl.querySelector('#submit_button')).click(); + await elementUpdated(formEl); + await formEl.updateComplete; + + const allElements = getAllFieldsAndFormGroups(formEl); + + allElements.forEach((/** @type {LionField} */ field) => { + // eslint-disable-next-line no-param-reassign + field.touched = true; + // eslint-disable-next-line no-param-reassign + field.dirty = true; + }); + + formEl.serializedValue = fullyChangedSerializedValue; + + allElements.forEach((/** @type {LionField} */ field) => { + expect(field.submitted).to.be.true; + expect(field.touched).to.be.true; + expect(field.dirty).to.be.true; + }); + + /** @type {LionButton} */ (formEl.querySelector('#reset_button')).click(); + await elementUpdated(formEl); + await formEl.updateComplete; + expect(formEl.submitted).to.be.false; + + allElements.forEach((/** @type {LionField} */ field) => { + expect(field.submitted).to.be.false; + expect(field.touched).to.be.false; + expect(field.dirty).to.be.false; + }); + + // TODO: investigate why this doesn't work + // expect(formEl.serializedValue).to.eql(fullyPrefilledSerializedValue); + }); + + // Wait till ListboxMixin properly clears + it('calling clearGroup() should clear all fields', async () => { + const el = /** @type {UmbrellaForm} */ (await fixture( + html``, + )); + await el.updateComplete; + const formEl = el._lionFormNode; + + formEl.clearGroup(); + await elementUpdated(formEl); + await formEl.updateComplete; + expect(formEl.serializedValue).to.eql({ + full_name: { first_name: '', last_name: '' }, + date: '', + datepicker: '', + bio: '', + money: '', + iban: '', + email: '', + checkers: [], + dinosaurs: '', + favoriteFruit: '', + favoriteMovie: '', + favoriteColor: '', + lyrics: '', + notifications: { + checked: false, + value: 'Lorem', + }, + range: '', + rsvp: '', + terms: [], + comments: '', + }); + }); +}); diff --git a/packages/form-integrations/test/form-integrations.test.js b/packages/form-integrations/test/form-integrations.test.js index 354dd5eac..bce4aa2b0 100644 --- a/packages/form-integrations/test/form-integrations.test.js +++ b/packages/form-integrations/test/form-integrations.test.js @@ -1,4 +1,5 @@ import { expect, fixture, html } from '@open-wc/testing'; +import { getAllTagNames } from './helpers/helpers.js'; import './helpers/umbrella-form.js'; /** @@ -28,6 +29,8 @@ describe('Form Integrations', () => { lyrics: '1', range: 2.3, terms: [], + notifications: { value: '', checked: false }, + rsvp: '', comments: '', }); }); @@ -36,6 +39,7 @@ describe('Form Integrations', () => { const el = /** @type {UmbrellaForm} */ (await fixture(html``)); await el.updateComplete; const formEl = el._lionFormNode; + expect(formEl.formattedValue).to.eql({ full_name: { first_name: '', last_name: '' }, date: '12/12/2000', @@ -52,6 +56,8 @@ describe('Form Integrations', () => { lyrics: '1', range: 2.3, terms: [], + notifications: '', + rsvp: '', comments: '', }); }); @@ -86,73 +92,52 @@ describe('Form Integrations', () => { }); }); - it('"Successfully registers all form components', async () => { + it('Successfully registers all form components', async () => { const el = /** @type {UmbrellaForm} */ await fixture(html``); - // @ts-ignore const formEl = /** @type {LionForm} */ (el._lionFormNode); - const getTagNames = (/** @type {HTMLElement} */ elm) => [ - elm.tagName.toLowerCase(), - // @ts-ignore - ...(elm.formElements ? elm.formElements.map(getTagNames).flat() : []), - ]; + await formEl.registrationComplete; + const registeredEls = getAllTagNames(formEl); - // @ts-ignore - const registeredEls = formEl.formElements.map(getTagNames).flat(); - - // TODO: fix registration of lion-switch and lion-input-stepper expect(registeredEls).to.eql([ 'lion-fieldset', - 'lion-input', - 'lion-input', - + ' lion-input', + ' lion-input', 'lion-input-date', - 'lion-input-datepicker', - 'lion-textarea', - 'lion-input-amount', - 'lion-input-iban', - 'lion-input-email', - 'lion-checkbox-group', - 'lion-checkbox', - 'lion-checkbox', - 'lion-checkbox', - + ' lion-checkbox', + ' lion-checkbox', + ' lion-checkbox', 'lion-radio-group', - 'lion-radio', - 'lion-radio', - 'lion-radio', - + ' lion-radio', + ' lion-radio', + ' lion-radio', 'lion-listbox', - 'lion-option', - 'lion-option', - 'lion-option', - + ' lion-option', + ' lion-option', + ' lion-option', 'lion-combobox', - 'lion-option', - 'lion-option', - 'lion-option', - 'lion-option', - 'lion-option', - 'lion-option', - + ' lion-option', + ' lion-option', + ' lion-option', + ' lion-option', + ' lion-option', + ' lion-option', 'lion-select-rich', - 'lion-option', - 'lion-option', - 'lion-option', + ' lion-option', + ' lion-option', + ' lion-option', 'lion-select', - 'lion-input-range', - 'lion-checkbox-group', - 'lion-checkbox', - // 'lion-switch', - // 'lion-input-stepper', + ' lion-checkbox', + 'lion-switch', + 'lion-input-stepper', 'lion-textarea', ]); }); diff --git a/packages/form-integrations/test/form-reset.test.js b/packages/form-integrations/test/form-reset.test.js deleted file mode 100644 index 59f48b3f7..000000000 --- a/packages/form-integrations/test/form-reset.test.js +++ /dev/null @@ -1,143 +0,0 @@ -import '@lion/button/define'; -import '@lion/checkbox-group/define'; -import { MinLength, Required } from '@lion/form-core'; -import '@lion/form/define'; -import '@lion/input-amount/define'; -import '@lion/input-date/define'; -import '@lion/input-datepicker/define'; -import '@lion/input-email/define'; -import '@lion/input-iban/define'; -import '@lion/input-range/define'; -import '@lion/input/define'; -import '@lion/radio-group/define'; -import '@lion/select/define'; -import '@lion/switch/define'; -import '@lion/textarea/define'; -import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; - -describe(`Submitting/Resetting Form`, async () => { - /** @type {import('@lion/form').LionForm} */ - let el; - beforeEach(async () => { - el = await fixture(html` - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- Submit - Reset -
-
-
- `); - }); - - it('Submitting a form should make submitted true for all fields', async () => { - /** @type {import('@lion/button').LionButton} */ (el.querySelector('#submit_button')).click(); - await elementUpdated(el); - await el.updateComplete; - el.formElements.forEach(field => { - expect(field.submitted).to.be.true; - }); - }); - - it('Resetting a form should reset metadata of all fields', async () => { - /** @type {import('@lion/button').LionButton} */ (el.querySelector('#submit_button')).click(); - /** @type {import('@lion/button').LionButton} */ (el.querySelector('#reset_button')).click(); - await elementUpdated(el); - await el.updateComplete; - expect(el.submitted).to.be.false; - el.formElements.forEach(field => { - expect(field.submitted).to.be.false; - expect(field.touched).to.be.false; - expect(field.dirty).to.be.false; - }); - }); -}); diff --git a/packages/form-integrations/test/helpers/helpers.js b/packages/form-integrations/test/helpers/helpers.js new file mode 100644 index 000000000..28999d156 --- /dev/null +++ b/packages/form-integrations/test/helpers/helpers.js @@ -0,0 +1,40 @@ +/** + * @typedef {import('@lion/form').LionForm} LionForm + * @typedef {import('@lion/form-core').LionField} LionField + */ + +/** + * @param {LionForm} formGroupEl + */ +export function getAllFormElements(formGroupEl) { + const getElms = (/** @type {HTMLElement} */ elm) => [ + elm, + // @ts-ignore + ...(elm.formElements ? elm.formElements.map(getElms).flat() : []), + ]; + + // @ts-ignore + return formGroupEl.formElements.map(elem => getElms(elem)).flat(); +} + +/** + * @param {LionForm} formGroupEl + */ +export function getAllTagNames(formGroupEl) { + const getTagNames = (/** @type {HTMLElement} */ elm, lvl = 0) => [ + ` `.repeat(lvl) + elm.tagName.toLowerCase(), + // @ts-ignore + ...(elm.formElements ? elm.formElements.map(elem => getTagNames(elem, lvl + 1)).flat() : []), + ]; + + // @ts-ignore + return formGroupEl.formElements.map(elem => getTagNames(elem)).flat(); +} + +/** + * @param {LionForm} formGroupEl + */ +export function getAllFieldsAndFormGroups(formGroupEl) { + const allElements = getAllFormElements(formGroupEl); + return allElements.filter((/** @type {LionField} */ elm) => elm.tagName !== 'LION-OPTION'); +} diff --git a/packages/form-integrations/test/helpers/umbrella-form.js b/packages/form-integrations/test/helpers/umbrella-form.js index 5efc3c712..eb86d7918 100644 --- a/packages/form-integrations/test/helpers/umbrella-form.js +++ b/packages/form-integrations/test/helpers/umbrella-form.js @@ -17,6 +17,8 @@ import '@lion/combobox/define'; import '@lion/input-range/define'; import '@lion/textarea/define'; import '@lion/button/define'; +import '@lion/switch/define'; +import '@lion/input-stepper/define'; export class UmbrellaForm extends LitElement { get _lionFormNode() { @@ -131,7 +133,10 @@ export class UmbrellaForm extends LitElement { name="terms" .validators="${[new Required()]}" > - + @@ -140,13 +145,14 @@ export class UmbrellaForm extends LitElement {
- Submit + Submit - // @ts-ignore - ev.currentTarget.parentElement.parentElement.parentElement.resetGroup()} + @click="${() => { + this._lionFormNode.resetGroup(); + }}" >Reset
diff --git a/packages/form-integrations/test/model-value-consistency.test.js b/packages/form-integrations/test/model-value-consistency.test.js index 31fbce067..b335a2270 100644 --- a/packages/form-integrations/test/model-value-consistency.test.js +++ b/packages/form-integrations/test/model-value-consistency.test.js @@ -10,11 +10,14 @@ import '@lion/input-datepicker/define'; import '@lion/input-email/define'; import '@lion/input-iban/define'; import '@lion/input-range/define'; +import '@lion/input-stepper/define'; + import '@lion/textarea/define'; import '@lion/checkbox-group/define'; import '@lion/radio-group/define'; +import '@lion/switch/define'; import '@lion/select/define'; @@ -343,11 +346,13 @@ describe('detail.isTriggeredByUser', () => { 'input-email', 'input-iban', 'input-range', + 'input-stepper', 'textarea', // 1b) Choice Fields 'option', 'checkbox', 'radio', + 'switch', // 1c) Choice Group Fields 'select', 'listbox',