Componentnavigation
AppShell
Page skeleton with top bar, collapsible sidebar, and main content area with built-in skip-link
Preview
Live Preview
Installation
Tokens guide →Add to your project via CLI (zero dependencies, code you own):
npx bigbullui add app-shellOr install the full npm package:
npm install bigbulluiUsage
import { AppShell } from "@/components/ui/app-shell"
<AppShell defaultCollapsed={false}>
<header>Header</header>
<aside>Sidebar</aside>
<main>Main content</main>
</AppShell>Source code
app-shell.tsxZero dependencies (only React + utils). Copy and paste directly into your project:
"use client";
import * as React from "react";
import { cn } from "./lib/utils";
export interface AppShellProps {
header?: React.ReactNode;
sidebar?: React.ReactNode;
children: React.ReactNode;
defaultCollapsed?: boolean;
className?: string;
}
export function AppShell({
header,
sidebar,
children,
defaultCollapsed = false,
className,
}: AppShellProps) {
const [collapsed, setCollapsed] = React.useState(defaultCollapsed);
return (
<div className={cn("flex min-h-screen overflow-hidden", className)}>
{/* Skip link */}
<a
href="#main"
className={cn(
"hidden focus:not-sr-only focus:translate-x-0 focus:transition-transform",
"mx-2 mb-2 rounded-md bg-secondary text-secondary-foreground px-3 py-1 text-[10px] uppercase tracking-[0.15em]"
)}
>
Skip to main content
</a>
{/* Top bar */}
<header
className={cn(
"flex h-16 items-center border-b border-border/50 bg-background px-4 sm:px-6"
)}
>
{header}
</header>
{/* Main content */}
<main
id="main"
className={cn(
"flex-1 overflow-y-auto p-4 sm:p-6",
collapsed && "pl-3 pr-0",
"transition-left duration-300 ease-out"
)}
>
{children}
</main>
{/* Sidebar */}
<aside
className={cn(
"w-64 flex-shrink-0 bg-card border-r border-border/50 transition-colors duration-300 ease-out",
collapsed && "w-0",
!collapsed && "pr-2",
"accordion"
)}
>
{sidebar || (
<div className="p-4 text-sm text-muted-foreground">
<p className="uppercase tracking-[0.15em]">Collapse sidebar</p>
<button
className="mt-2 w-full rounded-md py-2 bg-secondary text-secondary-foreground text-[10px] uppercase tracking-[0.15em]"
onClick={() => setCollapsed(!collapsed)}
>
Collapse
</button>
</div>
)}
</aside>
</div>
);
}Props
| Prop | Type | Description |
|---|---|---|
| header | ReactNode | Optional header content |
| sidebar | ReactNode | Optional sidebar content |
| children | ReactNode | Main content |
| defaultCollapsed | boolean | Whether sidebar starts collapsed |