fix(ui): correctly handle mobile breakpoints for the navbar

Fixes HP-529.
This commit is contained in:
Aarnav Tale
2026-04-20 21:45:40 -04:00
parent 9238f69bfc
commit 4d252833ef
3 changed files with 39 additions and 7 deletions
+1 -1
View File
@@ -111,7 +111,7 @@ export default function AppLayout({ loaderData }: Route.ComponentProps) {
configAvailable={loaderData.configAvailable} configAvailable={loaderData.configAvailable}
user={loaderData.user} user={loaderData.user}
/> />
<main className="container mt-4 mb-24 overscroll-contain"> <main className="container mt-4 mb-24 overflow-x-hidden overscroll-contain">
{!loaderData.isHealthy && ( {!loaderData.isHealthy && (
<StatusBanner <StatusBanner
className="mb-4" className="mb-4"
+37 -5
View File
@@ -46,10 +46,10 @@ export default function Header({ user, access, configAvailable }: HeaderProps) {
"dark:border-b dark:border-mist-800 shadow-inner", "dark:border-b dark:border-mist-800 shadow-inner",
)} )}
> >
<div className="container flex items-center justify-between py-4"> <div className="container flex items-center gap-x-4 py-4">
<div className="flex items-center gap-x-8"> <div className="flex min-w-0 items-center gap-x-4">
<div className="flex items-center gap-x-2"> <div className="flex items-center gap-x-2">
<picture> <picture className="min-w-8">
<source srcSet={logoLight} media="(prefers-color-scheme: dark)" /> <source srcSet={logoLight} media="(prefers-color-scheme: dark)" />
<source srcSet={logoDark} media="(prefers-color-scheme: light)" /> <source srcSet={logoDark} media="(prefers-color-scheme: light)" />
<img src={logoBg} alt="Headplane logo" /> <img src={logoBg} alt="Headplane logo" />
@@ -57,7 +57,7 @@ export default function Header({ user, access, configAvailable }: HeaderProps) {
<h1 className="text-2xl font-semibold">headplane</h1> <h1 className="text-2xl font-semibold">headplane</h1>
</div> </div>
{showTabs && ( {showTabs && (
<nav className="hidden items-center gap-x-2 text-sm font-medium md:flex"> <nav className="hidden items-center gap-x-2 overflow-x-auto p-1 text-sm font-medium md:flex">
{tabs.map((tab) => { {tabs.map((tab) => {
if (!access[tab.key]) return null; if (!access[tab.key]) return null;
if ((tab.key === "dns" || tab.key === "settings") && !configAvailable) return null; if ((tab.key === "dns" || tab.key === "settings") && !configAvailable) return null;
@@ -87,7 +87,7 @@ export default function Header({ user, access, configAvailable }: HeaderProps) {
</nav> </nav>
)} )}
</div> </div>
<div className="grid grid-cols-2 gap-x-4"> <div className="ml-auto grid shrink-0 grid-cols-2 gap-x-4">
<Menu> <Menu>
<MenuTrigger className="size-8 rounded-full p-1"> <MenuTrigger className="size-8 rounded-full p-1">
<CircleQuestionMark className="w-5" /> <CircleQuestionMark className="w-5" />
@@ -145,6 +145,38 @@ export default function Header({ user, access, configAvailable }: HeaderProps) {
</Menu> </Menu>
</div> </div>
</div> </div>
{showTabs && (
<div className="block overflow-x-auto p-2 md:hidden">
<nav className="flex items-center gap-x-2 text-sm font-medium">
{tabs.map((tab) => {
if (!access[tab.key]) return null;
if ((tab.key === "dns" || tab.key === "settings") && !configAvailable) return null;
return (
<NavLink
key={tab.to}
className={({ isActive }) =>
cn(
"relative px-3 py-1.5 flex items-center gap-x-1.5 rounded-md text-nowrap",
"hover:bg-mist-300/50 dark:hover:bg-mist-800",
"focus:outline-hidden focus:ring-2 focus:ring-indigo-500/40 focus:ring-offset-1",
"dark:focus:ring-indigo-400/40 dark:focus:ring-offset-mist-900",
"text-mist-600 dark:text-mist-300",
isActive &&
"text-mist-900 dark:text-mist-50 after:content-[''] after:absolute after:-bottom-2 after:inset-x-1 after:h-0.5 after:rounded-full after:bg-indigo-500",
)
}
prefetch="intent"
to={tab.to}
>
<tab.icon className="w-4" />
{tab.label}
</NavLink>
);
})}
</nav>
</div>
)}
</header> </header>
); );
} }
+1 -1
View File
@@ -32,7 +32,7 @@ export function Layout({ children }: { readonly children: React.ReactNode }) {
<Links /> <Links />
<link href={`${__PREFIX__}/favicon.ico`} rel="icon" /> <link href={`${__PREFIX__}/favicon.ico`} rel="icon" />
</head> </head>
<body className="overflow-x-hidden overscroll-none dark:bg-mist-900 dark:text-mist-50"> <body className="w-full overflow-x-hidden overscroll-none dark:bg-mist-900 dark:text-mist-50">
{children} {children}
<ToastProvider /> <ToastProvider />
<ScrollRestoration /> <ScrollRestoration />