Dashboard Layout
Responsive app shell — a persistent sidebar on desktop that collapses to a Sheet drawer on mobile — with a top navbar and a content area of cards and tabs.
Preview
Dashboard
A live snapshot of your workspace — metrics, activity, and anything else worth a glance.
Total revenue
$48,120
Active users
2,847
Conversion rate
4.82%
Churn
1.2%
Recent activity
View all- New subscriptionJane Cooper
Acme Corp upgraded to the Team plan.
- User invitedWade Warren
[email protected] was invited to the workspace.
- Payment receivedSystem
$1,240.00 from Stark Industries.
- Report exportedEsther Howard
Q1 revenue report exported as CSV.
When to Use
- Admin dashboards and internal tools
- Multi-section apps with persistent navigation that must also work on mobile
- Content-heavy layouts needing sidebar + main area structure
- Any app shell where the desktop sidebar should collapse to a drawer without duplicating nav markup
Components Used
Structure
<SidebarProvider>
{/* Desktop sidebar — hidden on mobile via CSS */}
<Sidebar className="sidebar-desktop">
<SidebarHeader>
<h2>App Name</h2>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Main</SidebarGroupLabel>
<SidebarMenu>
{navItems.map((item) => (
<SidebarMenuItem key={item.href}>
<SidebarMenuButton asChild isActive={pathname === item.href}>
<a href={item.href}>{item.label}</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<main>
<Navbar>
{/* Desktop: collapse the persistent sidebar */}
<SidebarTrigger className="sidebar-desktop-trigger" />
{/* Mobile: Sheet drawer sharing the same navItems */}
<Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
<SheetTrigger asChild className="sidebar-mobile-trigger">
<Button variant="ghost" size="icon" aria-label="Open navigation">
<List />
</Button>
</SheetTrigger>
<SheetContent side="left">
<SheetHeader>
<SheetTitle>Navigation</SheetTitle>
</SheetHeader>
<nav>
{navItems.map((item) => (
<a key={item.href} href={item.href} onClick={() => setMobileOpen(false)}>
{item.label}
</a>
))}
</nav>
</SheetContent>
</Sheet>
<Separator orientation="vertical" />
<span>Dashboard</span>
</Navbar>
<ScrollArea>
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
</TabsList>
<TabsContent value="overview">
<div style={{ display: "grid", gap: "var(--spacing-4)", gridTemplateColumns: "repeat(3, 1fr)" }}>
<Card>
<CardHeader><CardTitle>Revenue</CardTitle></CardHeader>
<CardContent>$12,345</CardContent>
</Card>
<Card>
<CardHeader><CardTitle>Users</CardTitle></CardHeader>
<CardContent>1,234</CardContent>
</Card>
<Card>
<CardHeader><CardTitle>Orders</CardTitle></CardHeader>
<CardContent>567</CardContent>
</Card>
</div>
</TabsContent>
</Tabs>
</ScrollArea>
</main>
</SidebarProvider>Notes
- SidebarProvider manages the collapsed/expanded state and provides context to child components.
- On desktop the SidebarTrigger toggles the persistent Sidebar; on mobile a Sheet drawer presents the same
navItems— use CSS to show/hide the desktop sidebar and the mobile trigger at the appropriate breakpoint, and avoid duplicating navigation markup across the two. - Close the Sheet when a nav link is clicked on mobile to avoid stale open state.
- Use ScrollArea for the main content area to get consistent styled scrollbars.
- Cards in a CSS Grid layout adapt to the content area width; Tabs organize dashboard views without page navigation.
Card Grid
A responsive grid of content cards with skeleton loading states, status badges, action buttons, pagination, and an empty-state fallback.
Data Table Row Actions
A data table for managing collections of records (CRUD) — per-row action menus, bulk selection with a bulk action bar, confirmation dialogs, and toast feedback for destructive operations.