Skip to content

Commit 4eae45a

Browse files
authored
components/tooltip: Allow hovering over tooltip to interact with links (#12218)
Use `ember-concurrency` `restartableTask` with 100ms delay to allow users to move their mouse from the anchor element into the tooltip without it disappearing. Add `mouseenter` and `mouseleave` handlers to the tooltip element itself to keep it visible while hovering.
1 parent 27d2f5b commit 4eae45a

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

app/components/tooltip.gjs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Component from '@glimmer/component';
33
import { tracked } from '@glimmer/tracking';
44

55
import { autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom';
6+
import { restartableTask, timeout } from 'ember-concurrency';
67
import { modifier } from 'ember-modifier';
78

89
export default class Tooltip extends Component {
@@ -14,13 +15,21 @@ export default class Tooltip extends Component {
1415
}
1516

1617
@action show() {
18+
this.hideTask.cancelAll();
1719
this.visible = true;
1820
}
1921

2022
@action hide() {
21-
this.visible = false;
23+
this.hideTask.perform().catch(() => {
24+
// ignore cancelation errors
25+
});
2226
}
2327

28+
hideTask = restartableTask(async () => {
29+
await timeout(100);
30+
this.visible = false;
31+
});
32+
2433
onInsertAnchor = modifier((anchor, [component]) => {
2534
component.anchorElement = anchor.parentElement;
2635

@@ -61,7 +70,14 @@ export default class Tooltip extends Component {
6170

6271
let cleanup = autoUpdate(referenceElement, floatingElement, update);
6372

64-
return () => cleanup();
73+
floatingElement.addEventListener('mouseenter', component.show);
74+
floatingElement.addEventListener('mouseleave', component.hide);
75+
76+
return () => {
77+
cleanup();
78+
floatingElement.removeEventListener('mouseenter', component.show);
79+
floatingElement.removeEventListener('mouseleave', component.hide);
80+
};
6581
});
6682

6783
// The `{{~@x~}}` is used for whitespace control to ensure we don't insert a leading whitespace element

0 commit comments

Comments
 (0)