import Component from "@glimmer/component"; import { concat } from "@ember/helper"; 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 { service } from "@ember/service"; import { modifier } from "ember-modifier"; import { and } from "truth-helpers"; import DButton from "discourse/components/d-button"; import DModal from "discourse/components/d-modal"; import concatClass from "discourse/helpers/concat-class"; import { isTesting } from "discourse-common/config/environment"; import DFloatBody from "float-kit/components/d-float-body"; import { MENU } from "float-kit/lib/constants"; import DMenuInstance from "float-kit/lib/d-menu-instance"; export default class DMenu extends Component { @service menu; @service site; menuInstance = new DMenuInstance(getOwner(this), { ...this.allowedProperties, autoUpdate: true, listeners: true, }); registerTrigger = modifier((element) => { this.menuInstance.trigger = element; this.options.onRegisterApi?.(this.menuInstance); return () => { this.menuInstance.destroy(); }; }); @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() { return `d-menu-${this.menuInstance.id}`; } get options() { return this.menuInstance?.options ?? {}; } get componentArgs() { return { close: this.menuInstance.close, data: this.options.data, }; } get allowedProperties() { const properties = {}; for (const [key, value] of Object.entries(MENU.options)) { properties[key] = this.args[key] ?? value; } return properties; } }