Skip to content

Commit

Permalink
Merge pull request #14842 from craftcms/feature/tooltip-delay
Browse files Browse the repository at this point in the history
Add slight delay before opening tooltip on hover
  • Loading branch information
brandonkelly committed Apr 23, 2024
2 parents 4847c16 + de7e21f commit f40cde8
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Sort options are now sorted alphabetically within element indexes, and custom fields’ options are now listed in a “Fields” group. ([#14725](https://github.com/craftcms/cms/issues/14725))
- Unselected table column options are now sorted alphabetically within element indexes.
- Table views within element index pages are now scrolled directly, so that their horizontal scrollbars are always visible without scrolling to the bottom of the page. ([#14765](https://github.com/craftcms/cms/issues/14765))
- Element tooltips now appear after a half-second delay. ([#14836](https://github.com/craftcms/cms/issues/14836))

### Administration
- Added the `asyncCsrfInputs` config setting. ([#14625](https://github.com/craftcms/cms/pull/14625))
Expand Down
2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/cp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/cp.js.map

Large diffs are not rendered by default.

40 changes: 25 additions & 15 deletions src/web/assets/cp/src/js/CraftTooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {arrow, computePosition, flip, offset, shift} from '@floating-ui/dom';
* @property {'top'|'top-start'|'top-end'|'right'|'right-start'|'right-end'|'bottom'|'bottom-start'|'bottom-end'|'left'|'left-start'|'left-end'} placement - The placement of the tooltip relative to the parent element.
* @property {boolean} arrow - Whether the tooltip should have an arrow.
* @property {number} offset - The offset of the tooltip from the parent element.
* @property {number} delay - The delay before the tooltip is shown on mouseentery.
* @method show - Show the tooltip.
* @method hide - Hide the tooltip.
* @method update - Update the position of the tooltip.
Expand All @@ -28,21 +29,23 @@ class CraftTooltip extends HTMLElement {

this.placement = this.getAttribute('placement') || 'bottom';
this.direction = getComputedStyle(this).direction;
this.delay = this.getAttribute('delay') || 500;
this.delayTimeout = null;

if (this.arrow && !this.arrowElement) {
this.renderInner();
this.renderArrow();
}

this.listeners = [
['mouseenter', this.show],
['focus', this.show],
['mouseleave', this.hide],
['blur', this.hide],
['mouseenter', this.show, this.delay],
['focus', this.show, 0],
['mouseleave', this.hide, 0],
['blur', this.hide, 0],
];

this.listeners.forEach(([event, handler]) => {
this.parentElement?.addEventListener(event, handler.bind(this));
this.listeners.forEach(([event, handler, delay]) => {
this.parentElement?.addEventListener(event, handler.bind(this, delay));
});

// Close on ESC
Expand Down Expand Up @@ -91,19 +94,26 @@ class CraftTooltip extends HTMLElement {
this.inner.appendChild(this.arrowElement);
}

show() {
show(delay) {
this.update();
Object.assign(this.style, {
opacity: 1,
transform: ['left', 'right'].includes(this.getStaticSide())
? `translateX(0)`
: `translateY(0)`,
// Make sure if a user hovers over the label itself, it stays open
pointerEvents: 'auto',
});

this.delayTimeout = setTimeout(() => {
Object.assign(this.style, {
opacity: 1,
transform: ['left', 'right'].includes(this.getStaticSide())
? `translateX(0)`
: `translateY(0)`,
// Make sure if a user hovers over the label itself, it stays open
pointerEvents: 'auto',
});
}, delay);
}

hide() {
if (this.delayTimeout) {
clearTimeout(this.delayTimeout);
}

Object.assign(this.style, {
opacity: 0,
transform: this.getInitialTransform(),
Expand Down

0 comments on commit f40cde8

Please sign in to comment.