DEV: Do not trigger floatkit 'hover' for touch events (#30793)

When tapping something on a touch-enabled device, `mouseMove` events are
still fired, so floatkit would still be triggered even if configured for
'hover' only. For links, this would be particularly strange, because the
tooltip would appear for a split-second, before the page navigation
occured.

To avoid this problem, we can use the more-modern 'pointerMove' event,
and check the `pointerType` to exclude 'touch'
This commit is contained in:
David Taylor
2025-01-16 12:36:47 +00:00
committed by GitHub
parent f28eb5b0dc
commit 72f4588d3b
9 changed files with 29 additions and 18 deletions

View File

@ -155,7 +155,7 @@ acceptance("Post inline mentions – user status tooltip", function (needs) {
};
async function mouseMove(selector) {
await triggerEvent(selector, "mousemove");
await triggerEvent(selector, "pointermove");
}
test("shows user status tooltip", async function (assert) {

View File

@ -46,7 +46,7 @@ module("Integration | Component | DStatTiles", function (hooks) {
</template>);
assert.dom(".d-stat-tile__tooltip").exists();
await triggerEvent(".fk-d-tooltip__trigger", "mousemove");
await triggerEvent(".fk-d-tooltip__trigger", "pointermove");
assert.dom(".fk-d-tooltip__content").hasText(i18n("bootstrap_mode"));
});

View File

@ -15,11 +15,11 @@ module("Integration | Component | FloatKit | d-tooltip", function (hooks) {
setupRenderingTest(hooks);
async function hover() {
await triggerEvent(".fk-d-tooltip__trigger", "mousemove");
await triggerEvent(".fk-d-tooltip__trigger", "pointermove");
}
async function leave() {
await triggerEvent(".fk-d-tooltip__trigger", "mouseleave");
await triggerEvent(".fk-d-tooltip__trigger", "pointerleave");
}
async function close() {

View File

@ -127,7 +127,7 @@ module("Integration | Component | user-info", function (hooks) {
await render(
hbs`<UserInfo @user={{this.currentUser}} @showStatus={{true}} /><DTooltips />`
);
await triggerEvent(query(".user-status-message"), "mousemove");
await triggerEvent(query(".user-status-message"), "pointermove");
assert
.dom("[data-content][data-identifier='user-status-message-tooltip']")

View File

@ -5,7 +5,7 @@ import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { fakeTime, query } from "discourse/tests/helpers/qunit-helpers";
async function mouseenter() {
await triggerEvent(query(".user-status-message"), "mousemove");
await triggerEvent(query(".user-status-message"), "pointermove");
}
module("Integration | Component | user-status-message", function (hooks) {

View File

@ -81,7 +81,7 @@ export default class DMenuInstance extends FloatKitInstance {
}
@action
async onMouseMove(event) {
async onPointerMove(event) {
if (this.expanded && this.trigger.contains(event.target)) {
return;
}
@ -99,7 +99,7 @@ export default class DMenuInstance extends FloatKitInstance {
}
@action
async onMouseLeave(event) {
async onPointerLeave(event) {
if (this.untriggers.includes("hover")) {
await this.onUntrigger(event);
}

View File

@ -65,8 +65,12 @@ export default class DTooltipInstance extends FloatKitInstance {
}
@action
async onMouseMove(event) {
if (this.expanded && this.trigger.contains(event.target)) {
async onPointerMove(event) {
if (
this.expanded &&
this.trigger.contains(event.target) &&
event.pointerType !== "touch"
) {
return;
}
@ -83,7 +87,7 @@ export default class DTooltipInstance extends FloatKitInstance {
}
@action
async onMouseLeave(event) {
async onPointerLeave(event) {
if (this.untriggers.includes("hover")) {
await this.onUntrigger(event);
}

View File

@ -128,9 +128,12 @@ export default class FloatKitInstance {
this.trigger.removeEventListener("focusout", this.onFocusOut);
break;
case "hover":
this.trigger.removeEventListener("mousemove", this.onMouseMove);
this.trigger.removeEventListener("pointermove", this.onPointerMove);
if (!this.options.interactive) {
this.trigger.removeEventListener("mouseleave", this.onMouseLeave);
this.trigger.removeEventListener(
"pointerleave",
this.onPointerLeave
);
}
break;
@ -180,13 +183,17 @@ export default class FloatKitInstance {
});
break;
case "hover":
this.trigger.addEventListener("mousemove", this.onMouseMove, {
this.trigger.addEventListener("pointermove", this.onPointerMove, {
passive: true,
});
if (!this.options.interactive) {
this.trigger.addEventListener("mouseleave", this.onMouseLeave, {
this.trigger.addEventListener(
"pointerleave",
this.onPointerLeave,
{
passive: true,
});
}
);
}
break;

View File

@ -159,7 +159,7 @@ module(
test("it shows status tooltip", async function (assert) {
await render(hbs`<ChatChannel @channel={{this.channel}} /><DTooltips />`);
await triggerEvent(statusSelector(mentionedUser.username), "mousemove");
await triggerEvent(statusSelector(mentionedUser.username), "pointermove");
assert
.dom(".user-status-tooltip-description")