fix: preselection in combobox

Co-authored-by: JYOTHI <JYOTHI@Jyomayi.local>
Co-authored-by: Thijs Louisse <Thijs.Louisse@ing.com>
This commit is contained in:
vbabu35 2025-07-29 20:51:22 +05:30 committed by GitHub
parent da46980da1
commit f19befe9c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 77 additions and 58 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/ui': patch
---
[combobox] fix preselection in combobox when modelValue present

View file

@ -1180,9 +1180,7 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(CustomChoiceGroupMi
*/
// eslint-disable-next-line no-unused-vars
_syncToTextboxCondition(modelValue, oldModelValue, { phase } = {}) {
return (
this.autocomplete === 'inline' || this.autocomplete === 'both' || phase === 'overlay-close'
);
return this.autocomplete === 'both' || this.autocomplete === 'inline' || !this.focused;
}
/**

View file

@ -640,38 +640,39 @@ describe('lion-combobox', () => {
});
it('syncs textbox to modelValue', async () => {
for (const autocompleteMode of ['none', 'list', 'inline', 'both']) {
const el = /** @type {LionCombobox} */ (
await fixture(html`
<lion-combobox name="foo" show-all-on-empty>
<lion-option .choiceValue="${'Aha'}" checked>Aha</lion-option>
<lion-option .choiceValue="${'Bhb'}">Bhb</lion-option>
<lion-combobox name="foo" show-all-on-empty .autocomplete="${autocompleteMode}">
<lion-option .choiceValue="${'Aa'}" checked>Aa</lion-option>
<lion-option .choiceValue="${'Bb'}">Bb</lion-option>
</lion-combobox>
`)
);
const { _inputNode } = getComboboxMembers(el);
/** @param {string} autocompleteMode */
async function performChecks(autocompleteMode) {
expect(_inputNode.value).to.equal('Aa', `autocompleteMode is ${autocompleteMode}`);
el.formElements[0].click();
await el.updateComplete;
// FIXME: fix properly for Webkit
// expect(_inputNode.value).to.equal('Aha', `autocompleteMode is ${autocompleteMode}`);
expect(_inputNode.value).to.equal('Aa', `autocompleteMode is ${autocompleteMode}`);
expect(el.checkedIndex).to.equal(0, `autocompleteMode is ${autocompleteMode}`);
await mimicUserTyping(el, 'Ah');
await mimicUserTyping(el, 'B');
await el.updateComplete;
expect(_inputNode.value).to.equal('Ah', `autocompleteMode is ${autocompleteMode}`);
if (autocompleteMode === 'none' || autocompleteMode === 'list') {
expect(el.modelValue).to.deep.equal(
{ type: 'unparseable', viewValue: 'B' },
`autocompleteMode is ${autocompleteMode}`,
);
await el.updateComplete;
expect(el.checkedIndex).to.equal(-1, `autocompleteMode is ${autocompleteMode}`);
} else {
expect(el.modelValue).to.equal('Bb', `autocompleteMode is ${autocompleteMode}`);
expect(el.checkedIndex).to.equal(1, `autocompleteMode is ${autocompleteMode}`);
}
}
el.autocomplete = 'none';
await performChecks('none');
el.autocomplete = 'list';
await performChecks('list');
});
it('works with Required validator', async () => {
@ -992,6 +993,27 @@ describe('lion-combobox', () => {
expect(el.modelValue).to.eql(['Art']);
});
it('allows prefilling the combobox', async () => {
const autocompleteValues = ['inline', 'none', 'both', 'list'];
for (const autocompleteValue of autocompleteValues) {
const el = /** @type {LionCombobox} */ (
await fixture(html`
<lion-combobox autocomplete="${autocompleteValue}" .modelValue="${'Chard'}" name="foo">
<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.modelValue).to.equal('Chard');
// @ts-expect-error
expect(el._inputNode.value).to.equal('Chard');
}
});
it('submits form on [Enter] when listbox is closed', async () => {
const submitSpy = sinon.spy(e => e.preventDefault());
const el = /** @type {HTMLFormElement} */ (
@ -2318,8 +2340,7 @@ describe('lion-combobox', () => {
</${tag}>
`)
);
// This ensures autocomplete would be off originally
el.autocomplete = 'list';
await mimicUserTypingAdvanced(el, ['v', 'i']); // so we have options ['Victoria Plum']
await el.updateComplete;
expect(el.checkedIndex).to.equal(3);
@ -2445,24 +2466,27 @@ describe('lion-combobox', () => {
expect(_inputNode.value).to.equal('');
el.setCheckedIndex(-1);
el.autocomplete = 'none';
el.setCheckedIndex(0);
expect(_inputNode.value).to.equal('');
el.setCheckedIndex(-1);
el.autocomplete = 'list';
el.setCheckedIndex(0);
expect(_inputNode.value).to.equal('');
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
expect(_inputNode.value).to.equal('art');
el.setCheckedIndex(-1);
el.value = '';
el.autocomplete = 'none';
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
expect(_inputNode.value).to.equal('art');
el.setCheckedIndex(-1);
el.value = '';
el.autocomplete = 'inline';
el.setCheckedIndex(0);
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
expect(_inputNode.value).to.equal('Artichoke');
el.setCheckedIndex(-1);
el.value = '';
el.autocomplete = 'both';
el.setCheckedIndex(0);
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
expect(_inputNode.value).to.equal('Artichoke');
});
@ -2482,30 +2506,28 @@ describe('lion-combobox', () => {
expect(_inputNode.value).to.eql('');
el.setCheckedIndex(-1);
el.autocomplete = 'none';
el.setCheckedIndex([0]);
el.setCheckedIndex([1]);
expect(_inputNode.value).to.equal('');
el.setCheckedIndex(-1);
el.autocomplete = 'list';
el.setCheckedIndex([0]);
el.setCheckedIndex([1]);
expect(_inputNode.value).to.equal('');
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
expect(_inputNode.value).to.equal('art');
el.setCheckedIndex(-1);
el.value = '';
el.autocomplete = 'none';
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
expect(_inputNode.value).to.equal('art');
el.setCheckedIndex(-1);
el.value = '';
el.autocomplete = 'inline';
el.setCheckedIndex([0]);
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
expect(_inputNode.value).to.equal('Artichoke');
el.setCheckedIndex([1]);
expect(_inputNode.value).to.equal('Chard');
el.setCheckedIndex(-1);
el.value = '';
el.autocomplete = 'both';
el.setCheckedIndex([0]);
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
expect(_inputNode.value).to.equal('Artichoke');
el.setCheckedIndex([1]);
expect(_inputNode.value).to.equal('Chard');
});
describe('Subclassers', () => {
@ -2754,12 +2776,6 @@ describe('lion-combobox', () => {
async function performChecks(autocompleteMode) {
await el.updateComplete;
el.formElements[0].click();
// FIXME: fix properly for Webkit
// expect(_inputNode.value).to.equal('Aha', autocompleteMode);
expect(el.checkedIndex).to.equal(0, autocompleteMode);
await mimicUserTypingAdvanced(el, ['A', 'r', 't', 'i']);
await el.updateComplete;
expect(_inputNode.value).to.equal('Arti', `autocompleteMode is ${autocompleteMode}`);