fix: replace bind:clientHeight with calculated bottom chrome height

bind:clientHeight + $effect setting CSS variable caused infinite reflow
loop: height change → CSS var → padding change → height change.

Now using $derived calculation from state (isCollapsed, isTagStripVisible)
instead of DOM measurement. No reflow loop possible.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-03 12:34:42 +02:00
parent 9534d29967
commit d368bd34b5

View file

@ -66,17 +66,8 @@
let isCollapsed = $state(false);
let showShortcuts = $state(false);
let showOnboarding = $state(false);
let bottomStackHeight = $state(0);
// Expose bottom stack height as CSS custom property for components outside the stack
$effect(() => {
if (typeof document !== 'undefined') {
document.documentElement.style.setProperty(
'--bottom-chrome-height',
`${bottomStackHeight}px`
);
}
});
// Bottom chrome height: calculated from state, not measured (avoids reflow loop)
const bottomChromeHeight = $derived((isCollapsed ? 0 : 80) + (isTagStripVisible ? 44 : 0) + 72); // PillNav ~80px + TagStrip ~44px + QuickInputBar ~72px
// ── Theme ───────────────────────────────────────────────
let isDark = $derived(theme.isDark);
@ -384,7 +375,7 @@
<div class="min-h-screen bg-background">
<!-- Bottom Stack: all fixed-bottom elements in one flex container -->
<div class="bottom-stack" bind:clientHeight={bottomStackHeight}>
<div class="bottom-stack" style:--bottom-chrome-height="{bottomChromeHeight}px">
<!-- QuickInputBar with inline nav toggle -->
<QuickInputBar
onSearch={inputBarAdapter.onSearch}
@ -476,7 +467,7 @@
<DragPreview />
<!-- Main content -->
<main style="padding-bottom: calc(var(--bottom-chrome-height, 6rem) + 2rem)">
<main style="padding-bottom: {bottomChromeHeight + 32}px">
<div class="mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8">
{@render children()}
</div>
@ -564,7 +555,7 @@
.notification-float {
position: fixed;
bottom: var(--bottom-chrome-height, 8rem);
bottom: 10rem;
left: 50%;
transform: translateX(-50%);
z-index: 100;