App Shell

The App Shell defines the main structure of your app.

A shell is a collection of components shared throughout your app and can consist of a header, sidebar, content aside, and footer.

Import#

  • AppShell: The container component that manages composition.
import { AppShell } from '@saas-ui/app-shell'

Usage#

To make sure AppShell fills up the entire viewport height, you need to add height="100%" to html, body and any parent divs.

You can add global css styles to your theme as follows.

import { theme as baseTheme } from '@saas-ui/react'
// Your custom theme
export const theme = extendTheme(
{
styles: {
global: {
'html, body': {
height: '100%',
},
},
},
},
baseTheme
)

Alternatively you can set height="100vh" on AppShell, but this is less reliable across browsers, especially Mobile Safari.

Basic shell#

AppShell will try to fit it's parent with position absolute and inset: 0 by default.

<AppShell
navbar={
<Box as="header" borderBottomWidth="1px" py="2" px="4">
<SaasUILogo width="100px" />
</Box>
}
sidebar={
<Sidebar>
<SidebarSection>
<NavItem label="Home" />
<NavItem label="Settings" />
</SidebarSection>
</Sidebar>
}
>
<Box as="main" flex="1" py="2" px="4" overflowY="auto">
Your application content
</Box>
</AppShell>

Variants#

The default variant is fullscreen, using the static variant the AppShell will behave like a regular flex box. Use the static variant when the AppShell needs a fixed height, or when using a sticky header / sidebar.

<AppShell
variant="static"
minH="100%"
navbar={
<Box
as="header"
borderBottomWidth="1px"
py="2"
px="4"
position="sticky"
top="0"
>
<SaasUILogo width="100px" />
</Box>
}
sidebar={
<Sidebar position="sticky" top="40px">
<SidebarSection>
<NavItem label="Home" />
<NavItem label="Settings" />
</SidebarSection>
</Sidebar>
}
>
<Box as="main" flex="1" py="2" px="4">
Your application content
</Box>
</AppShell>

Example layout#

Full example with Sidebar, Page Pro and DataGrid Pro

<AppShell
sidebar={
<Sidebar width="30%">
<SidebarSection direction="row">
<SaasUILogo width="100px" />
<Spacer />
<Menu>
<MenuButton
as={IconButton}
icon={
<PersonaAvatar
presence="online"
size="xs"
src="/showcase-avatar.jpg"
/>
}
variant="ghost"
/>
<MenuList>
<MenuItem>Sign out</MenuItem>
</MenuList>
</Menu>
</SidebarSection>
<SidebarSection flex="1" overflowY="auto">
<NavItem label="Home" icon={<FiHome />} />
<NavItem label="Contacts" icon={<FiUsers />} />
</SidebarSection>
</Sidebar>
}
>
<Page title="Page" contentWidth="full">
<DataGrid
isHoverable
isSelectable
isSortable
columns={[
{ id: 'name', Header: 'Name' },
{ id: 'role', Header: 'Role' },
{ id: 'actions', width: '100px', Cell: () => <Button>Edit</Button> },
]}
data={[{ name: 'Renata Alink', role: 'Founder' }]}
>
<DataGridPagination />
</DataGrid>
</Page>
</AppShell>

Props#

The AppShell component and all sub components accept all Box properties.

childrenrequired

Description

The main content

Type
ReactNode

aside

Description

Secondary sidebar, positioned on the right

Type
ReactNode

footer

Description

The footer

Type
ReactNode

navbar

Description

The top header navigation

Type
ReactNode

sidebar

Description

Main sidebar, positioned on the left

Type
ReactNode

Was this helpful?