diff --git a/app/assets/javascripts/discourse/app/components/notifications-tracking.gjs b/app/assets/javascripts/discourse/app/components/notifications-tracking.gjs index ac803db2337..4ac1ba103cf 100644 --- a/app/assets/javascripts/discourse/app/components/notifications-tracking.gjs +++ b/app/assets/javascripts/discourse/app/components/notifications-tracking.gjs @@ -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); } diff --git a/app/assets/javascripts/discourse/tests/integration/components/float-kit/d-menu-test.js b/app/assets/javascripts/discourse/tests/integration/components/float-kit/d-menu-test.js index 7fdc9c2e7d1..dc9be4dd8e8 100644 --- a/app/assets/javascripts/discourse/tests/integration/components/float-kit/d-menu-test.js +++ b/app/assets/javascripts/discourse/tests/integration/components/float-kit/d-menu-test.js @@ -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` + + ` + ); + + 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` + + ` + ); + + await click(".fk-d-menu__trigger"); + await triggerKeyEvent(document.activeElement, "keydown", "Tab"); + await triggerKeyEvent(document.activeElement, "keydown", "Enter"); + + assert.strictEqual(document.activeElement, document.body); + }); }); diff --git a/app/assets/javascripts/float-kit/addon/components/d-float-body.gjs b/app/assets/javascripts/float-kit/addon/components/d-float-body.gjs index e0e826bf590..bb344a4228b 100644 --- a/app/assets/javascripts/float-kit/addon/components/d-float-body.gjs +++ b/app/assets/javascripts/float-kit/addon/components/d-float-body.gjs @@ -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 diff --git a/app/assets/javascripts/float-kit/addon/components/d-menu.gjs b/app/assets/javascripts/float-kit/addon/components/d-menu.gjs index 7f64042215c..4cbbf092576 100644 --- a/app/assets/javascripts/float-kit/addon/components/d-menu.gjs +++ b/app/assets/javascripts/float-kit/addon/components/d-menu.gjs @@ -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}} diff --git a/app/assets/javascripts/float-kit/addon/lib/d-menu-instance.js b/app/assets/javascripts/float-kit/addon/lib/d-menu-instance.js index c3fc9b65067..33653217177 100644 --- a/app/assets/javascripts/float-kit/addon/lib/d-menu-instance.js +++ b/app/assets/javascripts/float-kit/addon/lib/d-menu-instance.js @@ -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