layouts
AppShell
Universal in-app layout — TopBar with brand + breadcrumbs, collapsible Sidebar with three modes (expanded / collapsed / hover), scrollable content area. The chrome around every product page.
The sidebar mode is persisted across reloads via a small client-side store. Nav structure is supplied via `navGroups` so each product wires its own sections. AppShell already wraps everything in `TooltipProvider` — don't add another one inside.
Install
Pull this component (and its dependencies) straight into your app via the shadcn CLI:
npx shadcn@latest add https://design.oapps.io/r/app-shell.jsonOr import from the workspace package:
import { AppShell, NavItem, NavGroup } from "@8maverik8/design";Examples
Schematic preview
AppShell occupies the full viewport, so the live one can't honestly fit inside a doc page. The mock below mirrors the exact structure (TopBar + Sidebar + main + bottom mode-picker). Mount the real one as the root layout of your Next.js app.
import { AppShell, type NavGroup } from "@8maverik8/design";
import { Home, Users, Megaphone } from "lucide-react";
const navGroups: NavGroup[] = [
{
section: "Workspace",
items: [
{ label: "Dashboard", icon: Home, href: "/" },
{ label: "Audiences", icon: Users, href: "/audiences" },
{ label: "Campaigns", icon: Megaphone, href: "/campaigns" },
],
},
];
export default function RootLayout({ children }) {
return (
<AppShell wordmark="cip" navGroups={navGroups}>
{children}
</AppShell>
);
}Anatomy
wordmarkLowercase product name shown in the topbar (e.g. `"cip"`).navGroupsArray of `{ section, items[] }`. Sections render as mono-caps headings; items are `{ label, icon, href }`.topbarLeftSlot to the right of the brand — typically a `<BreadcrumbTrail>`.topbarCenterCenter slot — typically the `<SearchPalette>` trigger button.topbarRightRight slot — typically `<FeedbackButton>` + `<UserMenu>`.
Guidelines
- Wire the `navGroups` once at the app's root layout — don't switch them per route.The sidebar should feel constant across the product. If a section needs to disappear contextually, hide it inside the page, not by mutating navGroups.
- Render your own page padding around children.AppShell's `<main>` already has `p-6`. DSPageShell's footer relies on this exact gutter to bleed correctly.