Skip to content

Commit 5591572

Browse files
committed
fix: ensure menu-bar is focusable after closing and moving focus
1 parent 5cae25d commit 5591572

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

packages/a11y-base/src/keyboard-direction-mixin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export const KeyboardDirectionMixin = (superclass) =>
116116
return;
117117
}
118118

119-
if (idx >= 0) {
119+
if (idx >= 0 && idx !== currentIdx) {
120120
event.preventDefault();
121121
this._focus(idx, { focusVisible: true }, true);
122122
}

packages/a11y-base/test/keyboard-direction-mixin.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,5 +238,17 @@ describe('KeyboardDirectionMixin', () => {
238238
tabKeyDown(items[5]);
239239
expect(element.focused).to.not.equal(items[0]);
240240
});
241+
242+
it('should not prevent default on Tab keydown with only one item present', () => {
243+
element.innerHTML = '<div tabindex="0">Foo</div>';
244+
items = element.children;
245+
items[0].focus();
246+
247+
const spy = sinon.spy();
248+
element.addEventListener('keydown', spy);
249+
tabKeyDown(items[0]);
250+
251+
expect(spy.firstCall.args[0].defaultPrevented).to.be.false;
252+
});
241253
});
242254
});

packages/menu-bar/src/vaadin-menu-bar-mixin.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,8 @@ export const MenuBarMixin = (superClass) =>
761761
*/
762762
_setFocused(focused) {
763763
if (focused) {
764-
const target = this.tabNavigation ? this.querySelector('[focused]') : this.querySelector('[tabindex="0"]');
764+
const selector = this.tabNavigation ? '[focused]' : '[tabindex="0"]';
765+
const target = this.querySelector(`vaadin-menu-bar-button${selector}`);
765766
if (target) {
766767
this._buttons.forEach((btn) => {
767768
this._setTabindex(btn, btn === target);

packages/menu-bar/test/keyboard-navigation.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,4 +454,45 @@ describe('keyboard navigation', () => {
454454
});
455455
});
456456
});
457+
458+
describe('single button', () => {
459+
beforeEach(async () => {
460+
menu.items = [{ text: 'Item 1', children: [{ text: 'Item 1 1' }] }];
461+
await nextUpdate(menu);
462+
buttons = menu._buttons;
463+
firstGlobalFocusable.focus();
464+
});
465+
466+
it('should be focusable on Shift + Tab after closing and moving focus by default', async () => {
467+
await sendKeys({ press: 'Tab' });
468+
469+
await sendKeys({ press: 'ArrowDown' });
470+
await nextRender();
471+
472+
await sendKeys({ press: 'Escape' });
473+
474+
await sendKeys({ press: 'Tab' });
475+
expect(document.activeElement).to.equal(lastGlobalFocusable);
476+
477+
await sendKeys({ press: 'Shift+Tab' });
478+
expect(document.activeElement).to.equal(buttons[0]);
479+
});
480+
481+
it('should be focusable on Shift + Tab after closing and moving focus with Tab navigation', async () => {
482+
menu.tabNavigation = true;
483+
484+
await sendKeys({ press: 'Tab' });
485+
486+
await sendKeys({ press: 'ArrowDown' });
487+
await nextRender();
488+
489+
await sendKeys({ press: 'Escape' });
490+
491+
await sendKeys({ press: 'Tab' });
492+
expect(document.activeElement).to.equal(lastGlobalFocusable);
493+
494+
await sendKeys({ press: 'Shift+Tab' });
495+
expect(document.activeElement).to.equal(buttons[0]);
496+
});
497+
});
457498
});

0 commit comments

Comments
 (0)