Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 7x 6x | "use client";
import React from "react";
import { Header } from "./Header";
import { Breadcrumbs } from "./Breadcrumbs";
import { PageContainer } from "./PageContainer";
interface BreadcrumbItem {
label: string;
href?: string;
}
interface AppLayoutProps {
breadcrumbs?: BreadcrumbItem[];
actions?: React.ReactNode;
/** The page renders an ActionBar: reserve room so it never covers the last row or footer. */
reserveActionBar?: boolean;
children: React.ReactNode;
}
export function AppLayout({ breadcrumbs, actions, reserveActionBar, children }: AppLayoutProps) {
return (
<div data-app-shell className={`flex min-h-screen flex-col ${reserveActionBar ? "pb-36 md:pb-0 [@media(max-height:500px)]:pb-0" : ""}`}>
<Header />
<main className="flex-1 pt-20">
<PageContainer>
{(breadcrumbs || actions) && (
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
{breadcrumbs ? <Breadcrumbs items={breadcrumbs} /> : <span />}
{/* shrink-0: a long, scrolling breadcrumb must not squeeze or wrap
the action (e.g. "Pause") on a tablet-width row. The
bottom margin stays on Breadcrumbs so the 19 action-less pages
keep their exact spacing. */}
{actions && (
<div className="mb-6 flex w-full shrink-0 justify-start sm:w-auto sm:justify-end">
{actions}
</div>
)}
</div>
)}
{children}
</PageContainer>
</main>
<footer className="border-t border-hairline py-4 text-center text-sm text-ink-soft">
<p>Adored · Find the things you love</p>
</footer>
</div>
);
}
|