diff --git a/packages/listbox/src/ListboxMixin.js b/packages/listbox/src/ListboxMixin.js index 292705fdf..6b3e697a3 100644 --- a/packages/listbox/src/ListboxMixin.js +++ b/packages/listbox/src/ListboxMixin.js @@ -547,7 +547,7 @@ const ListboxMixinImplementation = superclass => /* no default */ } - const keys = ['ArrowUp', 'ArrowDown', 'Home', 'End']; + const keys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End']; if (keys.includes(key) && this.selectionFollowsFocus && !this.multipleChoice) { this.setCheckedIndex(this.activeIndex); } diff --git a/packages/listbox/test-suites/ListboxMixin.suite.js b/packages/listbox/test-suites/ListboxMixin.suite.js index aedee3726..74148196c 100644 --- a/packages/listbox/test-suites/ListboxMixin.suite.js +++ b/packages/listbox/test-suites/ListboxMixin.suite.js @@ -912,7 +912,7 @@ export function runListboxMixinSuite(customConfig = {}) { }); } const el = /** @type {LionListbox} */ (await fixture(html` - <${tag} opened selection-follows-focus autocomplete="none"> + <${tag} opened selection-follows-focus orientation="horizontal" autocomplete="none"> <${optionTag} .choiceValue=${10}>Item 1 <${optionTag} .choiceValue=${20}>Item 2 <${optionTag} .choiceValue=${30}>Item 3 @@ -936,6 +936,45 @@ export function runListboxMixinSuite(customConfig = {}) { expect(el.checkedIndex).to.equal(0); expectOnlyGivenOneOptionToBeChecked(options, 0); }); + it('navigates through list with [ArrowLeft] [ArrowRight] keys when horizontal: activates and checks the option', async () => { + /** + * @param {LionOption[]} options + * @param {number} selectedIndex + */ + function expectOnlyGivenOneOptionToBeChecked(options, selectedIndex) { + options.forEach((option, i) => { + if (i === selectedIndex) { + expect(option.checked).to.be.true; + } else { + expect(option.checked).to.be.false; + } + }); + } + const el = /** @type {LionListbox} */ (await fixture(html` + <${tag} opened selection-follows-focus autocomplete="none"> + <${optionTag} .choiceValue=${10}>Item 1 + <${optionTag} .choiceValue=${20}>Item 2 + <${optionTag} .choiceValue=${30}>Item 3 + + `)); + + const { listbox } = getProtectedMembers(el); + const options = el.formElements; + // Normalize start values between listbox, slect and combobox and test interaction below + el.activeIndex = 0; + el.checkedIndex = 0; + expect(el.activeIndex).to.equal(0); + expect(el.checkedIndex).to.equal(0); + expectOnlyGivenOneOptionToBeChecked(options, 0); + listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' })); + expect(el.activeIndex).to.equal(1); + expect(el.checkedIndex).to.equal(1); + expectOnlyGivenOneOptionToBeChecked(options, 1); + listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' })); + expect(el.activeIndex).to.equal(0); + expect(el.checkedIndex).to.equal(0); + expectOnlyGivenOneOptionToBeChecked(options, 0); + }); it('checks first and last option with [Home] and [End] keys', async () => { const el = await fixture(html` <${tag} opened selection-follows-focus>