Skip to content

Commit

Permalink
refactor(tooltip): update anchoring approach (#318)
Browse files Browse the repository at this point in the history
  • Loading branch information
mimshins authored Dec 30, 2024
1 parent fc8eac4 commit b737541
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 67 deletions.
9 changes: 9 additions & 0 deletions packages/web-components/src/tooltip/tooltip.style.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { css } from "lit";
import { Z_INDEXES } from "../internals";

export default css`
*,
Expand All @@ -12,7 +13,9 @@ export default css`
}
:host {
isolation: isolate;
position: absolute;
width: 100%;
}
.root.visible {
Expand All @@ -24,6 +27,10 @@ export default css`
display: flex;
align-items: flex-start;
-moz-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
max-width: 20.5rem;
min-height: 2.25rem;
padding: var(--tapsi-spacing-3-1) var(--tapsi-spacing-4);
Expand All @@ -34,6 +41,8 @@ export default css`
background-color: var(--tapsi-color-surface-inverse-secondary);
visibility: hidden;
opacity: 0;
z-index: ${Z_INDEXES[5]};
}
.text {
Expand Down
95 changes: 28 additions & 67 deletions packages/web-components/src/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { property, query, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { styleMap } from "lit/directives/style-map.js";
import { KeyboardKeys } from "../internals";
import { getRenderRootSlot, isSSR, waitAMicrotask } from "../utils";
import { Slots } from "./constants";
import { isSSR, waitAMicrotask } from "../utils";
import { HideEvent, ShowEvent } from "./events";
import { dismiss } from "./icons";
import { rotateArrow, translate } from "./utils";
Expand Down Expand Up @@ -41,6 +40,12 @@ export class Tooltip extends LitElement {
@property({ type: String })
public text = "";

/**
* The id of the anchor element.
*/
@property({ type: String })
public anchor = "";

/**
* Whether the tooltip is visible or not.
*/
Expand Down Expand Up @@ -88,32 +93,8 @@ export class Tooltip extends LitElement {

if (!isSSR()) {
this._handleKeyDown = this._handleKeyDown.bind(this);
this._handleAnchorFocus = this._handleAnchorFocus.bind(this);
this._handleAnchorBlur = this._handleAnchorBlur.bind(this);

this.addEventListener(
"focus",
event => {
const anchorElement = this._getAnchorElement();

if (anchorElement !== event.target) return;

void this._handleAnchorFocus(event);
},
true,
);

this.addEventListener(
"blur",
event => {
const anchorElement = this._getAnchorElement();

if (anchorElement !== event.target) return;

void this._handleAnchorBlur(event);
},
true,
);
this._handleAnchorMouseEnter = this._handleAnchorMouseEnter.bind(this);
this._handleAnchorMouseLeave = this._handleAnchorMouseLeave.bind(this);
}
}

Expand All @@ -123,21 +104,32 @@ export class Tooltip extends LitElement {
if (!isSSR()) {
void this.updateTooltipPosition();

// eslint-disable-next-line @typescript-eslint/no-misused-promises
/* eslint-disable @typescript-eslint/no-misused-promises */
document.addEventListener("keydown", this._handleKeyDown);

const anchor = this._getAnchorElement();

if (!anchor) return;

anchor.addEventListener("mouseenter", this._handleAnchorMouseEnter);
anchor.addEventListener("mouseleave", this._handleAnchorMouseLeave);
/* eslint-enable @typescript-eslint/no-misused-promises */
}
}

public override disconnectedCallback() {
super.disconnectedCallback();

// eslint-disable-next-line @typescript-eslint/no-misused-promises
/* eslint-disable @typescript-eslint/no-misused-promises */
document.removeEventListener("keydown", this._handleKeyDown);
this._getAnchorElement()?.removeEventListener(
"focus",
// eslint-disable-next-line @typescript-eslint/no-misused-promises
this._handleAnchorFocus,
);

const anchor = this._getAnchorElement();

if (!anchor) return;

anchor.removeEventListener("mouseenter", this._handleAnchorMouseEnter);
anchor.removeEventListener("mouseleave", this._handleAnchorMouseLeave);
/* eslint-enable @typescript-eslint/no-misused-promises */
}

protected override updated(changed: PropertyValues<this>) {
Expand Down Expand Up @@ -227,15 +219,7 @@ export class Tooltip extends LitElement {
}

private _getAnchorElement() {
const anchorSlot = getRenderRootSlot(this.renderRoot, Slots.DEFAULT);

return (anchorSlot?.assignedElements()[0] ?? null) as HTMLElement | null;
}

private _updateAnchorAria() {
const anchorElement = this._getAnchorElement();

anchorElement?.setAttribute("aria-describedby", "root");
return document.getElementById(this.anchor);
}

private async _handleKeyDown(event: KeyboardEvent) {
Expand Down Expand Up @@ -270,18 +254,6 @@ export class Tooltip extends LitElement {
this.hide();
}

private async _handleAnchorFocus(event: FocusEvent) {
if (this.noFocusActivation) return;

await this._handleTriggerShowByEvent(event);
}

private async _handleAnchorBlur(event: FocusEvent) {
if (this.noFocusActivation) return;

await this._handleTriggerHideByEvent(event);
}

private async _handleAnchorMouseEnter(event: MouseEvent) {
if (this.noHoverActivation) return;

Expand All @@ -294,11 +266,6 @@ export class Tooltip extends LitElement {
await this._handleTriggerHideByEvent(event);
}

private _handleAnchorSlotChange() {
this._updateAnchorAria();
void this.updateTooltipPosition();
}

private _renderDismissButton() {
if (!this.dismissible) return null;

Expand Down Expand Up @@ -378,12 +345,6 @@ export class Tooltip extends LitElement {
</svg>
</div>
</div>
<!-- The anchor element -->
<slot
@slotchange=${this._handleAnchorSlotChange}
@mouseenter=${this._handleAnchorMouseEnter}
@mouseleave=${this._handleAnchorMouseLeave}
></slot>
`;
}
}

0 comments on commit b737541

Please sign in to comment.