Skip to content

Commit

Permalink
fix(tooltip): improve component timing (#7172)
Browse files Browse the repository at this point in the history
**Related Issue:** #6396

## Summary

- Separates timeout delay between open and close.
  - `open` is set to `300ms`.
  - `close` is set to `500ms`.
- Sets delay to `0ms` if a tooltip is already displayed.
- Add story for design review.
- Update tests.
  • Loading branch information
driskull authored Jun 15, 2023
1 parent 0e2a205 commit 106f5d2
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,36 @@ export const darkModeRTL_TestOnly = (): string =>

darkModeRTL_TestOnly.parameters = { modes: modesDarkDefault };

export const adjacentTooltipsOpenQuickly = (): string => html`<div style="display:flex; height:500px; width: 200px;">
<calcite-action-bar>
<calcite-action-group>
<calcite-action text="Add" icon="plus">
<calcite-tooltip placement="right" slot="tooltip">Add</calcite-tooltip>
</calcite-action>
<calcite-action text="Save" icon="save"
><calcite-tooltip placement="right" slot="tooltip">Save</calcite-tooltip></calcite-action
>
<calcite-action text="Layers" icon="layers"
><calcite-tooltip placement="right" slot="tooltip">Layers</calcite-tooltip></calcite-action
>
</calcite-action-group>
<calcite-action-group>
<calcite-action text="Add" icon="plus"
><calcite-tooltip placement="right" slot="tooltip">Add</calcite-tooltip></calcite-action
>
<calcite-action text="Save" active icon="save"
><calcite-tooltip placement="right" slot="tooltip">Save</calcite-tooltip></calcite-action
>
<calcite-action text="Layers" icon="layers"
><calcite-tooltip placement="right" slot="tooltip">Layers</calcite-tooltip></calcite-action
>
</calcite-action-group>
<calcite-action slot="bottom-actions" text="hello world" icon="layers"
><calcite-tooltip placement="right" slot="tooltip">hello world</calcite-tooltip></calcite-action
>
</calcite-action-bar>
</div>`;

export const withTooltip_NoTest = (): string =>
create(
"calcite-action-bar",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { newE2EPage } from "@stencil/core/testing";
import { html } from "../../../support/formatting";
import { accessible, defaults, focusable, hidden, reflects, renders, slots } from "../../tests/commonTests";
import { TOOLTIP_DELAY_MS } from "../tooltip/resources";
import { TOOLTIP_OPEN_DELAY_MS } from "../tooltip/resources";
import { CSS, SLOTS } from "./resources";

describe("calcite-action-menu", () => {
Expand Down Expand Up @@ -198,7 +198,7 @@ describe("calcite-action-menu", () => {
expect(await tooltip.isVisible()).toBe(false);

await trigger.hover();
await page.waitForTimeout(TOOLTIP_DELAY_MS);
await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS);

expect(await tooltip.isVisible()).toBe(true);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getShadowRootNode, isPrimaryPointerButton } from "../../utils/dom";
import { ReferenceElement } from "../../utils/floating-ui";
import { TOOLTIP_DELAY_MS } from "./resources";
import { TOOLTIP_OPEN_DELAY_MS, TOOLTIP_CLOSE_DELAY_MS } from "./resources";
import { getEffectiveReferenceElement } from "./utils";

export default class TooltipManager {
Expand All @@ -14,7 +14,9 @@ export default class TooltipManager {

private registeredShadowRootCounts = new WeakMap<ShadowRoot, number>();

private hoverTimeout: number = null;
private hoverOpenTimeout: number = null;

private hoverCloseTimeout: number = null;

private hoveredTooltip: HTMLCalciteTooltipElement = null;

Expand Down Expand Up @@ -80,7 +82,7 @@ export default class TooltipManager {

if (activeTooltip?.open) {
this.clearHoverTimeout();
this.closeExistingTooltip();
this.closeActiveTooltip();

const referenceElement = getEffectiveReferenceElement(activeTooltip);

Expand Down Expand Up @@ -111,9 +113,9 @@ export default class TooltipManager {
this.clickedTooltip = null;

if (tooltip) {
this.toggleHoveredTooltip(tooltip, true);
this.openHoveredTooltip(tooltip);
} else if (activeTooltip) {
this.toggleHoveredTooltip(activeTooltip, false);
this.closeHoveredTooltip();
}
};

Expand Down Expand Up @@ -166,61 +168,83 @@ export default class TooltipManager {
document.removeEventListener("focusout", this.focusOutHandler, { capture: true });
}

private clearHoverOpenTimeout(): void {
window.clearTimeout(this.hoverOpenTimeout);
this.hoverOpenTimeout = null;
}

private clearHoverCloseTimeout(): void {
window.clearTimeout(this.hoverCloseTimeout);
this.hoverCloseTimeout = null;
}

private clearHoverTimeout(): void {
window.clearTimeout(this.hoverTimeout);
this.hoverTimeout = null;
this.clearHoverOpenTimeout();
this.clearHoverCloseTimeout();
}

private closeExistingTooltip(): void {
private closeActiveTooltip(): void {
const { activeTooltip } = this;

if (activeTooltip?.open) {
this.toggleTooltip(activeTooltip, false);
}
}

private toggleFocusedTooltip(tooltip: HTMLCalciteTooltipElement, value: boolean): void {
this.closeExistingTooltip();
private toggleFocusedTooltip(tooltip: HTMLCalciteTooltipElement, open: boolean): void {
this.closeActiveTooltip();

if (value) {
if (open) {
this.clearHoverTimeout();
}

this.toggleTooltip(tooltip, value);
this.toggleTooltip(tooltip, open);
}

private toggleTooltip(tooltip: HTMLCalciteTooltipElement, value: boolean): void {
tooltip.open = value;
private toggleTooltip(tooltip: HTMLCalciteTooltipElement, open: boolean): void {
tooltip.open = open;

if (value) {
this.activeTooltip = tooltip;
}
this.activeTooltip = open ? tooltip : null;
}

private toggleHoveredTooltip = (tooltip: HTMLCalciteTooltipElement, value: boolean): void => {
this.hoverTimeout = window.setTimeout(() => {
if (this.hoverTimeout === null) {
return;
}
private openHoveredTooltip = (tooltip: HTMLCalciteTooltipElement): void => {
this.hoverOpenTimeout = window.setTimeout(
() => {
if (this.hoverOpenTimeout === null) {
return;
}

this.clearHoverCloseTimeout();
this.closeActiveTooltip();

this.closeExistingTooltip();
if (tooltip !== this.hoveredTooltip) {
return;
}

this.toggleTooltip(tooltip, true);
},
this.activeTooltip ? 0 : TOOLTIP_OPEN_DELAY_MS
);
};

if (tooltip !== this.hoveredTooltip) {
private closeHoveredTooltip = (): void => {
this.hoverCloseTimeout = window.setTimeout(() => {
if (this.hoverCloseTimeout === null) {
return;
}

this.toggleTooltip(tooltip, value);
}, TOOLTIP_DELAY_MS);
this.closeActiveTooltip();
}, TOOLTIP_CLOSE_DELAY_MS);
};

private queryFocusedTooltip(event: FocusEvent, value: boolean): void {
private queryFocusedTooltip(event: FocusEvent, open: boolean): void {
const tooltip = this.queryTooltip(event.composedPath());

if (!tooltip || this.isClosableClickedTooltip(tooltip)) {
return;
}

this.toggleFocusedTooltip(tooltip, value);
this.toggleFocusedTooltip(tooltip, open);
}

private isClosableClickedTooltip(tooltip: HTMLCalciteTooltipElement): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const CSS = {
container: "container"
};

export const TOOLTIP_DELAY_MS = 500;
export const TOOLTIP_OPEN_DELAY_MS = 300;
export const TOOLTIP_CLOSE_DELAY_MS = 500;

export const ARIA_DESCRIBED_BY = "aria-describedby";
Loading

0 comments on commit 106f5d2

Please sign in to comment.