FIX: ensures tabbing from trigger focus content (#30064)

`DMenu` is using in-element, which means the content is detached from the trigger, and pressing tab from the trigger is not going to jump into the content. This commit catches the tab event and attempts to focus the first focusable element of the content.
This commit is contained in:
Joffrey JAFFEUX 2024-12-04 12:46:02 +01:00 committed by GitHub
parent d2d8fbcf3b
commit 3ddb1cfbad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,6 +1,9 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { concat } from "@ember/helper"; import { concat } from "@ember/helper";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { getOwner } from "@ember/owner"; import { getOwner } from "@ember/owner";
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
import { service } from "@ember/service"; import { service } from "@ember/service";
import { modifier } from "ember-modifier"; import { modifier } from "ember-modifier";
import { and } from "truth-helpers"; import { and } from "truth-helpers";
@ -31,6 +34,28 @@ export default class DMenu extends Component {
}; };
}); });
@action
registerFloatBody(element) {
this.body = element;
}
@action
forwardTabToContent(event) {
if (!this.body) {
return;
}
if (event.key === "Tab") {
event.preventDefault();
const firstFocusable = this.body.querySelector(
'button, a, input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])'
);
firstFocusable?.focus() || this.body.focus();
}
}
get menuId() { get menuId() {
return `d-menu-${this.menuInstance.id}`; return `d-menu-${this.menuInstance.id}`;
} }
@ -73,6 +98,7 @@ export default class DMenu extends Component {
@translatedTitle={{@title}} @translatedTitle={{@title}}
@disabled={{@disabled}} @disabled={{@disabled}}
aria-expanded={{if this.menuInstance.expanded "true" "false"}} aria-expanded={{if this.menuInstance.expanded "true" "false"}}
{{on "keydown" this.forwardTabToContent}}
...attributes ...attributes
> >
{{#if (has-block "trigger")}} {{#if (has-block "trigger")}}
@ -122,6 +148,7 @@ export default class DMenu extends Component {
@innerClass="fk-d-menu__inner-content" @innerClass="fk-d-menu__inner-content"
@role="dialog" @role="dialog"
@inline={{this.options.inline}} @inline={{this.options.inline}}
{{didInsert this.registerFloatBody}}
> >
{{#if (has-block)}} {{#if (has-block)}}
{{yield this.componentArgs}} {{yield this.componentArgs}}