Skip to Content
PatternsLayoutApp Shell

App Shell

A full-page application layout with header, collapsible sidebar, and content area. Built using Box, Column, Row, and Button components.

My Application
Dashboard
Users
Settings
Main content area

Source

'use client'; import { createContext, useContext, useState } from 'react'; import { Box, Button, Column, Icon, Row } from '@umami/react-zen'; import { PanelLeft } from 'lucide-react'; const AppShellContext = createContext({ isSidebarOpen: true, setSidebarOpen: () => {}, }); export function useAppShell() { return useContext(AppShellContext); } export function AppShell({ defaultSidebarOpen = true, children, ...props }) { const [isSidebarOpen, setSidebarOpen] = useState(defaultSidebarOpen); return ( <AppShellContext.Provider value={{ isSidebarOpen, setSidebarOpen }}> <Box height="100%" {...props}> <Column height="100%">{children}</Column> </Box> </AppShellContext.Provider> ); } export function AppShellHeader({ children }) { return ( <Row paddingX="4" paddingY="3" alignItems="center" justifyContent="space-between" backgroundColor="surface-raised" borderColor="muted" border="bottom" > {children} </Row> ); } export function AppShellBody({ children }) { return ( <Row flexGrow="1" overflow="hidden"> {children} </Row> ); } export function AppShellSidebar({ width = '14rem', children, ...props }) { const { isSidebarOpen } = useAppShell(); if (!isSidebarOpen) return null; return ( <Box width={width} height="100%" backgroundColor="surface-raised" borderColor="muted" border="right" flexShrink="0" overflow="auto" {...props} > {children} </Box> ); } export function AppShellContent({ children, ...props }) { return ( <Box flexGrow="1" overflow="auto" {...props}> {children} </Box> ); } export function AppShellSidebarToggle() { const { isSidebarOpen, setSidebarOpen } = useAppShell(); return ( <Button variant="quiet" onPress={() => setSidebarOpen(!isSidebarOpen)}> <Icon style={{ transform: isSidebarOpen ? undefined : 'scaleX(-1)' }}> <PanelLeft /> </Icon> </Button> ); }

Variations

With navigation

Dashboard
Dashboard
Users
Settings
Main content area
Compact View
Click the toggle to show sidebar