DEV: allows d-menu to refocus trigger (#30522)

This commit is contained in:
Joffrey JAFFEUX 2025-01-02 09:31:15 +01:00 committed by GitHub
parent e04af92740
commit a5ba788a23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 56 additions and 4 deletions

View File

@ -64,7 +64,7 @@ export default class NotificationsTracking extends Component {
@action
async setNotificationLevel(level) {
await this.dmenuApi.close();
await this.dmenuApi.close({ focusTrigger: true });
this.args.onChange?.(level);
}

View File

@ -350,4 +350,43 @@ module("Integration | Component | FloatKit | d-menu", function (hooks) {
assert.dom(".fk-d-menu__trigger.first").doesNotExist();
assert.dom(".fk-d-menu.first").exists();
});
test("focusTrigger on close", async function (assert) {
this.api = null;
this.onRegisterApi = (api) => (this.api = api);
this.close = async () => await this.api.close();
await render(
hbs`<DMenu @onRegisterApi={{this.onRegisterApi}} @inline={{true}} @icon="xmark">
<DButton @icon="xmark" class="close" @action={{this.close}} />
</DMenu>`
);
await click(".fk-d-menu__trigger");
await triggerKeyEvent(document.activeElement, "keydown", "Tab");
await triggerKeyEvent(document.activeElement, "keydown", "Enter");
assert.strictEqual(
document.activeElement,
document.querySelector(".fk-d-menu__trigger")
);
});
test("focusTrigger=false on close", async function (assert) {
this.api = null;
this.onRegisterApi = (api) => (this.api = api);
this.close = async () => await this.api.close({ focusTrigger: false });
await render(
hbs`<DMenu @onRegisterApi={{this.onRegisterApi}} @inline={{true}} @icon="xmark">
<DButton @icon="xmark" class="close" @action={{this.close}} />
</DMenu>`
);
await click(".fk-d-menu__trigger");
await triggerKeyEvent(document.activeElement, "keydown", "Tab");
await triggerKeyEvent(document.activeElement, "keydown", "Enter");
assert.strictEqual(document.activeElement, document.body);
});
});

View File

@ -1,5 +1,5 @@
import Component from "@glimmer/component";
import { concat, hash } from "@ember/helper";
import { concat, fn, hash } from "@ember/helper";
import { htmlSafe } from "@ember/template";
import { modifier as modifierFn } from "ember-modifier";
import concatClass from "discourse/helpers/concat-class";
@ -70,7 +70,9 @@ export default class DFloatBody extends Component {
{{(if
this.supportsCloseOnClickOutside
(modifier
closeOnClickOutside @instance.close (hash target=this.content)
closeOnClickOutside
(fn @instance.close (hash focusTrigger=false))
(hash target=this.content)
)
)}}
{{(if

View File

@ -4,6 +4,7 @@ import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { getOwner } from "@ember/owner";
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
import { service } from "@ember/service";
import { modifier } from "ember-modifier";
import { and } from "truth-helpers";
@ -39,6 +40,11 @@ export default class DMenu extends Component {
this.body = element;
}
@action
teardownFloatBody() {
this.body = null;
}
@action
forwardTabToContent(event) {
if (!this.body) {
@ -151,6 +157,7 @@ export default class DMenu extends Component {
@role="dialog"
@inline={{this.options.inline}}
{{didInsert this.registerFloatBody}}
{{willDestroy this.teardownFloatBody}}
>
{{#if (has-block)}}
{{yield this.componentArgs}}

View File

@ -54,7 +54,7 @@ export default class DMenuInstance extends FloatKitInstance {
}
@action
async close() {
async close(options = { focusTrigger: true }) {
if (getOwner(this).isDestroying) {
return;
}
@ -66,6 +66,10 @@ export default class DMenuInstance extends FloatKitInstance {
}
await this.menu.close(this);
if (options.focusTrigger) {
this.trigger?.focus?.();
}
}
@action