Sidebar

Side navigation, commonly used as the primary navigation.

Import#

  • Sidebar: The container component that manages state.
  • SidebarSection: A sidebar section.
  • SidebarToggleButton: Button to toggle the sidebar visibility.
  • SidebarOverlay: Background overlay visible when the sidebar is open on mobile.
  • NavGroup: A group of navigation items.
  • NavItem: A navigation item.
import {
Sidebar,
SidebarSection,
SidebarToggleButton,
SidebarOverlay,
NavGroup,
NavItem,
} from '@saas-ui/sidebar'

Usage#

The Sidebar is currently in beta, we'd love to hear your feedback while we finalize the API. Please note that you need to import the components from @saas-ui/sidebar instead of @saas-ui/react while in beta.

Basic#

<AppShell
sidebar={
<Sidebar>
<SidebarToggleButton />
<SidebarSection direction="row">
<Image
src="https://saas-ui.dev/favicons/favicon-96x96.png"
boxSize="7"
/>
<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 aria-label="Main">
<NavItem icon={<FiHome />} isActive>
Home
</NavItem>
<NavItem icon={<FiUsers />}>Users</NavItem>
<NavItem icon={<FiSettings />}>Settings</NavItem>
</SidebarSection>
</Sidebar>
}
/>

Grouped items#

<AppShell
sidebar={
<Sidebar>
<SidebarToggleButton />
<SidebarSection direction="row">
<Image
src="https://saas-ui.dev/favicons/favicon-96x96.png"
boxSize="7"
/>
<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 aria-label="Main">
<NavGroup>
<NavItem icon={<FiHome />} isActive>
Home
</NavItem>
<NavItem icon={<FiUsers />}>Users</NavItem>
<NavItem icon={<FiSettings />}>Settings</NavItem>
</NavGroup>
<NavGroup title="Teams" isCollapsible>
<NavItem>Sales</NavItem>
<NavItem>Support</NavItem>
</NavGroup>
</SidebarSection>
</Sidebar>
}
/>

Scroll#

<AppShell
sidebar={
<Sidebar>
<SidebarToggleButton />
<SidebarSection direction="row">
<Image
src="https://saas-ui.dev/favicons/favicon-96x96.png"
boxSize="7"
/>
<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">
<NavGroup>
<NavItem icon={<FiHome />} isActive>
Home
</NavItem>
<NavItem icon={<FiUsers />}>Users</NavItem>
<NavItem icon={<FiSettings />}>Settings</NavItem>
</NavGroup>
<NavGroup title="Teams" isCollapsible>
<NavItem>Sales</NavItem>
<NavItem>Support</NavItem>
</NavGroup>
<NavGroup title="Tags" isCollapsible>
<NavItem
icon={<Badge bg="purple.500" boxSize="2" borderRadius="full" />}
>
<Text>Lead</Text>
<Badge opacity="0.6" borderRadius="full" bg="none" ms="auto">
83
</Badge>
</NavItem>
<NavItem
icon={<Badge bg="cyan.500" boxSize="2" borderRadius="full" />}
>
<Text>Customer</Text>
<Badge opacity="0.6" borderRadius="full" bg="none" ms="auto">
210
</Badge>
</NavItem>
</NavGroup>
</SidebarSection>
<SidebarSection>
<NavItem icon={<FiHelpCircle />}>Documentation</NavItem>
</SidebarSection>
</Sidebar>
}
/>

Condensed variant#

The condensed variant can be used as a collapsed state on smaller screens, or as the primary navigation in a double sidebar layout, see below. NavItem labels will be rendered as tooltips.

Use the tooltipProps prop to customize the tooltip.

<AppShell
sidebar={
<Sidebar variant="condensed" width="64px">
<SidebarToggleButton />
<SidebarSection alignItems="center">
<Image
src="https://saas-ui.dev/favicons/favicon-96x96.png"
boxSize="7"
/>
</SidebarSection>
<SidebarSection>
<NavItem icon={<FiHome size="1.2em" />} size="md">
Home
</NavItem>
<NavItem icon={<FiUsers size="1.2em" />} size="md">
Users
</NavItem>
<NavItem icon={<FiSettings size="1.2em" />} size="md">
Settings
</NavItem>
</SidebarSection>
</Sidebar>
}
/>

Toggle variant#

