199 lines
7.6 KiB
JavaScript
199 lines
7.6 KiB
JavaScript
import { mimicUserChangingDropdown } from '@lion/ui/input-amount-dropdown-test-helpers.js';
|
|
import { runInputAmountDropdownSuite } from '@lion/ui/input-amount-dropdown-test-suites.js';
|
|
import { LionInputAmountDropdown } from '@lion/ui/input-amount-dropdown.js';
|
|
import { aTimeout, expect, fixture } from '@open-wc/testing';
|
|
import { LionSelectRich } from '@lion/ui/select-rich.js';
|
|
import { repeat } from 'lit/directives/repeat.js';
|
|
import { LionOption } from '@lion/ui/listbox.js';
|
|
import { ref } from 'lit/directives/ref.js';
|
|
import { html } from 'lit';
|
|
|
|
import { isActiveElement } from '../../core/test-helpers/isActiveElement.js';
|
|
import { ScopedElementsMixin } from '../../core/src/ScopedElementsMixin.js';
|
|
import '@lion/ui/define/lion-input-amount-dropdown.js';
|
|
|
|
/**
|
|
* @typedef {import('../types/index.js').TemplateDataForDropdownInputAmount} TemplateDataForDropdownInputAmount
|
|
* @typedef {HTMLSelectElement|HTMLElement & {modelValue:string}} DropdownElement
|
|
* @typedef {import('../types/index.js').RegionMeta} RegionMeta
|
|
* @typedef {import('lit').TemplateResult} TemplateResult
|
|
*/
|
|
|
|
class WithFormControlInputAmountDropdown extends ScopedElementsMixin(LionInputAmountDropdown) {
|
|
/**
|
|
* @configure ScopedElementsMixin
|
|
*/
|
|
static scopedElements = {
|
|
...super.scopedElements,
|
|
'lion-select-rich': LionSelectRich,
|
|
'lion-option': LionOption,
|
|
};
|
|
|
|
static templates = {
|
|
...(super.templates || {}),
|
|
/**
|
|
* @param {TemplateDataForDropdownInputAmount} templateDataForDropdown
|
|
*/
|
|
dropdown: templateDataForDropdown => {
|
|
const { refs, data } = templateDataForDropdown;
|
|
// TODO: once spread directive available, use it per ref (like ref(refs?.dropdown?.ref))
|
|
return html`
|
|
<lion-select-rich
|
|
${ref(refs?.dropdown?.ref)}
|
|
label="${refs?.dropdown?.labels?.country}"
|
|
label-sr-only
|
|
@model-value-changed="${refs?.dropdown?.listeners['model-value-changed']}"
|
|
style="${refs?.dropdown?.props?.style}"
|
|
>
|
|
${repeat(
|
|
data.regionMetaList,
|
|
regionMeta => regionMeta.currencyCode,
|
|
regionMeta => html`
|
|
<lion-option .choiceValue="${regionMeta.currencyCode}"> </lion-option>
|
|
`,
|
|
)}
|
|
</lion-select-rich>
|
|
`;
|
|
},
|
|
};
|
|
}
|
|
|
|
runInputAmountDropdownSuite();
|
|
|
|
describe('WithFormControlInputAmountDropdown', () => {
|
|
// @ts-expect-error
|
|
// Runs it for LionSelectRich, which uses .modelValue/@model-value-changed instead of .value/@change
|
|
runInputAmountDropdownSuite({ klass: WithFormControlInputAmountDropdown });
|
|
|
|
it('focuses the textbox right after selection if selected via opened dropdown if interaction-mode is mac', async () => {
|
|
class InputAmountDropdownMac extends LionInputAmountDropdown {
|
|
static templates = {
|
|
...(super.templates || {}),
|
|
/**
|
|
* @param {TemplateDataForDropdownInputAmount} templateDataForDropdown
|
|
*/
|
|
dropdown: templateDataForDropdown => {
|
|
const { refs, data } = templateDataForDropdown;
|
|
// TODO: once spread directive available, use it per ref (like ref(refs?.dropdown?.ref))
|
|
return html`
|
|
<lion-select-rich
|
|
${ref(refs?.dropdown?.ref)}
|
|
label="${refs?.dropdown?.labels?.country}"
|
|
label-sr-only
|
|
@model-value-changed="${refs?.dropdown?.listeners['model-value-changed']}"
|
|
style="${refs?.dropdown?.props?.style}"
|
|
interaction-mode="mac"
|
|
>
|
|
${repeat(
|
|
data.regionMetaList,
|
|
regionMeta => regionMeta.currencyCode,
|
|
regionMeta => html`
|
|
<lion-option .choiceValue="${regionMeta.currencyCode}"> </lion-option>
|
|
`,
|
|
)}
|
|
</lion-select-rich>
|
|
`;
|
|
},
|
|
};
|
|
}
|
|
customElements.define('input-amount-dropdown-mac', InputAmountDropdownMac);
|
|
const el = /** @type {LionInputAmountDropdown} */ (
|
|
await fixture(html`
|
|
<input-amount-dropdown-mac
|
|
.allowedCurrencies="${['GBP', 'EUR']}"
|
|
.modelValue="{ currency: 'GBP', amount: '123' }"
|
|
></input-amount-dropdown-mac>
|
|
`)
|
|
);
|
|
const dropdownElement = el.refs.dropdown.value;
|
|
// @ts-expect-error [allow-protected-in-tests]
|
|
if (dropdownElement?._overlayCtrl) {
|
|
// @ts-expect-error [allow-protected-in-tests]
|
|
dropdownElement._overlayCtrl.show();
|
|
mimicUserChangingDropdown(dropdownElement, 'EUR');
|
|
await el.updateComplete;
|
|
await aTimeout(0);
|
|
// @ts-expect-error [allow-protected-in-tests]
|
|
expect(isActiveElement(el._inputNode)).to.be.true;
|
|
}
|
|
});
|
|
|
|
it('does not focus the textbox right after selection if selected via opened dropdown if interaction-mode is windows/linux', async () => {
|
|
class InputAmountDropdownWindows extends LionInputAmountDropdown {
|
|
static templates = {
|
|
...(super.templates || {}),
|
|
/**
|
|
* @param {TemplateDataForDropdownInputAmount} templateDataForDropdown
|
|
*/
|
|
dropdown: templateDataForDropdown => {
|
|
const { refs, data } = templateDataForDropdown;
|
|
// TODO: once spread directive available, use it per ref (like ref(refs?.dropdown?.ref))
|
|
return html`
|
|
<lion-select-rich
|
|
${ref(refs?.dropdown?.ref)}
|
|
label="${refs?.dropdown?.labels?.country}"
|
|
label-sr-only
|
|
@model-value-changed="${refs?.dropdown?.listeners['model-value-changed']}"
|
|
style="${refs?.dropdown?.props?.style}"
|
|
interaction-mode="windows/linux"
|
|
>
|
|
${repeat(
|
|
data.regionMetaList,
|
|
regionMeta => regionMeta.currencyCode,
|
|
regionMeta => html`
|
|
<lion-option .choiceValue="${regionMeta.currencyCode}"> </lion-option>
|
|
`,
|
|
)}
|
|
</lion-select-rich>
|
|
`;
|
|
},
|
|
};
|
|
}
|
|
customElements.define('input-amount-dropdown-windows', InputAmountDropdownWindows);
|
|
const el = /** @type {LionInputAmountDropdown} */ (
|
|
await fixture(html`
|
|
<input-amount-dropdown-windows
|
|
.allowedCurrencies="${['GBP', 'EUR']}"
|
|
.modelValue="{ currency: 'GBP', amount: '123' }"
|
|
></input-amount-dropdown-windows>
|
|
`)
|
|
);
|
|
const dropdownElement = el.refs.dropdown.value;
|
|
// @ts-expect-error [allow-protected-in-tests]
|
|
if (dropdownElement?._overlayCtrl) {
|
|
// @ts-expect-error [allow-protected-in-tests]
|
|
dropdownElement._overlayCtrl.show();
|
|
mimicUserChangingDropdown(dropdownElement, 'EUR');
|
|
await el.updateComplete;
|
|
await aTimeout(0);
|
|
// @ts-expect-error [allow-protected-in-tests]
|
|
expect(isActiveElement(el._inputNode)).to.be.false;
|
|
}
|
|
});
|
|
|
|
describe('defaultValidators', () => {
|
|
it('without interaction are not called', async () => {
|
|
const el = /** @type {LionInputAmountDropdown} */ (
|
|
await fixture(html`
|
|
<lion-input-amount-dropdown .allowedCurrencies="${['EUR']}"></lion-input-amount-dropdown>
|
|
`)
|
|
);
|
|
await aTimeout(0);
|
|
expect(el.hasFeedbackFor).to.deep.equal([]);
|
|
});
|
|
|
|
it('with interaction are called', async () => {
|
|
const el = /** @type {LionInputAmountDropdown} */ (
|
|
await fixture(html`
|
|
<lion-input-amount-dropdown
|
|
.allowedCurrencies="${['GBP', 'EUR']}"
|
|
></lion-input-amount-dropdown>
|
|
`)
|
|
);
|
|
el.modelValue = { currency: 'EUR' };
|
|
await aTimeout(0);
|
|
el.modelValue = { currency: 'EUR', amount: '' };
|
|
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
});
|
|
});
|
|
});
|