You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(ssr-overlay): render admin-sidebar gutter via CSS var so logged-in reload doesn't shift
Follow-up to #1321 (the anti-flicker SSR overlay, merged into `customer/vsb-tuo`).
## Problem
With the overlay in place, an authenticated user's hard reload still showed the whole page jump right
by the admin-sidebar width when the SSR snapshot was removed. (Anonymous users were already smooth —
they have no sidebar.)
## Root cause (independent of the overlay; the overlay just makes it a visible "reveal")
The `.outer-wrapper` left gutter came from the `@slideSidebarPadding` Angular animation, whose width is
read via `cssService.getVariable('--ds-admin-sidebar-*')`. That store is populated only in the browser
(`AppComponent.storeCSSVariables` -> `getComputedStyle`); on the server it stays empty, `skipWhile(!val)`
blocks forever, and the animation renders `outer-wrapper { padding-left: 0 }`. The browser then resolves
the real width (e.g. 55px), so the authenticated page (and the SSR snapshot, which is just that server
HTML) jumps right on reveal.
## Fix
Drive the gutter from a CSS class (`ds-admin-sidebar-{hidden,unpinned,pinned}`, set from a small
`sidebarPaddingState$`) whose `padding-left` is `var(--ds-admin-sidebar-fixed-element-width)` /
`--ds-admin-sidebar-total-width`. CSS resolves those custom properties identically on the server (the
snapshot) and the browser (the live app), so they always match — no hardcoded pixel width, fully
theme-overridable and viewport/media-query aware. The `@slideSidebarPadding` animation (which can't take
a `var()` value and is stripped to empty on SSR) is no longer used here; the unused import/registration
is dropped from the base and custom-theme root components. Non-admins are unaffected ('hidden' -> 0).
The pin/unpin slide is preserved via `transition: padding-left`, but GATED behind a
`ds-admin-sidebar-animate` class enabled only after the first browser paint (`gutterTransitionEnabled`).
This stops the initial SSR->CSR gutter resolution — which happens behind the overlay — from animating and
leaking a 300ms slide right as the overlay is removed (the overlay's settle detector watches DOM
mutations, not style changes). Addresses review feedback (3 independent SSR/DSpace reviewers).
## Verification (authenticated admin, real UA, throttled hard reload, local SSR build)
- SSR HTML renders `<div class="outer-wrapper ds-admin-sidebar-unpinned">` — a class, no inline px, and
no `ds-admin-sidebar-animate` (transition correctly off on the server / initial paint).
- snapshot vs settled `#main-content`: desktop 55/55 -> shift 0px; mobile (375px) 55/55 -> shift 0px;
the live app gains `ds-admin-sidebar-animate` only after first paint.
Refs: dspace-customers#725, #1321
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0 commit comments