function ToggleVariant() {
const { isOpen, onToggle } = useDisclosure({
defaultIsOpen: true,
})
return (
<AppShell
sidebar={
<Sidebar
breakpoints={{ base: false }}
variant={isOpen ? 'default' : 'condensed'}
transition="width"
transitionDuration="normal"
width={isOpen ? '280px' : '14'}
minWidth="auto"
>
<SidebarSection direction={isOpen ? 'row' : 'column'}>
<Image
src="https://saas-ui.dev/favicons/favicon-96x96.png"
boxSize="7"
mb="1"
display={isOpen ? 'block' : 'none'}
/>
<Spacer />
<IconButton
onClick={onToggle}
variant="ghost"
size="sm"
icon={isOpen ? <FiChevronsLeft /> : <FiChevronsRight />}
aria-label="Toggle Sidebar"
/>
</SidebarSection>
<SidebarSection flex="1" overflowY="auto" overflowX="hidden">
<NavGroup>
<NavItem icon={<FiHome />} isActive>
All users
</NavItem>
<NavItem icon={<StarIcon />}>Favourite users</NavItem>
</NavGroup>
</SidebarSection>
<SidebarOverlay zIndex="1" />
</Sidebar>
}
/>
)
}

Double sidebar#

You can stack multiple sidebars together to create a double sidebar layout.

<AppShell
sidebar={
<HStack spacing="0" alignItems="stretch">
<Sidebar variant="condensed" bg="purple.500" borderWidth="0" spacing="3">
<SidebarSection>
<Image
src="https://saas-ui.dev/favicons/favicon-96x96.png"
boxSize="7"
/>
</SidebarSection>
<SidebarSection>
<NavItem icon={<FiHome size="1.2em" color="white" />}>Home</NavItem>
<NavItem icon={<FiUsers size="1.2em" color="white" />} isActive>
Users
</NavItem>
<NavItem icon={<FiSettings size="1.2em" color="white" />}>
Settings
</NavItem>
</SidebarSection>
</Sidebar>
<Sidebar>
<SidebarSection direction="row" mt="2" px="4">
<Heading size="sm" fontWeight="semibold">
Users
</Heading>
</SidebarSection>
<SidebarSection flex="1" overflowY="auto">
<NavGroup>
<NavItem icon={<FiUsers />} isActive>
Overview
</NavItem>
</NavGroup>
<NavGroup title="Teams" isCollapsible>
<NavItem>Sales</NavItem>
<NavItem>Support</NavItem>
</NavGroup>
<NavGroup title="Tags" isCollapsible>
<NavItem
icon={<Badge bg="purple.500" boxSize="2" borderRadius="full" />}
>
<Text>Lead</Text>
<Badge opacity="0.6" borderRadius="full" bg="none" ms="auto">
83
</Badge>
</NavItem>
<NavItem
icon={<Badge bg="cyan.500" boxSize="2" borderRadius="full" />}
>
<Text>Customer</Text>
<Badge opacity="0.6" borderRadius="full" bg="none" ms="auto">
210
</Badge>
</NavItem>
</NavGroup>
</SidebarSection>
<SidebarSection>
<NavItem icon={<FiHelpCircle />}>Documentation</NavItem>
</SidebarSection>
</Sidebar>
</HStack>
}
/>

Breakpoints#

The sidebar will automatically close on small screens. You can change this behavior by customizing the breakpoints.

Default breakpoints.

<Sidebar breakpoints={{ base: true, lg: false }} />

Disabling closing the sidebar on small screens.

<AppShell
sidebar={
<Sidebar breakpoints={{ base: false }}>
<SidebarToggleButton />
<SidebarSection direction="row">
<Image
src="https://saas-ui.dev/favicons/favicon-96x96.png"
boxSize="7"
/>
<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 aria-label="Main">
<NavItem icon={<FiHome />} isActive>
Home
</NavItem>
<NavItem icon={<FiUsers />}>Users</NavItem>
<NavItem icon={<FiSettings />}>Settings</NavItem>
</SidebarSection>
<SidebarOverlay />
</Sidebar>
}
/>

Props#

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

breakpoints

Description

Define breakpoints for the mobile nav.

Type
Record<string, boolean>
Default
object { sm: true, lg: false }

isOpen

Type
boolean

motionPreset

Type
"none" | "slideInOut"

onClose

Type
(() => void)

onOpen

Type
(() => void)

spacing

Description

Spacing between child elements.

Type
ResponsiveValue<Union<number | "initial" | "inherit" | (string & {}) | "px" | "-moz-initial" | "revert" | "revert-layer" | "unset" | "auto" | "1" | "-1" | "2" | "-2" | "3" | "-3" | "4" | "-4" | "5" | ... 55 more ... | "-3.5">>

SidebarSection Props#

direction

Type
ResponsiveValue<"row" | "column">

SidebarToggleButton Props#

icon

Type
MaybeRenderProp<{ isOpen: boolean; }>

SidebarOverlay Props#

defaultIsOpen

Type
boolean
Default

icon

Type
ReactElement<any, string | JSXElementConstructor<any>>

isCollapsible

Type
boolean

onClose

Type
(() => void)

onOpen

Type
(() => void)

title

Type
ReactNode

labelrequired

Type
string

href

Type
string

icon

Type
ReactElement<any, string | JSXElementConstructor<any>>

isActive

Type
boolean

tooltip

Type
ReactNode

Was this helpful?