From 0d4c42ab6491f5c0fed4e3f80c09d2e3354542af Mon Sep 17 00:00:00 2001 From: gvangeest Date: Tue, 7 Mar 2023 11:03:45 +0100 Subject: [PATCH] fix(listbox): allow use of arrow keys when focus is not on listbox --- .changeset/eighty-dogs-travel.md | 5 +++++ .../ui/components/listbox/src/ListboxMixin.js | 6 ++++++ .../listbox/test-suites/ListboxMixin.suite.js | 16 +++++++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 .changeset/eighty-dogs-travel.md diff --git a/.changeset/eighty-dogs-travel.md b/.changeset/eighty-dogs-travel.md new file mode 100644 index 000000000..93c1c5bbb --- /dev/null +++ b/.changeset/eighty-dogs-travel.md @@ -0,0 +1,5 @@ +--- +'@lion/ui': patch +--- + +[listbox] allow use of arrow keys when focus is not on listbox diff --git a/packages/ui/components/listbox/src/ListboxMixin.js b/packages/ui/components/listbox/src/ListboxMixin.js index 9ac4f8eac..fb49ada94 100644 --- a/packages/ui/components/listbox/src/ListboxMixin.js +++ b/packages/ui/components/listbox/src/ListboxMixin.js @@ -635,6 +635,9 @@ const ListboxMixinImplementation = superclass => } break; case 'ArrowLeft': + if (this._listboxReceivesNoFocus) { + return; + } ev.preventDefault(); if (this.orientation === 'horizontal') { this.activeIndex = this._getPreviousEnabledOption(this.activeIndex); @@ -647,6 +650,9 @@ const ListboxMixinImplementation = superclass => } break; case 'ArrowRight': + if (this._listboxReceivesNoFocus) { + return; + } ev.preventDefault(); if (this.orientation === 'horizontal') { this.activeIndex = this._getNextEnabledOption(this.activeIndex); diff --git a/packages/ui/components/listbox/test-suites/ListboxMixin.suite.js b/packages/ui/components/listbox/test-suites/ListboxMixin.suite.js index 845a984bf..bc3923abe 100644 --- a/packages/ui/components/listbox/test-suites/ListboxMixin.suite.js +++ b/packages/ui/components/listbox/test-suites/ListboxMixin.suite.js @@ -861,6 +861,7 @@ export function runListboxMixinSuite(customConfig = {}) { mimicKeyPress(_listboxNode, 'End'); expect(el.activeIndex).to.equal(3); }); + it('navigates through open lists with [ArrowDown] [ArrowUp] keys activates the option', async () => { const el = /** @type {LionListbox} */ ( await fixture(html` @@ -936,7 +937,7 @@ export function runListboxMixinSuite(customConfig = {}) { it('uses [ArrowLeft] and [ArrowRight] keys when "horizontal"', async () => { const el = /** @type {LionListbox} */ ( await fixture(html` - <${tag} opened name="foo" orientation="horizontal" autocomplete="none" show-all-on-empty> + <${tag} ._listboxReceivesNoFocus="${false}" opened name="foo" orientation="horizontal" autocomplete="none" show-all-on-empty> <${optionTag} .choiceValue="${'Artichoke'}">Artichoke <${optionTag} .choiceValue="${'Chard'}">Chard @@ -948,15 +949,12 @@ export function runListboxMixinSuite(customConfig = {}) { // Normalize for suite tests el.activeIndex = 0; - await el.updateComplete; mimicKeyPress(_listboxNode, 'ArrowRight'); - expect(el.activeIndex).to.equal(1); mimicKeyPress(_listboxNode, 'ArrowLeft'); - expect(el.activeIndex).to.equal(0); // No response to vertical arrows... @@ -965,7 +963,14 @@ export function runListboxMixinSuite(customConfig = {}) { el.activeIndex = 1; mimicKeyPress(_listboxNode, 'ArrowUp'); + expect(el.activeIndex).to.equal(1); + // @ts-ignore allow protected member access in test + el._listboxReceivesNoFocus = true; + mimicKeyPress(_listboxNode, 'ArrowLeft'); + expect(el.activeIndex).to.equal(1); + + mimicKeyPress(_listboxNode, 'ArrowRight'); expect(el.activeIndex).to.equal(1); }); @@ -1141,6 +1146,7 @@ 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 @@ -1157,7 +1163,7 @@ export function runListboxMixinSuite(customConfig = {}) { } const el = /** @type {LionListbox} */ ( await fixture(html` - <${tag} opened selection-follows-focus orientation="horizontal" autocomplete="none" show-all-on-empty> + <${tag} ._listboxReceivesNoFocus="${false}" opened selection-follows-focus orientation="horizontal" autocomplete="none" show-all-on-empty> <${optionTag} .choiceValue=${10}>Item 1 <${optionTag} .choiceValue=${20}>Item 2 <${optionTag} .choiceValue=${30}>Item 3