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:
@@ -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]");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user