Skip to content

Commit 6bb66fc

Browse files
authored
Merge pull request #321 from pathsim/fix/editor-logo-tooltip
Remove editor logo overlay, fix tooltip edge clamping
2 parents d9d35a8 + 51398c0 commit 6bb66fc

2 files changed

Lines changed: 40 additions & 55 deletions

File tree

src/lib/components/Tooltip.svelte

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -77,26 +77,8 @@
7777
break;
7878
}
7979
80-
// Clamp horizontal position to keep tooltip within viewport
81-
if (finalPosition === 'bottom' || finalPosition === 'top') {
82-
const halfWidth = tooltipMaxWidth / 2;
83-
if (x - halfWidth < padding) {
84-
x = padding + halfWidth;
85-
} else if (x + halfWidth > window.innerWidth - padding) {
86-
x = window.innerWidth - padding - halfWidth;
87-
}
88-
}
89-
90-
// Clamp vertical position for left/right tooltips
91-
if (finalPosition === 'left' || finalPosition === 'right') {
92-
const halfHeight = tooltipHeight / 2;
93-
if (y - halfHeight < padding) {
94-
y = padding + halfHeight;
95-
} else if (y + halfHeight > window.innerHeight - padding) {
96-
y = window.innerHeight - padding - halfHeight;
97-
}
98-
}
99-
80+
// Viewport clamping happens in the component after render,
81+
// where the actual tooltip dimensions can be measured.
10082
tooltipStore.set({ text, shortcut, maxWidth, x, y, visible: true, position: finalPosition });
10183
}, 50);
10284
}
@@ -152,21 +134,51 @@
152134
</script>
153135

154136
<script lang="ts">
155-
let state = $state<TooltipState>({ text: '', x: 0, y: 0, visible: false, position: 'bottom' });
137+
let tip = $state<TooltipState>({ text: '', x: 0, y: 0, visible: false, position: 'bottom' });
138+
let tooltipEl = $state<HTMLDivElement>();
156139
157140
tooltipStore.subscribe((s) => {
158-
state = s;
141+
tip = s;
142+
});
143+
144+
// Clamp the rendered tooltip to the viewport using its measured size,
145+
// so narrow tooltips sit flush at the edges instead of being pushed
146+
// inward by a max-width estimate.
147+
$effect(() => {
148+
if (!tip.visible || !tooltipEl) return;
149+
void tip.text; void tip.shortcut; void tip.position;
150+
const padding = 8; // Minimum distance from viewport edge
151+
// Measure from the unclamped anchor position — a previous run may
152+
// have shifted the element while Svelte skipped the style attribute.
153+
tooltipEl.style.left = `${tip.x}px`;
154+
tooltipEl.style.top = `${tip.y}px`;
155+
const rect = tooltipEl.getBoundingClientRect();
156+
let dx = 0;
157+
let dy = 0;
158+
if (rect.left < padding) {
159+
dx = padding - rect.left;
160+
} else if (rect.right > window.innerWidth - padding) {
161+
dx = window.innerWidth - padding - rect.right;
162+
}
163+
if (rect.top < padding) {
164+
dy = padding - rect.top;
165+
} else if (rect.bottom > window.innerHeight - padding) {
166+
dy = window.innerHeight - padding - rect.bottom;
167+
}
168+
if (dx !== 0) tooltipEl.style.left = `${tip.x + dx}px`;
169+
if (dy !== 0) tooltipEl.style.top = `${tip.y + dy}px`;
159170
});
160171
</script>
161172

162-
{#if state.visible}
173+
{#if tip.visible}
163174
<div
164-
class="tooltip tooltip-{state.position}"
165-
style="left: {state.x}px; top: {state.y}px;{state.maxWidth ? ` max-width: ${state.maxWidth}px;` : ''}"
175+
bind:this={tooltipEl}
176+
class="tooltip tooltip-{tip.position}"
177+
style="left: {tip.x}px; top: {tip.y}px;{tip.maxWidth ? ` max-width: ${tip.maxWidth}px;` : ''}"
166178
>
167-
<span class="text">{state.text}</span>
168-
{#if state.shortcut}
169-
<span class="shortcut">{state.shortcut}</span>
179+
<span class="text">{tip.text}</span>
180+
{#if tip.shortcut}
181+
<span class="shortcut">{tip.shortcut}</span>
170182
{/if}
171183
</div>
172184
{/if}

src/routes/+page.svelte

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,11 +1366,6 @@
13661366
</div>
13671367
</header>
13681368

1369-
<!-- Logo overlay: stays over the canvas, below the fixed nav. -->
1370-
<button class="logo-overlay" onclick={() => showWelcomeModal = true} use:tooltip={"Welcome"} aria-label="Welcome">
1371-
<img src="{base}/{BRAND.logo}" alt="{BRAND.name}" />
1372-
</button>
1373-
13741369
<!-- Canvas takes full screen -->
13751370
<div class="canvas-layer">
13761371
<FlowCanvas />
@@ -1840,27 +1835,6 @@
18401835
.editor-nav .brand { margin-right: var(--space-xs); }
18411836
/* Push the top-anchored floating overlays below the fixed nav. */
18421837
.app.has-nav .subsystem-breadcrumb { top: calc(var(--space-md) + var(--header-height)); }
1843-
.app.has-nav .logo-overlay { top: calc(var(--space-md) + var(--header-height)); }
1844-
1845-
/* Logo overlay — stays over the canvas, below the fixed nav. */
1846-
.logo-overlay {
1847-
position: fixed;
1848-
top: var(--space-md);
1849-
left: var(--space-md);
1850-
z-index: 100;
1851-
background: none;
1852-
border: none;
1853-
padding: 0;
1854-
cursor: pointer;
1855-
}
1856-
.logo-overlay img {
1857-
height: 44px;
1858-
width: auto;
1859-
transition: opacity var(--transition-fast);
1860-
}
1861-
.logo-overlay:hover img {
1862-
opacity: 0.8;
1863-
}
18641838
18651839
.toolbar-btn {
18661840
width: var(--header-height);
@@ -2064,7 +2038,6 @@
20642038
pointer-events: none;
20652039
}
20662040
2067-
/* Logo overlay */
20682041
/* Subsystem breadcrumb navigation */
20692042
.subsystem-breadcrumb {
20702043
position: fixed;

0 commit comments

Comments
 (0)