diff --git a/docs/fundamentals/systems/form/use-cases.md b/docs/fundamentals/systems/form/use-cases.md
index 3c985e5d2..0d8b218f1 100644
--- a/docs/fundamentals/systems/form/use-cases.md
+++ b/docs/fundamentals/systems/form/use-cases.md
@@ -7,7 +7,9 @@ For usage and installation please see the appropriate packages.
import { html } from '@mdjs/mdjs-preview';
import '@lion/ui/define/lion-button.js';
import '@lion/ui/define/lion-checkbox-group.js';
+import '@lion/ui/define/lion-checkbox.js';
import '@lion/ui/define/lion-combobox.js';
+import '@lion/ui/define/lion-option.js';
import '@lion/ui/define/lion-fieldset.js';
import '@lion/ui/define/lion-form.js';
import '@lion/ui/define/lion-input-amount.js';
@@ -15,12 +17,14 @@ import '@lion/ui/define/lion-input-date.js';
import '@lion/ui/define/lion-input-datepicker.js';
import '@lion/ui/define/lion-input-email.js';
import '@lion/ui/define/lion-input-tel.js';
+import '@lion/ui/define/lion-input-tel-dropdown.js';
import '@lion/ui/define/lion-input-iban.js';
import '@lion/ui/define/lion-input-range.js';
import '@lion/ui/define/lion-input-stepper.js';
import '@lion/ui/define/lion-input.js';
import '@lion/ui/define/lion-listbox.js';
import '@lion/ui/define/lion-radio-group.js';
+import '@lion/ui/define/lion-radio.js';
import '@lion/ui/define/lion-select.js';
import '@lion/ui/define/lion-select-rich.js';
import '@lion/ui/define/lion-switch.js';
diff --git a/docs/fundamentals/systems/overlays/assets/umbrella-form.js b/docs/fundamentals/systems/overlays/assets/umbrella-form.js
index 58d5f7e13..db35ab01c 100644
--- a/docs/fundamentals/systems/overlays/assets/umbrella-form.js
+++ b/docs/fundamentals/systems/overlays/assets/umbrella-form.js
@@ -8,15 +8,22 @@ import '@lion/ui/define/lion-input-datepicker.js';
import '@lion/ui/define/lion-input-amount.js';
import '@lion/ui/define/lion-input-iban.js';
import '@lion/ui/define/lion-input-email.js';
+import '@lion/ui/define/lion-input-tel.js';
+import '@lion/ui/define/lion-input-tel-dropdown.js';
import '@lion/ui/define/lion-checkbox-group.js';
+import '@lion/ui/define/lion-checkbox.js';
import '@lion/ui/define/lion-radio-group.js';
+import '@lion/ui/define/lion-radio.js';
import '@lion/ui/define/lion-select.js';
import '@lion/ui/define/lion-select-rich.js';
+import '@lion/ui/define/lion-listbox.js';
+import '@lion/ui/define/lion-option.js';
+import '@lion/ui/define/lion-combobox.js';
import '@lion/ui/define/lion-input-range.js';
import '@lion/ui/define/lion-textarea.js';
import '@lion/ui/define/lion-button.js';
-import '@lion/ui/define/lion-input-tel.js';
-import '@lion/ui/define/lion-input-tel-dropdown.js';
+import '@lion/ui/define/lion-switch.js';
+import '@lion/ui/define/lion-input-stepper.js';
export class UmbrellaForm extends LitElement {
get _lionFormNode() {
diff --git a/packages/ui/components/form-integrations/test/form-group-methods.test.js b/packages/ui/components/form-integrations/test/form-group-methods.test.js
index a1eb233aa..567799c7f 100644
--- a/packages/ui/components/form-integrations/test/form-group-methods.test.js
+++ b/packages/ui/components/form-integrations/test/form-group-methods.test.js
@@ -96,15 +96,13 @@ 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;
+ await el.waitForAllChildrenUpdates();
+
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;
});
@@ -122,6 +120,8 @@ describe(`Submitting/Resetting/Clearing Form`, async () => {
html``,
)
);
+ await el.waitForAllChildrenUpdates();
+
await el.updateComplete;
const formEl = el._lionFormNode;
@@ -168,6 +168,8 @@ describe(`Submitting/Resetting/Clearing Form`, async () => {
html``,
)
);
+ await el.waitForAllChildrenUpdates();
+
await el.updateComplete;
const formEl = el._lionFormNode;
diff --git a/packages/ui/components/form-integrations/test/form-integrations.test.js b/packages/ui/components/form-integrations/test/form-integrations.test.js
index 48d711ef2..6e404be84 100644
--- a/packages/ui/components/form-integrations/test/form-integrations.test.js
+++ b/packages/ui/components/form-integrations/test/form-integrations.test.js
@@ -25,6 +25,7 @@ describe('Form Integrations', () => {
it('".serializedValue" returns all non disabled fields based on form structure', async () => {
const el = /** @type {UmbrellaForm} */ (await fixture(html``));
await el.updateComplete;
+ await el.waitForAllChildrenUpdates();
const formEl = el._lionFormNode;
expect(formEl.serializedValue).to.eql({
@@ -46,7 +47,7 @@ describe('Form Integrations', () => {
notifications: { value: '', checked: false },
rsvp: '',
tel: '',
- 'tel-dropdown': '',
+ 'tel-dropdown': '+44',
comments: '',
});
});
@@ -110,6 +111,7 @@ describe('Form Integrations', () => {
>`,
)
);
+ await el.waitForAllChildrenUpdates();
await el._lionFormNode.initComplete;
expect(el._lionFormNode.dirty).to.be.false;
@@ -162,9 +164,10 @@ describe('Form Integrations', () => {
];
it('successfully registers all form components', async () => {
- const el = /** @type {UmbrellaForm} */ await fixture(html``);
- // @ts-ignore
- const formEl = /** @type {LionForm} */ (el._lionFormNode);
+ const el = /** @type {UmbrellaForm} */ (await fixture(html``));
+ await el.waitForAllChildrenUpdates();
+
+ const formEl = el._lionFormNode;
await formEl.registrationComplete;
const registeredEls = getAllTagNames(formEl);
@@ -172,8 +175,10 @@ describe('Form Integrations', () => {
});
it('successfully unregisters all form components', async () => {
- const el = /** @type {UmbrellaForm} */ await fixture(html``);
+ const el = /** @type {UmbrellaForm} */ (await fixture(html``));
const offlineContainer = document.createElement('div');
+ await el.waitForAllChildrenUpdates();
+
// @ts-ignore
const formEl = /** @type {LionForm} */ (el._lionFormNode);
await formEl.registrationComplete;
diff --git a/packages/ui/components/form-integrations/test/helpers/umbrella-form.js b/packages/ui/components/form-integrations/test/helpers/umbrella-form.js
index 2873c4c33..c8413a24d 100644
--- a/packages/ui/components/form-integrations/test/helpers/umbrella-form.js
+++ b/packages/ui/components/form-integrations/test/helpers/umbrella-form.js
@@ -11,10 +11,13 @@ import '@lion/ui/define/lion-input-email.js';
import '@lion/ui/define/lion-input-tel.js';
import '@lion/ui/define/lion-input-tel-dropdown.js';
import '@lion/ui/define/lion-checkbox-group.js';
+import '@lion/ui/define/lion-checkbox.js';
import '@lion/ui/define/lion-radio-group.js';
+import '@lion/ui/define/lion-radio.js';
import '@lion/ui/define/lion-select.js';
import '@lion/ui/define/lion-select-rich.js';
import '@lion/ui/define/lion-listbox.js';
+import '@lion/ui/define/lion-option.js';
import '@lion/ui/define/lion-combobox.js';
import '@lion/ui/define/lion-input-range.js';
import '@lion/ui/define/lion-textarea.js';
@@ -36,6 +39,13 @@ export class UmbrellaForm extends LitElement {
this.__serializedValue = v;
}
+ /**
+ * Prevents errors outside test from being thrown
+ */
+ async waitForAllChildrenUpdates() {
+ return Promise.all(this._lionFormNode.formElements.map(child => child.updateComplete));
+ }
+
render() {
return html`
diff --git a/packages/ui/components/form-integrations/test/model-value-consistency.test.js b/packages/ui/components/form-integrations/test/model-value-consistency.test.js
index dec0398bf..184e216b6 100644
--- a/packages/ui/components/form-integrations/test/model-value-consistency.test.js
+++ b/packages/ui/components/form-integrations/test/model-value-consistency.test.js
@@ -11,23 +11,19 @@ import '@lion/ui/define/lion-input-email.js';
import '@lion/ui/define/lion-input-iban.js';
import '@lion/ui/define/lion-input-range.js';
import '@lion/ui/define/lion-input-stepper.js';
-
+import '@lion/ui/define/lion-input-tel.js';
+import '@lion/ui/define/lion-input-tel-dropdown.js';
import '@lion/ui/define/lion-textarea.js';
-
import '@lion/ui/define/lion-checkbox.js';
import '@lion/ui/define/lion-checkbox-group.js';
-
import '@lion/ui/define/lion-radio.js';
import '@lion/ui/define/lion-radio-group.js';
import '@lion/ui/define/lion-switch.js';
-
import '@lion/ui/define/lion-select.js';
import '@lion/ui/define/lion-option.js';
-
import '@lion/ui/define/lion-combobox.js';
import '@lion/ui/define/lion-listbox.js';
import '@lion/ui/define/lion-select-rich.js';
-
import '@lion/ui/define/lion-fieldset.js';
import '@lion/ui/define/lion-form.js';
import '@lion/ui/define/lion-field.js';
@@ -344,7 +340,6 @@ describe('lion-fieldset', () => {
describe('detail.isTriggeredByUser', () => {
const allFormControls = [
- 'switch', // TODO: move back below when scoped-elements (polyfill) fixed side effects
// 1) Fields
'field',
// 1a) Input Fields
@@ -356,12 +351,14 @@ describe('detail.isTriggeredByUser', () => {
'input-iban',
'input-range',
'input-stepper',
+ 'input-tel',
+ 'input-tel-dropdown',
'textarea',
// 1b) Choice Fields
'option',
'checkbox',
'radio',
- // 'switch',
+ 'switch',
// 1c) Choice Group Fields
'select',
'listbox',
@@ -423,9 +420,10 @@ describe('detail.isTriggeredByUser', () => {
/**
* @param {FormControl & {value: string;}} el
* @param {string} newViewValue
- * @param {{ triggerType?: string, labelInsteadOfInput?: boolean }} [optionals]
+ * @param {{ triggerType?: string, labelInsteadOfInput?: boolean, parent?: HTMLElement }} options
*/
- function mimicUserInput(el, newViewValue, optionals) {
+ function mimicUserInput(el, newViewValue, options = {}) {
+ // @ts-ignore
const { _inputNode, _labelNode } = getFormControlMembers(el);
const type = detectType(el);
let userInputEv;
@@ -434,15 +432,15 @@ describe('detail.isTriggeredByUser', () => {
el.value = newViewValue; // eslint-disable-line no-param-reassign
_inputNode.dispatchEvent(new Event(userInputEv, { bubbles: true }));
} else if (type === 'ChoiceField') {
- if (optionals?.labelInsteadOfInput) {
+ if (options?.labelInsteadOfInput) {
_labelNode.click();
} else {
_inputNode.click();
}
} else if (type === 'OptionChoiceField') {
- if (!optionals?.triggerType) {
+ if (!options?.triggerType) {
el.dispatchEvent(new Event('click', { bubbles: true }));
- } else if (optionals?.triggerType === 'keypress') {
+ } else if (options?.triggerType === 'keypress') {
el.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
el.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown', bubbles: true }));
el.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
@@ -503,9 +501,12 @@ describe('detail.isTriggeredByUser', () => {
/**
* @param {FormControl & {value: string;}} formControl
- * @param {boolean | undefined} [testKeyboardBehavior]
+ * @param {{parent?: FormControl; testKeyboardBehavior?: boolean}} moreOpts
*/
- async function expectCorrectEventMetaChoiceField(formControl, testKeyboardBehavior) {
+ async function expectCorrectEventMetaChoiceField(
+ formControl,
+ { parent, testKeyboardBehavior } = {},
+ ) {
const type = detectType(formControl);
await resetChoiceFieldToForceRepropagation(formControl);
@@ -526,14 +527,19 @@ describe('detail.isTriggeredByUser', () => {
formControl.modelValue = { value: 'programmaticValue', checked: false };
expect(spy.secondCall.args[0].detail.isTriggeredByUser).to.be.false;
- if (type === 'OptionChoiceField' && testKeyboardBehavior) {
+ if (
+ type === 'OptionChoiceField' &&
+ testKeyboardBehavior &&
+ parent?.constructor.name !== 'LionCombobox' // modelValue only changeable via click or textbox
+ ) {
await resetChoiceFieldToForceRepropagation(formControl);
- mimicUserInput(formControl, 'userValue', { triggerType: 'keypress' });
- // TODO: get rid of try/catch (?)...
+ mimicUserInput(formControl, 'userValue', { triggerType: 'keypress', parent });
try {
expect(spy.firstCall.args[0].detail.isTriggeredByUser).to.be.true;
} catch (e) {
- console.log(formControl);
+ throw new Error(
+ `model-value-changed of ${formControl.constructor.name} with parent ${parent?.constructor.name} not caught`,
+ );
}
}
}
@@ -556,7 +562,10 @@ describe('detail.isTriggeredByUser', () => {
);
el.appendChild(childrenEls);
await el.registrationComplete;
- await expectCorrectEventMetaChoiceField(el.formElements[0], true);
+ await expectCorrectEventMetaChoiceField(el.formElements[0], {
+ testKeyboardBehavior: true,
+ parent: el,
+ });
} else if (type === 'FormOrFieldset') {
const childrenEls = await fixture(
html`
`,
diff --git a/packages/ui/components/input-tel/src/parsers.js b/packages/ui/components/input-tel/src/parsers.js
index a9e887b0e..ed5f85373 100644
--- a/packages/ui/components/input-tel/src/parsers.js
+++ b/packages/ui/components/input-tel/src/parsers.js
@@ -25,7 +25,7 @@ export function parsePhoneNumber(viewValue, { regionCode }) {
// eslint-disable-next-line no-empty
} catch (_) {}
- if (pn) {
+ if (pn?.number) {
return pn.number.e164;
}
diff --git a/packages/ui/docs/fundamentals/systems/overlays/assets/umbrella-form.js b/packages/ui/docs/fundamentals/systems/overlays/assets/umbrella-form.js
index 58d5f7e13..db35ab01c 100644
--- a/packages/ui/docs/fundamentals/systems/overlays/assets/umbrella-form.js
+++ b/packages/ui/docs/fundamentals/systems/overlays/assets/umbrella-form.js
@@ -8,15 +8,22 @@ import '@lion/ui/define/lion-input-datepicker.js';
import '@lion/ui/define/lion-input-amount.js';
import '@lion/ui/define/lion-input-iban.js';
import '@lion/ui/define/lion-input-email.js';
+import '@lion/ui/define/lion-input-tel.js';
+import '@lion/ui/define/lion-input-tel-dropdown.js';
import '@lion/ui/define/lion-checkbox-group.js';
+import '@lion/ui/define/lion-checkbox.js';
import '@lion/ui/define/lion-radio-group.js';
+import '@lion/ui/define/lion-radio.js';
import '@lion/ui/define/lion-select.js';
import '@lion/ui/define/lion-select-rich.js';
+import '@lion/ui/define/lion-listbox.js';
+import '@lion/ui/define/lion-option.js';
+import '@lion/ui/define/lion-combobox.js';
import '@lion/ui/define/lion-input-range.js';
import '@lion/ui/define/lion-textarea.js';
import '@lion/ui/define/lion-button.js';
-import '@lion/ui/define/lion-input-tel.js';
-import '@lion/ui/define/lion-input-tel-dropdown.js';
+import '@lion/ui/define/lion-switch.js';
+import '@lion/ui/define/lion-input-stepper.js';
export class UmbrellaForm extends LitElement {
get _lionFormNode() {