Sidebar

Side navigation, commonly used as the primary navigation in web applications.

Theming#

The Sidebar, NavGroup and NavItem components have separate themes. This allows you to customize each component individually.

The Sidebar component is a multipart component. The styling needs to be applied to each part specifically.

To learn more about styling multipart components, visit the Chakra UI Component Style page.

Anatomy#

  • container
  • section
  • toggleWrapper

Default theme#

import { createMultiStyleConfigHelpers } from '@chakra-ui/styled-system'
import { sidebarAnatomy } from '@saas-ui/theme/anatomy'
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(sidebarAnatomy.keys)
const baseStyle = definePartsStyle((props) => {
const { colorScheme: c } = props
return {
container: {
bg: c ? `${c}.500` : 'white',
display: 'flex',
flexDirection: 'column',
borderRightWidth: '1px',
_dark: {
bg: c ? `${c}.500` : 'gray.800',
},
},
overlay: {
bg: 'blackAlpha.200',
},
}
})
const variantDefault = definePartsStyle((props) => {
return {
container: {
width: '280px',
maxWidth: ['100vw', '320px'],
minWidth: '220px',
py: 3,
'&[data-collapsible]': {
pt: 14,
},
},
section: {
px: 3,
},
toggleWrapper: {
h: 8,
mb: 4,
display: 'none',
'[data-collapsible] &': {
display: 'block',
},
},
}
})
const variantCondensed = definePartsStyle((props) => {
return {
container: {
width: '14',
py: 3,
},
section: {
px: 3,
},
toggleWrapper: {
display: 'none',
},
}
})
export const sidebarTheme = defineMultiStyleConfig({
defaultProps: {
variant: 'default',
},
baseStyle,
variants: {
default: variantDefault,
compact: variantCondensed,
},
})

The NavGroup component is a multipart component. The styling needs to be applied to each part specifically.

To learn more about styling multipart components, visit the Chakra UI Component Style page.

Anatomy#

  • container
  • title
  • content

Default theme#

import { createMultiStyleConfigHelpers } from '@chakra-ui/styled-system'
import { navGroupAnatomy } from '@saas-ui/theme/anatomy'
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(navGroupAnatomy.keys)
const baseStyle = definePartsStyle((props) => {
return {
container: {
'&:not(:last-of-type)': {
mb: 4,
},
},
title: {
display: 'flex',
alignItems: 'center',
px: 3,
my: 1,
height: 6,
fontSize: 'sm',
fontWeight: 'medium',
color: 'muted',
transitionProperty: 'common',
transitionDuration: 'normal',
'&.sui-collapse-toggle .chakra-icon': {
opacity: 0,
},
'&.sui-collapse-toggle': {
cursor: 'pointer',
borderRadius: 'md',
_hover: {
bg: 'blackAlpha.100',
'& .chakra-icon': {
opacity: 1,
},
_dark: {
bg: 'whiteAlpha.200',
},
},
},
'[data-compact] &': {
opacity: 0,
},
},
content: {},
}
})
export const navGroupTheme = defineMultiStyleConfig({
baseStyle,
})

The NavGroup component is a multipart component. The styling needs to be applied to each part specifically.

To learn more about styling multipart components, visit the Chakra UI Component Style page.

Anatomy#

  • item
  • link
  • inner
  • label
  • icon

Default theme#

import { transparentize } from '@chakra-ui/theme-tools'
import { theme as baseTheme } from '@chakra-ui/react'
import { createMultiStyleConfigHelpers } from '@chakra-ui/styled-system'
import { navItemAnatomy } from '@saas-ui/theme/anatomy'
const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(navItemAnatomy.keys)
const baseStyle = definePartsStyle((props) => {
return {
item: {
my: '2px',
color: 'gray.900',
minW: 1,
_dark: {
color: 'whiteAlpha.900',
},
},
link: {
display: 'flex',
rounded: 'md',
justifyContent: 'flex-start',
alignItems: 'center',
textDecoration: 'none',
transitionProperty: 'common',
transitionDuration: 'normal',
minW: 1,
_hover: {
textDecoration: 'none',
},
_focusVisible: {
outline: 'none',
boxShadow: 'outline',
},
},
inner: {
display: 'flex',
flex: 1,
w: '100%',
alignItems: 'center',
minW: 1,
},
label: {
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden',
},
icon: {
display: 'flex',
transitionProperty: 'common',
transitionDuration: 'normal',
alignItems: 'center',
justifyContent: 'center',
width: '4',
ml: '-0.25rem',
color: 'currentColor',
},
}
})
const variantNeutral = definePartsStyle((props) => {
return {
link: {
_hover: {
bg: 'blackAlpha.100',
_dark: {
bg: `whiteAlpha.200`,
},
},
_active: {
bg: 'blackAlpha.200',
_dark: {
bg: `whiteAlpha.300`,
},
},
},
icon: {
opacity: 0.8,
'[data-active] &': {
opacity: 1,
},
},
}
})
const variantSubtle = definePartsStyle((props) => {
const { colorScheme: c, theme } = props
return {
link: {
_hover: {
bg: `blackAlpha.100`,
_dark: {
bg: `whiteAlpha.200`,
},
},
_active: {
bg: transparentize(`${c}.500`, 0.3)(theme),
fontWeight: 'semibold',
color: `${c}.600`,
_dark: {
bg: transparentize(`${c}.500`, 0.3)(theme),
color: `${c}.100`,
},
},
},
}
})
const variantSolid = definePartsStyle((props) => {
const { colorScheme: c } = props
return {
link: {
_hover: {
bg: 'blackAlpha.100',
_dark: {
bg: `whiteAlpha.200`,
},
},
_active: {
bg: `${c}.500`,
},
color: 'white',
},
icon: {
color: 'white',
},
label: {},
}
})
export const navItemTheme = defineMultiStyleConfig({
defaultProps: {
size: 'sm',
colorScheme: 'primary',
variant: 'neutral',
},
baseStyle,
sizes: {
xs: {
link: baseTheme.components.Button.sizes?.xs,
icon: {
me: 1,
fontSize: 'xs',
},
},
sm: {
link: baseTheme.components.Button.sizes?.sm,
icon: {
me: 2,
fontSize: 'sm',
},
},
md: {
link: baseTheme.components.Button.sizes?.md,
icon: {
me: 2,
fontSize: 'md',
},
},
lg: {
link: baseTheme.components.Button.sizes?.lg,
icon: {
me: 3,
fontSize: 'lg',
},
},
},
variants: {
neutral: variantNeutral,
subtle: variantSubtle,
solid: variantSolid,
},
})

Was this helpful?