fix(pwa): keep the status bar readable on the sign-in pages too

The light-theme fix painted the strip behind the white status bar only
in the signed-in shell. The sign-in, registration and take-over pages
and the onboarding shell padded the strip without painting it, so after
a sign-out in the installed iOS app the clock was white on near-white.
They now use the same shell-safe-area band.
This commit is contained in:
Marc-André Bombeck committed 2026-11-12 14:08:34 +01:00
1 parent e59ef4533d
commit 95a906b2a7
2 files changed
+51 -3

No files matched your search

@@ -0,0 +1,46 @@
/**
* The strip behind the status bar on the sign-in pages.
*
* The installed iOS app draws the clock in white over whatever the page
* paints there. The signed-in shell paints the strip; the sign-in pages only
* padded it, so after a sign-out in the light theme the clock was white on
* near-white.
*/
import { afterEach, describe, expect, it } from "vitest";
import { renderWithApp } from "../../../../tests/browser/render";
import { stubFetch } from "../../../../tests/browser/fetch-stub";
import { AuthShell } from "../auth-shell";
afterEach(() => {
document.documentElement.classList.remove("light");
document.documentElement.classList.add("dark");
});
describe("AuthShell status bar strip", () => {
it("is painted on the sign-in page in the light theme", async () => {
document.documentElement.classList.remove("dark");
document.documentElement.classList.add("light");
stubFetch().on("GET", "/api/auth/me", {
status: 401,
error: "Unauthorized",
meta: { errorCode: "auth.missing" },
});
window.history.replaceState(null, "", "/auth/login");
await renderWithApp(
<AuthShell>
<div data-slot="page" />
</AuthShell>,
{ user: null },
);
await expect
.poll(() => document.querySelector('[data-slot="page"]'))
.toBeTruthy();
const wrapper = document.getElementById("main-content")!.parentElement!;
expect(getComputedStyle(wrapper).backgroundImage).toContain(
"linear-gradient",
);
});
});
+5 -3
View File
@@ -345,9 +345,11 @@ export function AuthShell({
// a sign-in form that is taller than a fixed-height box centres out of
// it at the top, where nothing can scroll back to it. A minimum lets the
// box grow and the document scroll. The safe-area padding keeps the form
// off the status bar and the home indicator in an installed app.
// off the status bar and the home indicator in an installed app, and
// `shell-safe-area` paints the strip behind the status bar so its white
// clock stays readable in the light theme, as in the signed-in shell.
return (
<div className="flex min-h-dvh flex-col pt-[env(safe-area-inset-top,0px)] pr-[env(safe-area-inset-right,0px)] pb-[env(safe-area-inset-bottom,0px)] pl-[env(safe-area-inset-left,0px)]">
<div className="shell-safe-area flex min-h-dvh flex-col pb-[env(safe-area-inset-bottom,0px)]">
{demoMode ? <DemoBanner /> : null}
<main
id="main-content"
@@ -419,7 +421,7 @@ export function AuthShell({
{showUnlockNotifier && user?.id ? (
<AchievementUnlockNotifier userId={user.id} />
) : null}
<div className="flex min-h-dvh flex-col pt-[env(safe-area-inset-top,0px)] pr-[env(safe-area-inset-right,0px)] pl-[env(safe-area-inset-left,0px)]">
<div className="shell-safe-area flex min-h-dvh flex-col">
<MaintainershipBanner />
<div className="flex flex-1 items-center justify-center px-4 py-8">
{children}