improvement(scroll): fade the page scroller's clipped edges
The subdued edge-fade the rail and side panels use now hints at more content on the page scroller too, which the feed, the channel page and Plex all scroll inside. Both <main>s move into one PageScroller so the invariants they share — the load-bearing scrollbar gutter, and the bar staying visible because hiding it would zero that gutter — are stated once. Two fixes the hook needed first: it set fresh state on every scroll event, which above a page tree would re-render it per frame; and it watched a single child captured at mount, so a lazy page swapping out its Suspense fallback left the observer on a detached node and the fade frozen at its pre-load value (measured on the Plex page: no bottom fade over a 3119px list).
This commit is contained in:
@@ -54,6 +54,7 @@ import NavSidebar from "./components/NavSidebar";
|
||||
import Sidebar from "./components/Sidebar";
|
||||
import PlaylistsRail from "./components/PlaylistsRail";
|
||||
import BackToTop from "./components/BackToTop";
|
||||
import PageScroller from "./components/PageScroller";
|
||||
import GlassTuner from "./components/GlassTuner";
|
||||
import ChatDock from "./components/ChatDock";
|
||||
import Toaster from "./components/Toaster";
|
||||
@@ -898,13 +899,7 @@ export default function App() {
|
||||
>
|
||||
{meQuery.data!.is_demo && <DemoBanner />}
|
||||
<VersionBanner onOpen={() => openReleaseNotes(CURRENT_VERSION)} />
|
||||
{/* scrollbar-gutter: stable is load-bearing, not cosmetic. The feed derives its column
|
||||
count from this element's clientWidth and its thumbnails are aspect-ratio boxes, so
|
||||
when the content lands within a scrollbar's width of the viewport height the two feed
|
||||
each other: scrollbar appears -> 15px narrower -> shorter thumbs -> content fits ->
|
||||
scrollbar goes -> wider -> taller -> repeat, every frame. Reserving the gutter keeps
|
||||
clientWidth constant and breaks the loop. */}
|
||||
<main className="flex-1 min-w-0 overflow-y-auto [scrollbar-gutter:stable]">
|
||||
<PageScroller>
|
||||
<Suspense fallback={pageFallback}>
|
||||
{page === "channels" ? (
|
||||
<Channels
|
||||
@@ -986,7 +981,7 @@ export default function App() {
|
||||
/>
|
||||
)}
|
||||
</Suspense>
|
||||
</main>
|
||||
</PageScroller>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user