feat(ui): add floating variant to PageBack for sticky nav

- Add `floating` prop to pin PageBack to viewport on lg+ screens
- Switch styling from glass-subtle to glass with shadow for better contrast
- Use floating variant on SettingsLayout
This commit is contained in:
Quick
2026-05-26 20:51:52 -04:00
parent f7cae960c4
commit a8ef653c11
3 changed files with 27 additions and 7 deletions
+14 -3
View File
@@ -52,7 +52,7 @@ describe("PageBack", () => {
expect(mocks.navigate).toHaveBeenCalledWith(-1);
});
it("applies the documented positioning and glass-subtle styling", () => {
it("applies the documented positioning and glass styling", () => {
render(
<MemoryRouter>
<PageBack />
@@ -61,13 +61,24 @@ describe("PageBack", () => {
const button = screen.getByRole("button", { name: "Go back" });
expect(button).toHaveClass(
"glass-subtle",
"glass",
"absolute",
"top-4",
"left-4",
"left-2",
"z-20",
"rounded-full",
"p-1.5",
);
});
it("pins to the viewport on lg+ when floating is set", () => {
render(
<MemoryRouter>
<PageBack floating />
</MemoryRouter>,
);
const button = screen.getByRole("button", { name: "Go back" });
expect(button).toHaveClass("lg:fixed", "lg:left-[268px]");
});
});
+11 -2
View File
@@ -3,16 +3,25 @@ import { useNavigate } from "react-router";
interface PageBackProps {
label?: string;
/**
* When true, pins the button to the viewport on lg+ so it stays visible
* while scrolling. The offset matches the app sidebar (260px) so the
* button sits just inside the page content area.
*/
floating?: boolean;
}
export default function PageBack({ label = "Go back" }: PageBackProps) {
export default function PageBack({ label = "Go back", floating = false }: PageBackProps) {
const navigate = useNavigate();
const position = floating
? "absolute top-4 left-2 sm:top-6 lg:fixed lg:left-[268px]"
: "absolute top-4 left-2 sm:top-6";
return (
<button
type="button"
aria-label={label}
onClick={() => navigate(-1)}
className="glass-subtle text-muted-foreground hover:text-foreground absolute top-4 left-4 z-20 flex items-center justify-center rounded-full p-1.5 transition-colors sm:top-6 sm:left-6"
className={`glass text-foreground hover:bg-accent ${position} z-20 flex items-center justify-center rounded-full p-1.5 shadow-md transition-colors`}
>
<ChevronLeft className="size-5" />
</button>
+2 -2
View File
@@ -156,8 +156,8 @@ export default function SettingsLayout() {
return (
<div className="min-h-[100dvh]">
<main className="page-shell-wide relative flex min-h-[100dvh] flex-col py-4 sm:py-6">
<PageBack />
<div className="page-header gap-5">
<PageBack floating />
<div className="page-header mt-10 gap-5 sm:mt-12">
<div className="min-w-0 space-y-3">
<h1 className="page-title text-[clamp(2rem,4vw,3rem)]">Settings</h1>
<p className="page-subtitle text-sm sm:text-base">