diff --git a/frontend/src/lib/components/NavBreadcrumb.svelte b/frontend/src/lib/components/NavBreadcrumb.svelte index bffb4b7c43..496a5c2ca4 100644 --- a/frontend/src/lib/components/NavBreadcrumb.svelte +++ b/frontend/src/lib/components/NavBreadcrumb.svelte @@ -197,8 +197,7 @@ same weight, size and icon size, so the line reads as one control rather than fo
- +
{#snippet children({ createMenu })} diff --git a/frontend/src/routes/(root)/(logged)/sessions/+page.svelte b/frontend/src/routes/(root)/(logged)/sessions/+page.svelte index 32b71510a7..c1acc47acc 100644 --- a/frontend/src/routes/(root)/(logged)/sessions/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/sessions/+page.svelte @@ -467,12 +467,7 @@ if (reducedMotion.val) return panesAnimating = true clearTimeout(panesAnimationTimer) - panesAnimationTimer = setTimeout(() => { - panesAnimating = false - // The panel's final width was measured while the writes above were suppressed, and a - // settled panel may get no further resize to publish it. - if (!fullscreen) panelWidth = previewWidth - }, PANES_MOVE_MS) + panesAnimationTimer = setTimeout(() => (panesAnimating = false), PANES_MOVE_MS) } onDestroy(() => clearTimeout(panesAnimationTimer)) /** The arriving strip fades in over the expansion; the leaving one goes quickly, so the two @@ -490,12 +485,21 @@ } // Width of the preview panel, so the band can stop where it starts. let previewWidth = $state(0) - /** The same width, excluding what the panel measures while it is expanding or contracting for - * a full-screen switch. The band's inset is read from this: fed the live measurement, the bar - * would be sized against a panel that has not arrived yet, and on the way back from full - * screen it starts at 146px — narrow enough that the bar wraps to two rows for a tenth of a - * second before the panel settles. */ - let panelWidth = $state(0) + /** Width of the row the panes share, so the panel can be remembered as a share of it. */ + let contentWidth = $state(0) + /** What share of that row the panel takes, sampled only while it is standing still. The band's + * inset is read from this for the length of a full-screen switch: fed the live measurement, + * the bar would be sized against a panel that has not arrived yet, and on the way back from + * full screen it starts at 146px — narrow enough that the bar wraps to two rows before the + * panel settles. A share rather than a width, so a window resized while full screen still + * gives the right inset on the way out. */ + let panelShare = $state(0) + const bandInset = $derived.by(() => { + if (fullscreen) return 0 + if (panesAnimating && panelShare > 0 && contentWidth > 0) + return Math.round(panelShare * contentWidth) + return previewCollapsed || previewWidth === 0 ? undefined : previewWidth + }) // Fullscreen is page state, not per-session, so it outlives a session switch — // tell the incoming session's model, whose own collapsed flag it overrides, or // re-opening the item plainly on screen would be judged invisible and not flash. @@ -955,15 +959,12 @@ - +
previewWidth, (w) => { previewWidth = w - if (!fullscreen && !panesAnimating) panelWidth = w + if (!fullscreen && !panesAnimating && contentWidth > 0) + panelShare = w / contentWidth }} class="flex-1 min-h-0 flex flex-col {fullscreen ? 'p-0 pt-11' : 'p-2 pl-0'}" > @@ -1321,9 +1325,9 @@ {/snippet} {#snippet previewTabStrip(inBand: boolean)} - +
:global(.splitpanes__pane) { - /* `!important` to beat app.css's blanket `transition: none !important` on vertical panes, + /* The duration comes from PANES_MOVE_MS, which also times how long the class stays on. + `!important` to beat app.css's blanket `transition: none !important` on vertical panes, which is there so a splitter drag tracks the pointer exactly. */ - transition: width 240ms cubic-bezier(0.33, 1, 0.68, 1) !important; + transition: width var(--panes-move) cubic-bezier(0.33, 1, 0.68, 1) !important; } /* Collapsed preview: the pane is resized to 0 but stays mounted, so remove