fix tooltip docs, remove stopAnimations

This commit is contained in:
konnorrogers
2024-06-11 13:07:49 -04:00
parent 9c17b0e16b
commit ca524a03f3
5 changed files with 44 additions and 72 deletions

View File

@@ -207,9 +207,8 @@ const App = () => (
Set the `trigger` attribute to `click` to toggle the tooltip on click instead of hover.
```html {.example}
<wa-tooltip content="Click again to dismiss" trigger="click">
<wa-button>Click to Toggle</wa-button>
</wa-tooltip>
<wa-button id="toggle-button">Click to Toggle</wa-button>
<wa-tooltip for="toggle-button" trigger="click">Click again to dismiss</wa-tooltip>
```
{% 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}
<wa-button style="margin-right: 4rem;">Toggle Manually</wa-button>
<wa-button id="manual-trigger" style="margin-right: 4rem;">Toggle Manually</wa-button>
<wa-tooltip content="This is an avatar" trigger="manual" class="manual-tooltip">
<wa-tooltip for="manual-trigger" trigger="manual" class="manual-tooltip">
<wa-avatar label="User"></wa-avatar>
</wa-tooltip>
@@ -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}
<wa-tooltip content="This is a tooltip" style="--wa-tooltip-arrow-size: 0;">
<wa-button>No Arrow</wa-button>
</wa-tooltip>
<wa-button id="no-arrow">No Arrow</wa-button>
<wa-tooltip for="no-arrow" style="--wa-tooltip-arrow-size: 0;">This is a tooltip with no arrow</wa-tooltip>
```
{% 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}
<wa-tooltip>
<div slot="content">I'm not <strong>just</strong> a tooltip, I'm a <em>tooltip</em> with HTML!</div>
<wa-button>Hover me</wa-button>
<wa-button id="rich-tooltip">Hover me</wa-button>
<wa-tooltip for="rich-tooltip">
<div>I'm not <strong>just</strong> a tooltip, I'm a <em>tooltip</em> with HTML!</div>
</wa-tooltip>
```
@@ -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}
<wa-tooltip style="--max-width: 80px;" content="This tooltip will wrap after only 80 pixels.">
<wa-button>Hover me</wa-button>
<wa-tooltip for="wrapping-tooltip" style="--max-width: 80px;">
This tooltip will wrap after only 80 pixels.
</wa-tooltip>
<wa-button id="wrapping-tooltip">Hover me</wa-button>
```
{% raw %}
@@ -364,20 +362,20 @@ Tooltips will be clipped if they're inside a container that has `overflow: auto|
```html {.example}
<div class="tooltip-hoist">
<wa-tooltip content="This is a tooltip">
<wa-button>No Hoist</wa-button>
</wa-tooltip>
<wa-tooltip for="no-hoist">This is a tooltip</wa-tooltip>
<wa-button id="no-hoist">No Hoist</wa-button>
<wa-tooltip content="This is a tooltip" hoist>
<wa-button>Hoist</wa-button>
<wa-tooltip for="hoist" hoist>
This is a tooltip
</wa-tooltip>
<wa-button id="hoist">Hoist</wa-button>
</div>
<style>
.tooltip-hoist {
position: relative;
border: solid 2px var(--wa-color-surface-border);
overflow: hidden;
border: solid 2px var(--wa-color-surface-border);
padding: var(--wa-space-m);
}
</style>

View File

@@ -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(

View File

@@ -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');
}

View File

@@ -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'));

View File

@@ -11,14 +11,29 @@ export async function animate(el: Element, keyframes: Keyframe[], options?: Keyf
*/
export function animateWithClass(el: Element, className: string) {
return new Promise<void>(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();
});
})
);
}