Component Hierarchy
Application layout structure, component organization, and hierarchical relationships in Smart Shelf.
Component Hierarchy
Detailed overview of the Smart Shelf application's component hierarchy, layout structure, and organizational patterns that create a cohesive user interface.
Application Layout Structure
App Layout
├── Navigation Sidebar
│ ├── Main Menu Items
│ ├── User Profile Menu
│ └── Quick Actions
├── Main Content Area
│ ├── Page Header
│ │ ├── Breadcrumbs
│ │ ├── Page Title
│ │ └── Action Buttons
│ ├── Content Body
│ │ ├── Data Tables
│ │ ├── Forms
│ │ ├── Charts/Graphs
│ │ └── Modals/Dialogs
│ └── Status/Loading States
└── Toast Notifications
Layout Components
AppLayout
Root layout component with navigation and main content area:
export function AppLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex h-screen bg-background">
<Sidebar />
<main className="flex-1 overflow-auto">
<Header />
<div className="p-6">
{children}
</div>
</main>
</div>
);
}
PageLayout
Standardized page layout with header and content:
interface PageLayoutProps {
title: string;
description?: string;
actions?: React.ReactNode;
children: React.ReactNode;
}
export function PageLayout({ title, description, actions, children }: PageLayoutProps) {
return (
<div className="space-y-6">
<PageHeader title={title} description={description} actions={actions} />
<div className="space-y-4">
{children}
</div>
</div>
);
}
Navigation Components
Sidebar Component
interface SidebarProps {
isCollapsed?: boolean;
onToggle?: () => void;
}
export function Sidebar({ isCollapsed, onToggle }: SidebarProps) {
const navigation = useNavigation();
return (
<aside className={cn(
"bg-card border-r transition-all duration-300",
isCollapsed ? "w-16" : "w-64"
)}>
<div className="p-4">
<Logo collapsed={isCollapsed} />
</div>
<nav className="px-2">
{navigation.map((section) => (
<NavigationSection
key={section.id}
section={section}
collapsed={isCollapsed}
/>
))}
</nav>
<div className="absolute bottom-4 left-2 right-2">
<UserProfile collapsed={isCollapsed} />
</div>
</aside>
);
}
Header Component
interface HeaderProps {
title?: string;
breadcrumbs?: BreadcrumbItem[];
actions?: React.ReactNode;
}
export function Header({ title, breadcrumbs, actions }: HeaderProps) {
return (
<header className="border-b bg-background px-6 py-4">
<div className="flex items-center justify-between">
<div className="space-y-1">
{breadcrumbs && <Breadcrumbs items={breadcrumbs} />}
{title && <h1 className="text-2xl font-semibold">{title}</h1>}
</div>
<div className="flex items-center space-x-4">
<NotificationButton />
<UserMenu />
{actions}
</div>
</div>
</header>
);
}
Content Area Components
Dashboard Layout
export function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<PageLayout title="Dashboard" description="Overview of your inventory and operations">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<MetricCard
title="Total Products"
value="1,234"
change={{ value: 12, type: 'increase', period: 'last month' }}
icon={<Package className="h-4 w-4" />}
/>
<MetricCard
title="Low Stock Items"
value="23"
change={{ value: 5, type: 'decrease', period: 'last week' }}
icon={<AlertTriangle className="h-4 w-4" />}
color="yellow"
/>
<MetricCard
title="Total Value"
value="$45,231"
change={{ value: 8, type: 'increase', period: 'last month' }}
icon={<DollarSign className="h-4 w-4" />}
color="green"
/>
<MetricCard
title="Pending Orders"
value="12"
icon={<ShoppingCart className="h-4 w-4" />}
color="blue"
/>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{children}
</div>
</PageLayout>
);
}
Inventory Page Layout
export function InventoryPageLayout() {
return (
<PageLayout
title="Inventory Management"
description="Manage your product inventory and stock levels"
actions={
<div className="flex gap-2">
<Button variant="outline">
<Upload className="h-4 w-4 mr-2" />
Import
</Button>
<Button>
<Plus className="h-4 w-4 mr-2" />
Add Product
</Button>
</div>
}
>
<div className="space-y-4">
<InventoryFilters />
<InventoryTable />
</div>
</PageLayout>
);
}
Modal and Dialog Hierarchy
Modal Stack Management
interface ModalStackContextValue {
modals: Modal[];
openModal: (modal: Modal) => void;
closeModal: (id: string) => void;
closeAllModals: () => void;
}
export function ModalStackProvider({ children }: { children: React.ReactNode }) {
const [modals, setModals] = useState<Modal[]>([]);
const openModal = useCallback((modal: Modal) => {
setModals(prev => [...prev, modal]);
}, []);
const closeModal = useCallback((id: string) => {
setModals(prev => prev.filter(modal => modal.id !== id));
}, []);
const closeAllModals = useCallback(() => {
setModals([]);
}, []);
return (
<ModalStackContext.Provider value={{ modals, openModal, closeModal, closeAllModals }}>
{children}
<ModalRenderer modals={modals} />
</ModalStackContext.Provider>
);
}
Dialog Component Structure
interface DialogProps {
title: string;
description?: string;
children: React.ReactNode;
actions?: React.ReactNode;
size?: 'sm' | 'md' | 'lg' | 'xl';
onClose?: () => void;
}
export function Dialog({ title, description, children, actions, size = 'md', onClose }: DialogProps) {
return (
<DialogPrimitive.Root onOpenChange={onClose}>
<DialogPrimitive.Portal>
<DialogPrimitive.Overlay className="fixed inset-0 bg-black/50" />
<DialogPrimitive.Content
className={cn(
"fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
"bg-background rounded-lg shadow-lg",
"w-full max-h-[85vh] overflow-y-auto",
{
'max-w-sm': size === 'sm',
'max-w-md': size === 'md',
'max-w-lg': size === 'lg',
'max-w-4xl': size === 'xl',
}
)}
>
<DialogPrimitive.Title className="px-6 py-4 border-b font-semibold">
{title}
</DialogPrimitive.Title>
{description && (
<DialogPrimitive.Description className="px-6 py-2 text-muted-foreground">
{description}
</DialogPrimitive.Description>
)}
<div className="px-6 py-4">
{children}
</div>
{actions && (
<div className="px-6 py-4 border-t bg-muted/20">
<div className="flex justify-end gap-2">
{actions}
</div>
</div>
)}
</DialogPrimitive.Content>
</DialogPrimitive.Portal>
</DialogPrimitive.Root>
);
}
Form Layout Hierarchy
Form Container Structure
interface FormLayoutProps {
title: string;
description?: string;
children: React.ReactNode;
actions: React.ReactNode;
errors?: Record<string, string>;
}
export function FormLayout({ title, description, children, actions, errors }: FormLayoutProps) {
return (
<div className="space-y-6">
<div className="space-y-2">
<h2 className="text-2xl font-semibold">{title}</h2>
{description && (
<p className="text-muted-foreground">{description}</p>
)}
</div>
{Object.keys(errors || {}).length > 0 && (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Please fix the following errors:</AlertTitle>
<AlertDescription>
<ul className="list-disc list-inside">
{Object.entries(errors || {}).map(([field, error]) => (
<li key={field}>{error}</li>
))}
</ul>
</AlertDescription>
</Alert>
)}
<div className="space-y-4">
{children}
</div>
<div className="flex justify-end gap-2 pt-4 border-t">
{actions}
</div>
</div>
);
}
Form Section Organization
interface FormSectionProps {
title: string;
description?: string;
children: React.ReactNode;
collapsible?: boolean;
defaultExpanded?: boolean;
}
export function FormSection({
title,
description,
children,
collapsible = false,
defaultExpanded = true
}: FormSectionProps) {
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
if (collapsible) {
return (
<Collapsible open={isExpanded} onOpenChange={setIsExpanded}>
<CollapsibleTrigger className="flex items-center justify-between w-full py-2">
<div className="text-left">
<h3 className="font-medium">{title}</h3>
{description && (
<p className="text-sm text-muted-foreground">{description}</p>
)}
</div>
<ChevronDown className={cn(
"h-4 w-4 transition-transform",
isExpanded && "rotate-180"
)} />
</CollapsibleTrigger>
<CollapsibleContent className="space-y-4 pt-4">
{children}
</CollapsibleContent>
</Collapsible>
);
}
return (
<div className="space-y-4">
<div className="space-y-1">
<h3 className="font-medium">{title}</h3>
{description && (
<p className="text-sm text-muted-foreground">{description}</p>
)}
</div>
<div className="space-y-4">
{children}
</div>
</div>
);
}
Responsive Layout Patterns
Responsive Grid System
interface ResponsiveGridProps {
children: React.ReactNode;
cols?: {
default: number;
sm?: number;
md?: number;
lg?: number;
xl?: number;
};
gap?: number;
}
export function ResponsiveGrid({ children, cols = { default: 1 }, gap = 4 }: ResponsiveGridProps) {
const gridClasses = cn(
"grid",
`gap-${gap}`,
`grid-cols-${cols.default}`,
cols.sm && `sm:grid-cols-${cols.sm}`,
cols.md && `md:grid-cols-${cols.md}`,
cols.lg && `lg:grid-cols-${cols.lg}`,
cols.xl && `xl:grid-cols-${cols.xl}`
);
return (
<div className={gridClasses}>
{children}
</div>
);
}
Mobile-First Component Hierarchy
export function MobileLayout({ children }: { children: React.ReactNode }) {
const [sidebarOpen, setSidebarOpen] = useState(false);
return (
<div className="flex h-screen bg-background">
{/* Mobile sidebar overlay */}
<MobileSidebar open={sidebarOpen} onClose={() => setSidebarOpen(false)} />
{/* Desktop sidebar */}
<div className="hidden lg:flex lg:w-64 lg:flex-col">
<Sidebar />
</div>
{/* Main content */}
<div className="flex-1 flex flex-col overflow-hidden">
{/* Mobile header */}
<MobileHeader onMenuClick={() => setSidebarOpen(true)} />
{/* Desktop header */}
<div className="hidden lg:block">
<Header />
</div>
{/* Content area */}
<main className="flex-1 overflow-y-auto p-4 lg:p-6">
{children}
</main>
</div>
</div>
);
}
Component Composition Examples
Product Management Hierarchy
export function ProductManagementPage() {
return (
<PageLayout
title="Product Management"
description="Manage your product catalog and inventory"
actions={<ProductActions />}
>
<div className="space-y-6">
<ProductFilters />
<ResponsiveGrid cols={{ default: 1, lg: 2 }}>
<Card>
<CardHeader>
<CardTitle>Product Overview</CardTitle>
</CardHeader>
<CardContent>
<ProductMetrics />
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Recent Activity</CardTitle>
</CardHeader>
<CardContent>
<ProductActivity />
</CardContent>
</Card>
</ResponsiveGrid>
<ProductTable />
</div>
</PageLayout>
);
}
This component hierarchy ensures a consistent, scalable, and maintainable structure for the Smart Shelf application's user interface.