fix(plex): portal the full-screen player out of the page scroller
The player is `fixed left-0 top-0 z-50` but rendered from inside the page scroller, so it only ever covered the viewport because that scroller happened not to be a stacking context. Giving it the edge-fade made it one, and the mask scoped the player's z-50 inside it: the rail, the side panel and the header painted straight over the player, and its edges faded. Measured both ways, then fixed where every other full-screen overlay here already sits — <body>. Same for the Suspense fallback that stands in while the player chunk loads, and for the floating draft save bar on the Configuration page. Swept the rest: every other `fixed` element is either App-level or already portaled.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { createPortal } from "react-dom";
|
||||
import { Check, RotateCcw, Save } from "lucide-react";
|
||||
|
||||
// The Save / Discard bar shown while an edited draft has unsaved changes (Settings prefs,
|
||||
@@ -34,11 +35,15 @@ export function DraftSaveBar({
|
||||
}) {
|
||||
if (!dirty && state === "idle") return null;
|
||||
const saving = state === "saving";
|
||||
const wrap =
|
||||
variant === "floating"
|
||||
? "fixed bottom-4 left-1/2 -translate-x-1/2 z-40 glass rounded-2xl shadow-lg flex items-center justify-between gap-4 px-4 py-3 w-[min(48rem,calc(100%-2rem))]"
|
||||
: "flex items-center justify-between gap-3 border-t border-border/60 px-4 py-3 bg-card/40";
|
||||
return (
|
||||
const floating = variant === "floating";
|
||||
const wrap = floating
|
||||
? "fixed bottom-4 left-1/2 -translate-x-1/2 z-40 glass rounded-2xl shadow-lg flex items-center justify-between gap-4 px-4 py-3 w-[min(48rem,calc(100%-2rem))]"
|
||||
: "flex items-center justify-between gap-3 border-t border-border/60 px-4 py-3 bg-card/40";
|
||||
// The floating variant is fixed to the viewport but renders from a page inside the page
|
||||
// scroller, so it goes to <body> — otherwise the scroller's stacking context (its edge-fade
|
||||
// mask) scopes this z-40 and fades the bar's bottom edge. The inline variant is in normal flow
|
||||
// and stays put.
|
||||
const bar = (
|
||||
<div className={wrap}>
|
||||
<span className="text-sm text-muted">
|
||||
{state === "saved" ? (
|
||||
@@ -72,4 +77,5 @@ export function DraftSaveBar({
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return floating ? createPortal(bar, document.body) : bar;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user