slate-v3-1770514618/packages/layout/src/DashboardShell.tsx
jordan c65d01ffe7
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/manual/woodpecker Pipeline was successful
Initialize project from skeleton template
2026-02-08 01:36:59 +00:00

79 lines
2.1 KiB
TypeScript

import * as React from 'react';
import { cn } from '@slate-v3-1770514618/ui';
export interface DashboardShellProps {
/** Sidebar element to render on the left */
sidebar?: React.ReactNode;
/** Header element to render at the top */
header?: React.ReactNode;
/** Main content */
children: React.ReactNode;
/** Width of the sidebar in pixels (default: 256) */
sidebarWidth?: number;
/** Height of the header in pixels (default: 64) */
headerHeight?: number;
/** Additional class names for the main content area */
className?: string;
}
/**
* DashboardShell provides a standard layout for dashboard applications
* with a fixed sidebar, header, and scrollable main content area.
*
* @example
* <DashboardShell
* sidebar={<AppSidebar />}
* header={<AppHeader />}
* >
* <MainContent />
* </DashboardShell>
*/
export function DashboardShell({
sidebar,
header,
children,
sidebarWidth = 256,
headerHeight = 64,
className,
}: DashboardShellProps) {
return (
<div className="min-h-screen bg-[var(--background)]">
{/* Sidebar */}
{sidebar && (
<aside
className="fixed inset-y-0 left-0 z-[var(--z-sticky)] flex flex-col border-r border-[var(--border)] bg-[var(--background-secondary)]"
style={{ width: sidebarWidth }}
>
{sidebar}
</aside>
)}
{/* Main area */}
<div
className="flex flex-col min-h-screen"
style={{ marginLeft: sidebar ? sidebarWidth : 0 }}
>
{/* Header */}
{header && (
<header
className="sticky top-0 z-[var(--z-sticky)] flex items-center border-b border-[var(--border)] bg-[var(--background)]/95 backdrop-blur supports-[backdrop-filter]:bg-[var(--background)]/60"
style={{ height: headerHeight }}
>
{header}
</header>
)}
{/* Main content */}
<main
className={cn(
'flex-1 overflow-auto p-6',
className
)}
>
{children}
</main>
</div>
</div>
);
}