Skip to content

Commit 927c3f4

Browse files
authored
Improve tooltiips UX (#11381)
* remove duplicated Toggle.story * feat(tooltip): make subsequent tooltips show instantly when one is visible, add global tracking * remove unnecessary delays
1 parent 4c1c95f commit 927c3f4

File tree

5 files changed

+83
-27
lines changed

5 files changed

+83
-27
lines changed

apps/desktop/src/components/CollapseStackButton.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
}
3131
</script>
3232

33-
<Tooltip text={isFolded ? 'Expand stack' : 'Collapse stack'} delay={800}>
33+
<Tooltip text={isFolded ? 'Expand stack' : 'Collapse stack'}>
3434
<button
3535
class="collapse-button"
3636
class:isFolded

packages/ui/src/lib/components/LineStats.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</script>
1010

1111
{#if linesAdded > 0 || linesRemoved > 0}
12-
<Tooltip text="Lines added/removed" delay={1200}>
12+
<Tooltip text="Lines added/removed">
1313
<div class="line-stats text-11 text-semibold">
1414
{#if linesAdded > 0}
1515
<span class="added">+{linesAdded}</span>

packages/ui/src/lib/components/Tooltip.svelte

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<script lang="ts" module>
22
export type TooltipPosition = 'top' | 'bottom';
33
export type TooltipAlign = 'start' | 'center' | 'end';
4+
5+
// Global state to track if any tooltip is currently shown
6+
let anyTooltipShown = $state(false);
7+
let tooltipHideTimeout: ReturnType<typeof setTimeout> | undefined;
48
</script>
59

610
<script lang="ts">
@@ -44,6 +48,7 @@
4448
let position = $state(requestedPosition);
4549
let show = $state(false);
4650
let timeoutId: undefined | ReturnType<typeof setTimeout> = $state();
51+
let isInstant = $state(false);
4752
4853
const isTextEmpty = $derived(!text || text === '');
4954
@@ -68,14 +73,31 @@
6873
6974
function handleMouseEnter() {
7075
if (disabled) return;
71-
timeoutId = setTimeout(() => {
76+
77+
// If any tooltip is already shown, show this one instantly
78+
if (anyTooltipShown) {
79+
isInstant = true;
7280
show = true;
73-
}, delay);
81+
clearTimeout(tooltipHideTimeout);
82+
} else {
83+
isInstant = false;
84+
timeoutId = setTimeout(() => {
85+
show = true;
86+
anyTooltipShown = true;
87+
}, delay);
88+
}
7489
}
7590
7691
function handleMouseLeave() {
7792
clearTimeout(timeoutId);
7893
show = false;
94+
95+
// Reset the global state after a short delay
96+
// This allows for smooth transitions between tooltips
97+
clearTimeout(tooltipHideTimeout);
98+
tooltipHideTimeout = setTimeout(() => {
99+
anyTooltipShown = false;
100+
}, 100);
79101
}
80102
81103
function handleClick(e: MouseEvent) {
@@ -112,8 +134,10 @@
112134
use:portal={'body'}
113135
class="tooltip-container text-11 text-body"
114136
style:max-width="{pxToRem(maxWidth)}rem"
137+
data-instant={isInstant ? true : undefined}
115138
transition:flyScale={{
116-
position: position
139+
position: position,
140+
duration: 150
117141
}}
118142
>
119143
<span>{text}</span>

packages/ui/src/stories/components/Toggle.stories.svelte

Lines changed: 0 additions & 22 deletions
This file was deleted.

packages/ui/src/stories/components/Tooltip.stories.svelte

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,38 @@
6363

6464
<Story name="Playground" />
6565

66+
<Story name="Multiple Tooltips">
67+
{#snippet template()}
68+
<div class="wrapper">
69+
<p class="text-13 text">Hover over these items quickly to test instant tooltips:</p>
70+
<div class="tooltip-grid">
71+
<Tooltip text="First tooltip">
72+
<button type="button" class="test-button">Item 1</button>
73+
</Tooltip>
74+
<Tooltip text="Second tooltip">
75+
<button type="button" class="test-button">Item 2</button>
76+
</Tooltip>
77+
<Tooltip text="Third tooltip">
78+
<button type="button" class="test-button">Item 3</button>
79+
</Tooltip>
80+
<Tooltip text="Fourth tooltip">
81+
<button type="button" class="test-button">Item 4</button>
82+
</Tooltip>
83+
<Tooltip text="Fifth tooltip">
84+
<button type="button" class="test-button">Item 5</button>
85+
</Tooltip>
86+
<Tooltip text="Sixth tooltip">
87+
<button type="button" class="test-button">Item 6</button>
88+
</Tooltip>
89+
</div>
90+
<p class="text-13 text" style="margin-top: 20px;">
91+
The first tooltip has a 500ms delay. Once shown, move between items quickly - subsequent
92+
tooltips appear instantly without delay or animation.
93+
</p>
94+
</div>
95+
{/snippet}
96+
</Story>
97+
6698
<style>
6799
.wrapper {
68100
display: flex;
@@ -78,4 +110,26 @@
78110
text-decoration: underline;
79111
text-decoration-style: dotted;
80112
}
113+
114+
.tooltip-grid {
115+
display: grid;
116+
grid-template-columns: repeat(3, 1fr);
117+
margin-top: 20px;
118+
gap: 16px;
119+
}
120+
121+
.test-button {
122+
padding: 12px 24px;
123+
border: 1px solid var(--clr-border-2);
124+
border-radius: var(--radius-m);
125+
background: var(--clr-bg-1);
126+
color: var(--clr-text-1);
127+
cursor: pointer;
128+
transition: all 0.15s ease;
129+
}
130+
131+
.test-button:hover {
132+
border-color: var(--clr-border-3);
133+
background: var(--clr-bg-2);
134+
}
81135
</style>

0 commit comments

Comments
 (0)