designComponents

Search the design system…

Search the design system…

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.json

Or 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.

cip
/Audiences

Workspace

Dashboard
Audiences
Campaigns

Data

Persons
Workspaces
⇆ Sidebar
Audiences
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.