Skip to main content

Overview

The dashboard layout components provide pre-built, polished layouts for building dashboard pages with:
  • Responsive width constraints
  • Sidebar integration
  • Sticky headers with backdrop blur
  • Consistent spacing and styling
  • Page header components

DashboardWrapper

A simple wrapper component that provides responsive width constraints across all viewport sizes.

Usage

import { DashboardWrapper } from "@repo/ui";

function DashboardPage() {
  return (
    <DashboardWrapper>
      <h1>My Dashboard</h1>
      <p>Content here</p>
    </DashboardWrapper>
  );
}

Props

children
ReactNode
required
The content to wrap.
className
string
Additional CSS classes to apply.

Responsive Widths

The wrapper applies different max-widths at different breakpoints:
  • Mobile - Full width with px-4 padding
  • sm - max-w-2xl (672px) with px-6
  • md - max-w-4xl (896px)
  • lg - max-w-5xl (1024px)
  • xl - max-w-6xl (1152px)
  • 2xl - max-w-7xl (1280px)

DashboardLayout

A complete dashboard layout with sidebar, header, and content area.

Basic Usage

import { 
  DashboardLayout,
  Sidebar,
  SidebarContent,
  // ... other sidebar components
} from "@repo/ui";

function AppSidebar() {
  return (
    <Sidebar>
      <SidebarContent>
        {/* Your sidebar content */}
      </SidebarContent>
    </Sidebar>
  );
}

function App() {
  return (
    <DashboardLayout
      sidebar={<AppSidebar />}
      headerContent={<Breadcrumb />}
    >
      {/* Your page content */}
    </DashboardLayout>
  );
}

Props

sidebar
ReactNode
required
The sidebar component to render (typically a Sidebar component).
children
ReactNode
required
The main content of the dashboard.
headerContent
ReactNode
Optional content to display in the header (e.g., breadcrumbs, title).
mainClassName
string
Additional CSS classes for the main content area.
headerClassName
string
Additional CSS classes for the header.
showHeaderSeparator
boolean
default:"true"
Whether to show a separator between the sidebar trigger and header content.
defaultOpen
boolean
default:"true"
Default open state of the sidebar.

Features

DashboardPageHeader

A consistent page header component for dashboard pages with title, description, and actions.

Usage

import { DashboardPageHeader } from "@repo/ui";

function UsersPage() {
  return (
    <>
      <DashboardPageHeader
        title="Users"
        description="Manage your team members and their permissions"
        actions={
          <button>Add User</button>
        }
      />
      
      {/* Page content */}
    </>
  );
}

Props

title
string
required
The page title.
description
string
Optional description below the title.
actions
ReactNode
Optional action buttons/content to display on the right.
className
string
Additional CSS classes to apply.

Layout

The header uses responsive flex layout:
  • Mobile - Stacked vertically (flex-col)
  • Desktop - Horizontal with space-between (flex-row)
  • Actions have top margin on mobile, none on desktop
  • Bottom margin of mb-6 for spacing from content

DashboardContent

A content wrapper that provides consistent max-width constraints.

Usage

import { DashboardContent } from "@repo/ui";

function Page() {
  return (
    <DashboardContent>
      <div className="grid grid-cols-3 gap-4">
        {/* Your content */}
      </div>
    </DashboardContent>
  );
}

Props

children
ReactNode
required
The content to wrap.
className
string
Additional CSS classes to apply.
constrained
boolean
default:"true"
Whether to apply max-width constraint (max-w-7xl).Set to false for full-width content.

Example: Full Width

<DashboardContent constrained={false}>
  {/* Full width content */}
  <div className="w-full">...</div>
</DashboardContent>

Complete Example

import {
  DashboardLayout,
  DashboardPageHeader,
  DashboardContent,
  Sidebar,
  SidebarContent,
  SidebarMenu,
  SidebarMenuItem,
  SidebarMenuButton,
  Button,
  Card,
  CardHeader,
  CardTitle,
  CardContent,
} from "@repo/ui";
import { Home, Users, Settings, Plus } from "lucide-react";

function AppSidebar() {
  return (
    <Sidebar>
      <SidebarContent>
        <SidebarMenu>
          <SidebarMenuItem>
            <SidebarMenuButton isActive>
              <Home />
              <span>Dashboard</span>
            </SidebarMenuButton>
          </SidebarMenuItem>
          <SidebarMenuItem>
            <SidebarMenuButton>
              <Users />
              <span>Users</span>
            </SidebarMenuButton>
          </SidebarMenuItem>
          <SidebarMenuItem>
            <SidebarMenuButton>
              <Settings />
              <span>Settings</span>
            </SidebarMenuButton>
          </SidebarMenuItem>
        </SidebarMenu>
      </SidebarContent>
    </Sidebar>
  );
}

function DashboardPage() {
  return (
    <DashboardLayout
      sidebar={<AppSidebar />}
      headerContent={
        <div className="flex items-center gap-2">
          <span className="text-sm text-muted-foreground">Dashboard</span>
        </div>
      }
    >
      <DashboardContent>
        <DashboardPageHeader
          title="Dashboard"
          description="Welcome back! Here's what's happening today."
          actions={
            <div className="flex gap-2">
              <Button variant="outline">Export</Button>
              <Button>
                <Plus />
                Create New
              </Button>
            </div>
          }
        />
        
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <Card>
            <CardHeader>
              <CardTitle>Total Users</CardTitle>
            </CardHeader>
            <CardContent>
              <div className="text-3xl font-bold">2,543</div>
            </CardContent>
          </Card>
          
          <Card>
            <CardHeader>
              <CardTitle>Revenue</CardTitle>
            </CardHeader>
            <CardContent>
              <div className="text-3xl font-bold">$45,231</div>
            </CardContent>
          </Card>
          
          <Card>
            <CardHeader>
              <CardTitle>Growth</CardTitle>
            </CardHeader>
            <CardContent>
              <div className="text-3xl font-bold">23%</div>
            </CardContent>
          </Card>
        </div>
      </DashboardContent>
    </DashboardLayout>
  );
}

export default DashboardPage;

TypeScript Types

interface DashboardWrapperProps {
  children: React.ReactNode;
  className?: string;
}

interface DashboardLayoutProps {
  sidebar: React.ReactNode;
  children: React.ReactNode;
  headerContent?: React.ReactNode;
  mainClassName?: string;
  headerClassName?: string;
  showHeaderSeparator?: boolean;
  defaultOpen?: boolean;
}

interface DashboardPageHeaderProps {
  title: string;
  description?: string;
  actions?: React.ReactNode;
  className?: string;
}

interface DashboardContentProps {
  children: React.ReactNode;
  className?: string;
  constrained?: boolean;
}

Best Practices

  1. Use DashboardLayout for full pages - It provides sidebar integration and header management
  2. Use DashboardPageHeader consistently - Maintain visual consistency across pages
  3. Use DashboardContent for width constraints - Prevent content from being too wide on large screens
  4. Combine with other UI components - Works seamlessly with cards, buttons, etc.

Layout Hierarchy

DashboardLayout
├── Sidebar
│   └── SidebarContent
└── SidebarInset
    ├── Header (with SidebarTrigger)
    └── Main
        └── DashboardContent (optional)
            ├── DashboardPageHeader (optional)
            └── Your content

Build docs developers (and LLMs) love