fix(dashboard): portal MobileNavBar to document.body for robust fixed positioning
vpdebug on Android tablet captured the nav bar's getBoundingClientRect at y=2800 with html height 798 — meaning some ancestor was creating a containing block for the bar's `position: fixed`, putting it 2000+ px below the visible window. Any ancestor with `transform`, `filter`, `will-change`, or `contain: paint` would do that, and it's hard to audit which of our many ancestors (providers, view wrappers, plugin hosts) introduces one in a given Android Chrome state. Sidestep the whole question: render the bar via createPortal into document.body. Its only ancestor is body, so `position: fixed; bottom: 0` is now guaranteed to pin to the visual viewport bottom. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import "./MobileNavBar.css";
|
import "./MobileNavBar.css";
|
||||||
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from "react";
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from "react";
|
||||||
|
import { createPortal } from "react-dom";
|
||||||
import {
|
import {
|
||||||
Activity,
|
Activity,
|
||||||
Bot,
|
Bot,
|
||||||
@@ -296,7 +297,12 @@ export function MobileNavBar({
|
|||||||
|| view === "stash-recovery"
|
|| view === "stash-recovery"
|
||||||
|| (isPluginViewId(view) && !topLevelPrimaryPluginViews.some((entry) => buildPluginTaskViewId(entry.pluginId, entry.view.viewId) === view));
|
|| (isPluginViewId(view) && !topLevelPrimaryPluginViews.some((entry) => buildPluginTaskViewId(entry.pluginId, entry.view.viewId) === view));
|
||||||
|
|
||||||
return (
|
// Portal the bar directly into document.body so its `position: fixed`
|
||||||
|
// can't be hijacked by an ancestor's containing block (any ancestor with
|
||||||
|
// transform/filter/will-change/contain creates a fixed-positioning
|
||||||
|
// containing block — and we hit exactly that on Android tablet, leaving
|
||||||
|
// the bar positioned far below the visible window).
|
||||||
|
const content = (
|
||||||
<>
|
<>
|
||||||
<nav
|
<nav
|
||||||
ref={navRef}
|
ref={navRef}
|
||||||
@@ -837,4 +843,6 @@ export function MobileNavBar({
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
if (typeof document === "undefined") return content;
|
||||||
|
return createPortal(content, document.body);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user