Skip to content

Commit 07e8a24

Browse files
committed
refactor: restore the original fix, move tabindex logic
1 parent 1b02619 commit 07e8a24

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,23 @@ export const KeyboardDirectionMixin = (superclass) =>
4444
* @override
4545
*/
4646
focus(options) {
47-
const items = this._getItems();
48-
if (Array.isArray(items)) {
49-
const idx = this._getAvailableIndex(items, 0, null, (item) => !isElementHidden(item));
50-
if (idx >= 0) {
51-
this._focus(idx, options);
52-
}
47+
const idx = this._getFocusableIndex();
48+
if (idx >= 0) {
49+
this._focus(idx, options);
5350
}
5451
}
5552

53+
/**
54+
* Get the index of a first focusable item, if any.
55+
*
56+
* @return {Element[]}
57+
* @protected
58+
*/
59+
_getFocusableIndex() {
60+
const items = this._getItems();
61+
return Array.isArray(items) ? this._getAvailableIndex(items, 0, null, (item) => !isElementHidden(item)) : -1;
62+
}
63+
5664
/**
5765
* Get the list of items participating in keyboard navigation.
5866
* By default, it treats all the light DOM children as items.

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Directive, directive } from 'lit/directive.js';
88
import { ifDefined } from 'lit/directives/if-defined.js';
99
import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
1010
import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
11-
import { isElementFocused, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
11+
import { isElementFocused, isElementHidden, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
1212
import { KeyboardDirectionMixin } from '@vaadin/a11y-base/src/keyboard-direction-mixin.js';
1313
import { microTask } from '@vaadin/component-base/src/async.js';
1414
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
@@ -268,7 +268,6 @@ export const MenuBarMixin = (superClass) =>
268268
set _hasOverflow(hasOverflow) {
269269
if (this._overflow) {
270270
this._overflow.toggleAttribute('hidden', !hasOverflow);
271-
this._overflow.setAttribute('tabindex', hasOverflow ? '0' : '-1');
272271
}
273272
}
274273

@@ -502,9 +501,12 @@ export const MenuBarMixin = (superClass) =>
502501
const items = buttons.filter((b) => !remaining.includes(b)).map((b) => b.item);
503502
this.__updateOverflow(items);
504503

505-
// Ensure there is at least one button with tabindex set to 0
506-
// so that menu-bar is not skipped when navigating with Tab
507-
if (remaining.length && !remaining.some((btn) => btn.getAttribute('tabindex') === '0')) {
504+
if (!remaining.length) {
505+
// If all buttons except overflow are hidden, set tabindex on it
506+
this._overflow.setAttribute('tabindex', '0');
507+
} else if (!remaining.some((btn) => btn.getAttribute('tabindex') === '0')) {
508+
// Ensure there is at least one button with tabindex set to 0
509+
// so that menu-bar is not skipped when navigating with Tab
508510
this._setTabindex(remaining[remaining.length - 1], true);
509511
}
510512
}
@@ -762,7 +764,7 @@ export const MenuBarMixin = (superClass) =>
762764
*/
763765
_setFocused(focused) {
764766
if (focused) {
765-
const target = this._buttons.find((btn) => isElementFocused(btn));
767+
const target = this.__getFocusTarget();
766768
if (target) {
767769
this._buttons.forEach((btn) => {
768770
this._setTabindex(btn, btn === target);
@@ -776,6 +778,24 @@ export const MenuBarMixin = (superClass) =>
776778
}
777779
}
778780

781+
/** @private */
782+
__getFocusTarget() {
783+
// First, check if focus is moving to a visible button
784+
let target = this._buttons.find((btn) => isElementFocused(btn));
785+
786+
if (!target) {
787+
const selector = this.tabNavigation ? '[focused]' : '[tabindex="0"]';
788+
// Next, check if there is a button that could be focused but is hidden
789+
target = this.querySelector(`vaadin-menu-bar-button${selector}`);
790+
791+
if (isElementHidden(target)) {
792+
target = this._buttons[this._getFocusableIndex()];
793+
}
794+
}
795+
796+
return target;
797+
}
798+
779799
/**
780800
* @param {!KeyboardEvent} event
781801
* @private

packages/menu-bar/test/dom/__snapshots__/menu-bar.test.snap.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ snapshots["menu-bar basic"] =
5656
hidden=""
5757
role="menuitem"
5858
slot="overflow"
59-
tabindex="-1"
59+
tabindex="0"
6060
>
6161
<div aria-hidden="true">
6262
···
@@ -156,7 +156,7 @@ snapshots["menu-bar opened"] =
156156
hidden=""
157157
role="menuitem"
158158
slot="overflow"
159-
tabindex="-1"
159+
tabindex="0"
160160
>
161161
<div aria-hidden="true">
162162
···

0 commit comments

Comments
 (0)