bare routes lacked a scrollport under overflow:hidden html/body. wide rich-text tables used overflow-x:auto alone, which computes overflow-y:auto and traps vertical touch on iphone. force ink palette on /s/* for a consistent public share look.
45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
import { headers } from "next/headers";
|
|
import type { NavStyle } from "@/modules/_core/themes";
|
|
import type { DashboardMeta } from "@/app/d/actions";
|
|
import { Sidebar } from "@/components/sidebar";
|
|
import { Topbar } from "@/components/topbar";
|
|
import { BottomNav } from "@/components/bottom-nav";
|
|
import { NavModeProvider } from "@/components/nav-mode-provider";
|
|
|
|
const BARE_PREFIXES = ["/s/", "/login"];
|
|
|
|
interface Props {
|
|
signedIn: boolean;
|
|
navStyle: NavStyle;
|
|
dashboards: DashboardMeta[];
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export async function AppShell({ signedIn, navStyle, children }: Props) {
|
|
const h = await headers();
|
|
const pathname = h.get("x-pathname") ?? "";
|
|
const bare = BARE_PREFIXES.some(
|
|
(p) => pathname === p || pathname.startsWith(p + "/") || pathname === p.replace(/\/$/, ""),
|
|
);
|
|
|
|
if (bare || !signedIn) {
|
|
// No shell — share viewer and signed-out pages render bare.
|
|
// html/body are overflow:hidden for the app grid; bare pages need their own scroller.
|
|
return <div className="bare-scroll">{children}</div>;
|
|
}
|
|
|
|
const useTopVariant = navStyle === "top-nav";
|
|
|
|
return (
|
|
<div className="app">
|
|
{useTopVariant ? <Sidebar variant="top" /> : <Sidebar variant="side" />}
|
|
<main className="main">
|
|
<Topbar />
|
|
<div className="scroll-area">{children}</div>
|
|
</main>
|
|
<BottomNav />
|
|
<NavModeProvider navStyle={navStyle} />
|
|
</div>
|
|
);
|
|
}
|