From ca524a03f3a8650a3e80da2d793338b8ddbef224 Mon Sep 17 00:00:00 2001 From: konnorrogers Date: Tue, 11 Jun 2024 13:07:49 -0400 Subject: [PATCH] fix tooltip docs, remove stopAnimations --- docs/docs/components/tooltip.md | 38 +++++++++++++-------------- src/components/details/details.ts | 4 +-- src/components/tooltip/tooltip.ts | 35 ++++++------------------ src/components/tree-item/tree-item.ts | 5 +--- src/internal/animate.ts | 34 +++++++++++------------- 5 files changed, 44 insertions(+), 72 deletions(-) diff --git a/docs/docs/components/tooltip.md b/docs/docs/components/tooltip.md index a3321ab77..6819e35c9 100644 --- a/docs/docs/components/tooltip.md +++ b/docs/docs/components/tooltip.md @@ -207,9 +207,8 @@ const App = () => ( Set the `trigger` attribute to `click` to toggle the tooltip on click instead of hover. ```html {.example} - - Click to Toggle - +Click to Toggle +Click again to dismiss ``` {% raw %} @@ -230,9 +229,9 @@ const App = () => ( Tooltips can be controller programmatically by setting the `trigger` attribute to `manual`. Use the `open` attribute to control when the tooltip is shown. ```html {.example} -Toggle Manually +Toggle Manually - + @@ -274,9 +273,8 @@ const App = () => { You can control the size of tooltip arrows by overriding the `--wa-tooltip-arrow-size` design token. To remove them, set the value to `0` as shown below. ```html {.example} - - No Arrow - +No Arrow +This is a tooltip with no arrow ``` {% raw %} @@ -311,10 +309,9 @@ To override it globally, set it in a root block in your stylesheet after the Web Use the `content` slot to create tooltips with HTML content. Tooltips are designed only for text and presentational elements. Avoid placing interactive content, such as buttons, links, and form controls, in a tooltip. ```html {.example} - -
I'm not just a tooltip, I'm a tooltip with HTML!
- - Hover me +Hover me + +
I'm not just a tooltip, I'm a tooltip with HTML!
``` @@ -340,9 +337,10 @@ const App = () => ( Use the `--max-width` custom property to change the width the tooltip can grow to before wrapping occurs. ```html {.example} - - Hover me + + This tooltip will wrap after only 80 pixels. +Hover me ``` {% raw %} @@ -364,20 +362,20 @@ Tooltips will be clipped if they're inside a container that has `overflow: auto| ```html {.example}
- - No Hoist - + This is a tooltip + No Hoist - - Hoist + + This is a tooltip + Hoist
diff --git a/src/components/details/details.ts b/src/components/details/details.ts index 467fe7d8f..fc2900f72 100644 --- a/src/components/details/details.ts +++ b/src/components/details/details.ts @@ -1,5 +1,5 @@ import '../icon/icon.js'; -import { animate, parseDuration, stopAnimations } from '../../internal/animate.js'; +import { animate, parseDuration } from '../../internal/animate.js'; import { classMap } from 'lit/directives/class-map.js'; import { customElement, property, query } from 'lit/decorators.js'; import { html } from 'lit'; @@ -144,7 +144,6 @@ export default class WaDetails extends WebAwesomeElement { return; } - await stopAnimations(this.body); const duration = parseDuration(getComputedStyle(this.body).getPropertyValue('--show-duration')); // We can't animate to 'auto', so use the scroll height for now await animate( @@ -171,7 +170,6 @@ export default class WaDetails extends WebAwesomeElement { return; } - await stopAnimations(this.body); const duration = parseDuration(getComputedStyle(this.body).getPropertyValue('--hide-duration')); // We can't animate from 'auto', so use the scroll height for now await animate( diff --git a/src/components/tooltip/tooltip.ts b/src/components/tooltip/tooltip.ts index 93434ce8d..f3abf74dc 100644 --- a/src/components/tooltip/tooltip.ts +++ b/src/components/tooltip/tooltip.ts @@ -1,4 +1,4 @@ -import { animateWithClass, stopAnimations } from '../../internal/animate.js'; +import { animateWithClass } from '../../internal/animate.js'; import { classMap } from 'lit/directives/class-map.js'; import { customElement, property, query, state } from 'lit/decorators.js'; import { html } from 'lit'; @@ -149,28 +149,19 @@ export default class WaTooltip extends WebAwesomeElement { } }; - private handleClick = (e: Event) => { + private handleClick = () => { if (this.hasTrigger('click')) { if (this.open) { this.hide(); } else { - - let anchor = undefined - if (e.currentTarget !== this) { - anchor = e.currentTarget as HTMLElement - } - this.show(anchor); + this.show(); } } }; - private handleFocus = (e: Event) => { + private handleFocus = () => { if (this.hasTrigger('focus')) { - let anchor = undefined - if (e.currentTarget !== this) { - anchor = e.currentTarget as HTMLElement - } - this.show(anchor); + this.show(); } }; @@ -182,15 +173,11 @@ export default class WaTooltip extends WebAwesomeElement { } }; - private handleMouseOver = (e: Event) => { + private handleMouseOver = () => { if (this.hasTrigger('hover')) { clearTimeout(this.hoverTimeout); - let anchor = undefined - if (e.currentTarget !== this) { - anchor = e.currentTarget as HTMLElement - } - this.hoverTimeout = window.setTimeout(() => this.show(anchor), this.showDelay); + this.hoverTimeout = window.setTimeout(() => this.show(), this.showDelay); } }; @@ -233,7 +220,6 @@ export default class WaTooltip extends WebAwesomeElement { this.body.hidden = false; this.popup.active = true; - await stopAnimations(this.popup.popup); await animateWithClass(this.popup.popup, 'show-with-scale'); this.popup.reposition(); @@ -250,7 +236,6 @@ export default class WaTooltip extends WebAwesomeElement { this.closeWatcher?.destroy(); document.removeEventListener('keydown', this.handleDocumentKeyDown); - await stopAnimations(this.popup.popup); await animateWithClass(this.popup.popup, 'hide-with-scale'); this.popup.active = false; this.body.hidden = true; @@ -320,15 +305,11 @@ export default class WaTooltip extends WebAwesomeElement { } /** Shows the tooltip. */ - async show(anchor?: HTMLElement) { + async show() { if (this.open) { return undefined; } - if (anchor) { - this.anchor = anchor - } - this.open = true; return waitForEvent(this, 'wa-after-show'); } diff --git a/src/components/tree-item/tree-item.ts b/src/components/tree-item/tree-item.ts index 3182253e4..48364eddc 100644 --- a/src/components/tree-item/tree-item.ts +++ b/src/components/tree-item/tree-item.ts @@ -1,7 +1,7 @@ import '../checkbox/checkbox.js'; import '../icon/icon.js'; import '../spinner/spinner.js'; -import { animate, parseDuration, stopAnimations } from '../../internal/animate.js'; +import { animate, parseDuration } from '../../internal/animate.js'; import { classMap } from 'lit/directives/class-map.js'; import { customElement, property, query, state } from 'lit/decorators.js'; import { html } from 'lit'; @@ -122,8 +122,6 @@ export default class WaTreeItem extends WebAwesomeElement { private async animateCollapse() { this.dispatchEvent(new WaCollapseEvent()); - await stopAnimations(this.childrenContainer); - const duration = parseDuration(getComputedStyle(this.childrenContainer).getPropertyValue('--hide-duration')); await animate( this.childrenContainer, @@ -159,7 +157,6 @@ export default class WaTreeItem extends WebAwesomeElement { private async animateExpand() { this.dispatchEvent(new WaExpandEvent()); - await stopAnimations(this.childrenContainer); this.childrenContainer.hidden = false; // We can't animate to 'auto', so use the scroll height for now const duration = parseDuration(getComputedStyle(this.childrenContainer).getPropertyValue('--show-duration')); diff --git a/src/internal/animate.ts b/src/internal/animate.ts index 2d5a84a32..c6c90778b 100644 --- a/src/internal/animate.ts +++ b/src/internal/animate.ts @@ -11,14 +11,29 @@ export async function animate(el: Element, keyframes: Keyframe[], options?: Keyf */ export function animateWithClass(el: Element, className: string) { return new Promise(resolve => { + el.classList.remove(className) + const controller = new AbortController() + const { signal } = controller + el.classList.add(className); el.addEventListener( 'animationend', () => { el.classList.remove(className); resolve(); + controller.abort() }, - { once: true } + { once: true, signal } + ); + + el.addEventListener( + 'animationcancel', + () => { + el.classList.remove(className); + resolve(); + controller.abort() + }, + { once: true, signal } ); }); } @@ -43,20 +58,3 @@ export function prefersReducedMotion() { const query = window.matchMedia('(prefers-reduced-motion: reduce)'); return query.matches; } - -/** - * Stops all active animations on the target element. Returns a promise that resolves after all animations are canceled. - */ -export function stopAnimations(el: HTMLElement) { - return Promise.all( - el.getAnimations().map(animation => { - return new Promise(resolve => { - const handleAnimationEvent = requestAnimationFrame(resolve); - - animation.addEventListener('cancel', () => handleAnimationEvent, { once: true }); - animation.addEventListener('finish', () => handleAnimationEvent, { once: true }); - animation.cancel(); - }); - }) - ); -}