Jump to a component
Core · Navigation
SideNav
The creator sidebar: product, a switcher for the current workspace, grouped sections, a footer slot and the signed-in account at the bottom. The account is always shown. The current item reads in ink weight with the small state dot beside its name: no fill, no edge.
@anicanon/sakuga/uiv1.0Used onWeb
Live, from @anicanon/sakuga 2.0.0
Sakuga for iOS and Android is coming
iOS
Web only
SideNav is made for the web, and isn’t part of Sakuga for iOS yet.
Android
Web only
SideNav is made for the web, and isn’t part of Sakuga for Android yet.
- Use it for
- The creator sidebar: the switcher for the current workspace, grouped sections and the signed-in account at the bottom.
- Not for
- The main sections a viewer moves between on desktopTopNav
- The views and scenes inside a productionProductionNav
- Navigation on a phoneTabBar
Guidelines
Motion: state changes fade with motion-fast; entrances use motion-base and ease-enter.
switcher.onClickandswitcher.open(whether its list is open) make the switcher work;account.onClickmakes the account button work.
import { SideNav } from '@anicanon/sakuga/ui';
export default function SideNavExample() {
return (
<SideNav
brand={{ name: 'AniCanon', product: 'Studio' }}
switcher={{ label: 'EBA' }}
groups={[
{ items: [{ label: 'Home', icon: 'home' }] },
{
title: 'Make',
items: [{ label: 'Studio', icon: 'image', current: true }],
},
]}
account={{ name: 'Raul Menezes', handle: '@rmenezes' }}
/>
);
}PropsSideNavProps
groupsrequired{ title?: string; items: { label: string; icon?: IconName; current?: boolean; href?: string; onClick?: MouseEventHandler; }[]; }[]accountrequired{ name: string; handle?: string; image?: string; onClick?: MouseEventHandler; }brand{ logo?: string; name?: string; product?: string; href?: string; }switcher{ label: string; image?: string; /** Default "Series". */ prefix?: string; /** Whether its list is open. */ open?: boolean; /** The id of what it opens. */ controls?: string; onClick?: MouseEventHandler; }labelstringDefault 'Sections'childrenReactNodeclassNamestringAn IconName is any of the names Icon lists.
Each token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.
Colour
sidebar-bgStudio sidebar: its panel.bg-surface→neutral-0#ffffffbg-surface→neutral-900#111117sidebar-borderStudio sidebar: edge against the page.border-hairline→shade-a08rgba(11,10,16,0.08)border-hairline→white-a06rgba(255,255,255,0.06)sidebar-groupStudio sidebar: group headings (Make, Cast and world).text-muted→neutral-600#5c5b67text-muted→neutral-400#a3a3a7sidebar-item-fgStudio sidebar: idle items.text-secondary→neutral-800#2e2d36text-secondary→neutral-200#dcdcdesidebar-item-hover-bgStudio sidebar: hovered item.bg-fill-subtle→shade-a06rgba(11,10,16,0.06)bg-fill-subtle→white-a08rgba(255,255,255,0.08)sidebar-item-active-fgStudio sidebar: the current page name.text-primary→neutral-925#0b0a10text-primary→neutral-0#ffffffSpace and shape
sidebar-widthsidebar-gapgap-xlsidebar-padding-yinset-lgsidebar-padding-xinset-lgsidebar-edge-right-widthsidebar-brand-gapgap-mdsidebar-brand-padding-xinset-smsidebar-brand-img-sizesidebar-switch-gapgap-lgsidebar-switch-paddinginset-xssidebar-switch-radiusradius-mdsidebar-switch-img-sizesidebar-switch-img-radiusradius-smsidebar-nav-gapgap-lgsidebar-group-gapgap-2xssidebar-title-margin-bottomgap-xssidebar-title-padding-xinset-mdsidebar-item-gapgap-lgsidebar-item-heightsize-control-smsidebar-item-padding-xinset-mdsidebar-item-radiusradius-smsidebar-focus-outline-offsetfocus-ring-offsetsidebar-account-gapgap-lgsidebar-account-paddinginset-smsidebar-account-radiusradius-mdsidebar-account-img-sizesidebar-switch-chevron-icon-sizeicon-size-smsidebar-item-icon-sizeicon-size-smsidebar-who-chevron-icon-sizeicon-size-smsidebar-active-scalescale-press-lgsidebar-forced-edge-widthline-hairlineType
sidebar-font-familyfont-sanssidebar-name-fonttext-title-4sidebar-product-fonttext-caption-strongsidebar-switch-fonttext-labelsidebar-title-fonttext-microsidebar-item-fonttext-bodysidebar-item-page-font-weightweight-boldsidebar-account-font-familyfont-sanssidebar-initials-fonttext-microsidebar-who-b-fonttext-labelsidebar-who-span-fonttext-smallMotion
sidebar-switch-durationmotion-fastsidebar-switch-easingease-standardsidebar-item-durationmotion-fastsidebar-item-easingease-standardsidebar-account-durationmotion-fastsidebar-account-easingease-standardsidebar-active-durationmotion-instantChecked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.
- Result
- No issues found, in light or in dark.
- By design
- A complementary region named by
label(default "Sections"); Tab moves through the brand link (withoutbrand.href, the name alone), the series switcher ("Series: Ember Bay. Switch", expanded or collapsed fromswitcher.open, runningswitcher.onClick, controllingswitcher.controls), the links of a navigation named "Sections navigation" (each group named by its title, the current link "current page"; an item withouthrefis a button running itsonClick), the footer slot (children) and the account button ("Your account, Aiko Mori", runningaccount.onClick). Icons and pictures are hidden. - Not tested
- The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.