fix(ssr-overlay): render admin-sidebar gutter on the server so logged-in reload doesn't shift#1333
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
5b91e72 to
75fca50
Compare
…n 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>
75fca50 to
13d73fa
Compare
Review summaryReviewed for SSR correctness, DSpace regressions, and "does it actually solve the flicker / can it break anything". Verdict: correct, no layout regression, solves the reported symptom for the right reason. Why the SSR snapshot matches the live app (the core guarantee):
Review feedback addressed in
Verified (authenticated admin, real UA, throttled hard reload, local SSR build): SSR renders Honest residuals (pre-existing, not introduced here, out of scope):
|
Follow-up to #1321 (the anti-flicker SSR overlay, already 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-wrapperleft gutter came from the@slideSidebarPaddingAngular animation, whose width is read viacssService.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 rendersouter-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 — no hardcoded width
Drive the gutter from a CSS class (
ds-admin-sidebar-{hidden,unpinned,pinned}, set from a smallsidebarPaddingState$) whosepadding-leftisvar(--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 — theme-overridable and viewport/media-query aware, with zero magic pixels — and atransition: padding-leftkeeps the pin/unpin slide. The@slideSidebarPaddinganimation isn't used here anymore (it can't take avar()value — Angular strips it to empty on SSR — which is exactly why the pure-CSS route is needed). Non-admins are unaffected (hidden→ padding 0).Verification (authenticated admin, real UA, throttled hard reload, local SSR build)
<div class="outer-wrapper … ds-admin-sidebar-unpinned">(a class, no inline px).#main-content:Refs: dspace-customers#725, #1321
🤖 Generated with Claude Code