diff --git a/app/assets/javascripts/discourse/app/components/d-tooltip.gjs b/app/assets/javascripts/discourse/app/components/d-tooltip.gjs
new file mode 100644
index 00000000000..1f0a9719f59
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/d-tooltip.gjs
@@ -0,0 +1,41 @@
+import Component from "@glimmer/component";
+import didInsert from "@ember/render-modifiers/modifiers/did-insert";
+import { inject as service } from "@ember/service";
+import { action } from "@ember/object";
+import { iconHTML } from "discourse-common/lib/icon-library";
+import tippy from "tippy.js";
+
+export default class DiscourseTooltip extends Component {
+
+ {{! template-lint-disable modifier-name-case }}
+ {{yield}}
+
+
+ @service capabilities;
+
+ #tippyInstance;
+
+ willDestroy() {
+ super.willDestroy(...arguments);
+ this.#tippyInstance.destroy();
+ }
+
+ stopPropagation(instance, event) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ @action
+ initTippy(element) {
+ this.#tippyInstance = tippy(element.parentElement, {
+ content: element,
+ interactive: this.args.interactive ?? false,
+ trigger: this.capabilities.touch ? "click" : "mouseenter",
+ theme: this.args.theme || "d-tooltip",
+ arrow: this.args.arrow ? iconHTML("tippy-rounded-arrow") : false,
+ placement: this.args.placement || "bottom-start",
+ onTrigger: this.stopPropagation,
+ onUntrigger: this.stopPropagation,
+ });
+ }
+}
diff --git a/app/assets/javascripts/discourse/app/components/d-tooltip.hbs b/app/assets/javascripts/discourse/app/components/d-tooltip.hbs
deleted file mode 100644
index 97b23804af4..00000000000
--- a/app/assets/javascripts/discourse/app/components/d-tooltip.hbs
+++ /dev/null
@@ -1,3 +0,0 @@
-
- {{yield}}
-
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/d-tooltip.js b/app/assets/javascripts/discourse/app/components/d-tooltip.js
deleted file mode 100644
index 7083c0a797e..00000000000
--- a/app/assets/javascripts/discourse/app/components/d-tooltip.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import Component from "@ember/component";
-import { schedule } from "@ember/runloop";
-import { iconHTML } from "discourse-common/lib/icon-library";
-import tippy from "tippy.js";
-import Ember from "ember";
-
-export default class DiscourseTooltip extends Component {
- tagName = "";
- interactive = false;
- placement = this.args?.placement || "bottom-start";
-
- didInsertElement() {
- this._super(...arguments);
- this._initTippy();
- }
-
- willDestroyElement() {
- this._super(...arguments);
- this._tippyInstance.destroy();
- }
-
- stopPropagation(instance, event) {
- event.preventDefault();
- event.stopPropagation();
- }
-
- _initTippy() {
- schedule("afterRender", () => {
- // Ember.ViewUtils.getViewBounds is a private API,
- // but it's not going to be dropped without a public deprecation warning,
- // see: https://stackoverflow.com/a/50125938/3206146
- const viewBounds = Ember.ViewUtils.getViewBounds(this);
- const element = viewBounds.firstNode;
- const parent = viewBounds.parentElement;
- const interactive = this.interactive;
- this._tippyInstance = tippy(parent, {
- interactive,
- content: element,
- trigger: this.capabilities.touch ? "click" : "mouseenter",
- theme: this.attrs.theme || "d-tooltip",
- arrow: this.attrs.arrow ? iconHTML("tippy-rounded-arrow") : false,
- placement: this.placement,
- onTrigger: this.stopPropagation,
- onUntrigger: this.stopPropagation,
- });
- });
- }
-}