Skip to content

Commit 8057bf6

Browse files
committed
Merge branch 'optimize-dom' into feat-spreadsheet
2 parents c071257 + d6705b9 commit 8057bf6

File tree

2 files changed

+68
-58
lines changed

2 files changed

+68
-58
lines changed

v2/pink-sb/src/lib/Popover.svelte

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
2-
import { onMount, hasContext } from 'svelte';
2+
import { fade } from 'svelte/transition';
3+
import { hasContext, tick } from 'svelte';
34
import { activePopover } from './context.js';
45
import type { Placement } from '@floating-ui/dom';
56
import { computePosition, autoUpdate, shift, offset, flip } from '@floating-ui/dom';
@@ -60,10 +61,12 @@
6061
6162
async function update() {
6263
if (!referenceElement || !tooltipElement) return;
64+
6365
const firstChild = referenceElement.firstElementChild;
6466
if (!(firstChild instanceof HTMLElement)) {
6567
return;
6668
}
69+
6770
const { x, y } = await computePosition(firstChild, tooltipElement, {
6871
placement,
6972
middleware: [offset(2), flip(), shift()]
@@ -96,25 +99,37 @@
9699
};
97100
}
98101
99-
onMount(() => autoUpdate(referenceElement, tooltipElement, update));
102+
function autoUpdateAction(_: HTMLDivElement) {
103+
tick().then(() => {
104+
if (!referenceElement || !tooltipElement) return;
105+
106+
const cleanup = autoUpdate(referenceElement, tooltipElement, update);
107+
return { destroy: cleanup };
108+
});
109+
}
100110
</script>
101111

102112
<svelte:window on:click={onBlur} on:keydown={onKeyDown} on:resize={update} />
103113

104114
<span aria-describedby={id} bind:this={referenceElement}>
105115
<slot showing={showTooltip} {toggle} {update} {show} {hide} />
106116
</span>
107-
<div
108-
{id}
109-
role="tooltip"
110-
aria-hidden={!showTooltip}
111-
bind:this={tooltipElement}
112-
class:padding-m={padding === 'm'}
113-
class:padding-none={padding === 'none'}
114-
use:portalPopover
115-
>
116-
<slot showing={showTooltip} {toggle} {update} {show} {hide} name="tooltip" />
117-
</div>
117+
118+
{#if showTooltip}
119+
<div
120+
{id}
121+
role="tooltip"
122+
aria-hidden="false"
123+
bind:this={tooltipElement}
124+
class:padding-m={padding === 'm'}
125+
class:padding-none={padding === 'none'}
126+
use:portalPopover
127+
use:autoUpdateAction
128+
transition:fade={{ duration: 150 }}
129+
>
130+
<slot showing={showTooltip} {toggle} {update} {show} {hide} name="tooltip" />
131+
</div>
132+
{/if}
118133

119134
<style lang="scss">
120135
span {

v2/pink-sb/src/lib/Tooltip.svelte

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
2+
import { tick } from 'svelte';
23
import type { Placement } from '@floating-ui/dom';
34
import { autoUpdate, computePosition, flip, offset, shift } from '@floating-ui/dom';
4-
import { onMount } from 'svelte';
55
66
export let placement: Placement | undefined = undefined;
77
export let padding: 'none' | 'm' = 'm';
@@ -25,10 +25,13 @@
2525
}
2626
2727
async function update() {
28+
if (!referenceElement || !tooltipElement) return;
29+
2830
const firstChild = referenceElement.firstElementChild;
2931
if (!(firstChild instanceof HTMLElement)) {
3032
return;
3133
}
34+
3235
const { x, y } = await computePosition(firstChild, tooltipElement, {
3336
placement,
3437
middleware: [offset(offsetAmount), flip(), shift()]
@@ -40,7 +43,24 @@
4043
});
4144
}
4245
43-
onMount(() => autoUpdate(referenceElement, tooltipElement, update));
46+
function fadeSlide(_: Node, { y = 8, duration = 200 } = {}) {
47+
return {
48+
duration,
49+
css: (time: number) => `
50+
opacity: ${time};
51+
transform: translateY(${(1 - time) * y}px);
52+
`
53+
};
54+
}
55+
56+
function autoUpdateAction(_: HTMLDivElement) {
57+
tick().then(() => {
58+
if (!referenceElement || !tooltipElement) return;
59+
60+
const cleanup = autoUpdate(referenceElement, tooltipElement, update);
61+
return { destroy: cleanup };
62+
});
63+
}
4464
</script>
4565

4666
<svelte:window on:resize={update} />
@@ -57,19 +77,24 @@
5777
>
5878
<slot {showing} {update} />
5979
</span>
60-
<div
61-
{id}
62-
on:transitionend={() => (showing = false)}
63-
bind:this={tooltipElement}
64-
aria-hidden={!show}
65-
class:padding-none={padding === 'none'}
66-
class:padding-m={padding === 'm'}
67-
role="tooltip"
68-
style:max-inline-size={maxWidth}
69-
data-state={!show ? 'closed' : 'open'}
70-
>
71-
<slot {showing} {update} name="tooltip" />
72-
</div>
80+
81+
{#if show}
82+
<div
83+
{id}
84+
transition:fadeSlide
85+
use:autoUpdateAction
86+
on:transitionend={() => (showing = false)}
87+
bind:this={tooltipElement}
88+
aria-hidden={!show}
89+
class:padding-none={padding === 'none'}
90+
class:padding-m={padding === 'm'}
91+
role="tooltip"
92+
style:max-inline-size={maxWidth}
93+
data-state={!show ? 'closed' : 'open'}
94+
>
95+
<slot {showing} {update} name="tooltip" />
96+
</div>
97+
{/if}
7398

7499
<style lang="scss">
75100
[role='note'] {
@@ -88,7 +113,6 @@
88113
color: var(--fgcolor-on-invert);
89114
visibility: hidden;
90115
opacity: 0;
91-
transition: visibility 0s linear 0.2s;
92116
z-index: 9002;
93117
94118
&[aria-hidden='false'] {
@@ -104,34 +128,5 @@
104128
padding: var(--space-2) var(--space-4);
105129
}
106130
}
107-
108-
&[data-state='open'] {
109-
animation: pink-tooltip-enter 0.2s ease-out;
110-
}
111-
112-
&[data-state='closed'] {
113-
animation: pink-tooltip-exit 0.2s ease-out;
114-
}
115-
}
116-
@keyframes pink-tooltip-enter {
117-
from {
118-
opacity: 0;
119-
transform: translateY(0.5rem);
120-
}
121-
to {
122-
opacity: 1;
123-
transform: translateY(0);
124-
}
125-
}
126-
127-
@keyframes pink-tooltip-exit {
128-
from {
129-
opacity: 1;
130-
transform: translateY(0);
131-
}
132-
to {
133-
opacity: 0;
134-
transform: translateY(0.5rem);
135-
}
136131
}
137132
</style>

0 commit comments

Comments
 (0)