feat(combobox): allow to configure textbox sync on close

This commit is contained in:
Thijs Louisse 2021-03-24 16:42:37 +01:00 committed by Joren Broekema
parent 0c711f6962
commit 72a6ccc81e
4 changed files with 66 additions and 4 deletions

View file

@ -0,0 +1,11 @@
---
'@lion/combobox': minor
'@lion/form-core': patch
'@lion/form-integrations': patch
---
Allow Subclassers of LionCombobox to set '\_syncToTextboxCondition' in closing phase of overlay
## Fixes
Allow an extra microtask in registration phase to make forms inside dialogs compatible.

View file

@ -215,7 +215,10 @@ This will:
```js preview-story
export const multipleChoice = () => html`
<lion-combobox name="combo" label="Multiple" multiple-choice>
<demo-selection-display slot="selection-display"></demo-selection-display>
<demo-selection-display
slot="selection-display"
style="display: contents;"
></demo-selection-display>
${lazyRender(
listboxData.map(
(entry, i) =>

View file

@ -440,7 +440,12 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
__onOverlayClose() {
if (!this.multipleChoice) {
if (this.checkedIndex !== -1) {
if (
this.checkedIndex !== -1 &&
this._syncToTextboxCondition(this.modelValue, this.__oldModelValue, {
phase: 'overlay-close',
})
) {
this._inputNode.value = this.formElements[
/** @type {number} */ (this.checkedIndex)
].choiceValue;
@ -739,12 +744,15 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
}
/**
* @overridable
* @param {string|string[]} modelValue
* @param {string|string[]} oldModelValue
*/
// eslint-disable-next-line no-unused-vars
_syncToTextboxCondition(modelValue, oldModelValue) {
return this.autocomplete === 'inline' || this.autocomplete === 'both';
_syncToTextboxCondition(modelValue, oldModelValue, { phase } = {}) {
return (
this.autocomplete === 'inline' || this.autocomplete === 'both' || phase === 'overlay-close'
);
}
/**

View file

@ -936,6 +936,46 @@ describe('lion-combobox', () => {
await performChecks('both', [0, 1], '');
});
it('is possible to adjust textbox synchronize condition on overlay close', async () => {
const el = /** @type {LionCombobox} */ (await fixture(html`
<lion-combobox name="foo" autocomplete="none" ._syncToTextboxCondition="${() => false}">
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
</lion-combobox>
`));
expect(el._inputNode.value).to.equal('');
/**
* @param {'none' | 'list' | 'inline' | 'both'} autocomplete
* @param {number|number[]} index
* @param {string} valueOnClose
*/
async function performChecks(autocomplete, index, valueOnClose) {
await el.updateComplete;
el.opened = true;
el.setCheckedIndex(-1);
await el.updateComplete;
el.autocomplete = autocomplete;
el.setCheckedIndex(index);
el.opened = false;
await el.updateComplete;
expect(el._inputNode.value).to.equal(valueOnClose);
}
await performChecks('none', 0, '');
await performChecks('list', 0, '');
await performChecks('inline', 0, '');
await performChecks('both', 0, '');
el.multipleChoice = true;
await performChecks('none', [0, 1], '');
await performChecks('list', [0, 1], '');
await performChecks('inline', [0, 1], '');
await performChecks('both', [0, 1], '');
});
it('does inline autocompletion when adding chars', async () => {
const el = /** @type {LionCombobox} */ (await fixture(html`
<lion-combobox name="foo" autocomplete="inline">