fix(nav): remove backdrop div so the account popover frosts
The full-screen transparent dismiss backdrop sat directly behind the popover and acted as a compositing layer, so the popover's backdrop-filter sampled it (empty) instead of the page — making the glass look fully solid. Drop the backdrop and dismiss via document mousedown/Escape listeners (like the other menus). Now backdrop-filter samples real content and the frost shows.
This commit is contained in:
parent
a18924bf97
commit
ed2d76f92d
1 changed files with 29 additions and 9 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import { useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
|
|
@ -37,6 +37,7 @@ export default function NavSidebar({
|
||||||
);
|
);
|
||||||
const [acctOpen, setAcctOpen] = useState(false);
|
const [acctOpen, setAcctOpen] = useState(false);
|
||||||
const acctBtnRef = useRef<HTMLButtonElement | null>(null);
|
const acctBtnRef = useRef<HTMLButtonElement | null>(null);
|
||||||
|
const acctPanelRef = useRef<HTMLDivElement | null>(null);
|
||||||
// Popover position (fixed, viewport coords). It's portaled to <body> so it escapes the
|
// Popover position (fixed, viewport coords). It's portaled to <body> so it escapes the
|
||||||
// nav's backdrop-filter, which would otherwise trap fixed positioning + stacking and let
|
// nav's backdrop-filter, which would otherwise trap fixed positioning + stacking and let
|
||||||
// clicks fall through to the controls behind it.
|
// clicks fall through to the controls behind it.
|
||||||
|
|
@ -50,6 +51,27 @@ export default function NavSidebar({
|
||||||
setAcctOpen((o) => !o);
|
setAcctOpen((o) => !o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dismiss on outside click / Escape via document listeners — NOT a full-screen backdrop
|
||||||
|
// div, which (sitting between the popover and the page) would break the popover's
|
||||||
|
// backdrop-filter and make it look solid.
|
||||||
|
useEffect(() => {
|
||||||
|
if (!acctOpen) return;
|
||||||
|
function onDoc(e: MouseEvent) {
|
||||||
|
const t = e.target as Node;
|
||||||
|
if (acctPanelRef.current?.contains(t) || acctBtnRef.current?.contains(t)) return;
|
||||||
|
setAcctOpen(false);
|
||||||
|
}
|
||||||
|
function onKey(e: KeyboardEvent) {
|
||||||
|
if (e.key === "Escape") setAcctOpen(false);
|
||||||
|
}
|
||||||
|
document.addEventListener("mousedown", onDoc);
|
||||||
|
document.addEventListener("keydown", onKey);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", onDoc);
|
||||||
|
document.removeEventListener("keydown", onKey);
|
||||||
|
};
|
||||||
|
}, [acctOpen]);
|
||||||
|
|
||||||
function toggleCollapsed() {
|
function toggleCollapsed() {
|
||||||
setCollapsed((c) => {
|
setCollapsed((c) => {
|
||||||
const next = !c;
|
const next = !c;
|
||||||
|
|
@ -157,9 +179,8 @@ export default function NavSidebar({
|
||||||
|
|
||||||
{acctOpen &&
|
{acctOpen &&
|
||||||
createPortal(
|
createPortal(
|
||||||
<>
|
|
||||||
<div className="fixed inset-0 z-40" onClick={() => setAcctOpen(false)} />
|
|
||||||
<div
|
<div
|
||||||
|
ref={acctPanelRef}
|
||||||
style={{ position: "fixed", left: acctPos.left, bottom: acctPos.bottom }}
|
style={{ position: "fixed", left: acctPos.left, bottom: acctPos.bottom }}
|
||||||
className="glass w-60 rounded-xl p-3 z-50 animate-[popIn_0.16s_ease]"
|
className="glass w-60 rounded-xl p-3 z-50 animate-[popIn_0.16s_ease]"
|
||||||
>
|
>
|
||||||
|
|
@ -199,8 +220,7 @@ export default function NavSidebar({
|
||||||
{t("header.account.signOut")}
|
{t("header.account.signOut")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>,
|
||||||
</>,
|
|
||||||
document.body
|
document.body
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue