Zephora UI

Navigation

Sidebar

App drawer rendered as an in-flow <aside> (inline mode) or a portaled modal panel (overlay mode), with header/body/footer sections, a mini collapsed rail that can persist across reloads via persistKey, and nested navigation (SidebarNav/Group/Item/Sub) with automatic active-trail expansion.

Import

import { Sidebar, SidebarHeader, SidebarBody, SidebarFooter, SidebarNav, SidebarGroup, SidebarItem, SidebarSub } from "@zephora/react";

Examples

Inline layout

Inline mode participates in normal flow — place it next to your content.

Content

Collapsed rail

Inline sidebars can shrink to a mini rail via `collapsed`.

Content

Nested navigation

`SidebarNav` renders a <nav> landmark; `SidebarGroup` adds labelled sections, `SidebarItem` the links and `SidebarSub` collapsible branches (W3C disclosure-navigation pattern). An `active` item marks the current page and signals every ancestor sub (`data-active-trail`), so uncontrolled subs on the trail open automatically. In icon-collapse mode group labels and badges hide, item icons stay visible and uncontrolled subs close. Add `persistKey` to remember the collapsed state across reloads.

Content

API

Sidebar props

PropTypeDefaultDescription
mode"inline" | "overlay""inline"Rendering mode: in-flow <aside> or a portaled modal drawer with backdrop and focus trap.
openbooleanControlled open state.
defaultOpenbooleantrueInitial open state when uncontrolled.
onOpenChange(open: boolean) => voidCalled when the open state changes.
side"start" | "end""start"Which inline edge the sidebar sits on.
widthnumber | string"16rem"Expanded width. Numbers are px.
collapsedWidthnumber | string"4rem"Width in collapsed (mini rail) mode.
collapsedbooleanControlled mini rail mode (inline only).
defaultCollapsedbooleanfalseInitial collapsed state when uncontrolled.
onCollapsedChange(collapsed: boolean) => voidCalled when the collapsed state changes.
persistKeystringPersists the collapsed state to storage under `zephora-sidebar:<persistKey>` and restores it on mount. The persisted value seeds the uncontrolled default; a controlled `collapsed` prop always wins.
persistStorage"local" | "session""local"Storage backing persistKey.
unstyledbooleanfalseHeadless mode — skips Zephora styling.

SidebarHeader / SidebarBody / SidebarFooter props

PropTypeDefaultDescription
unstyledbooleanfalseHeadless mode — skips Zephora styling.
…restHTMLAttributes<HTMLDivElement>All native div props are forwarded. Body scrolls; header and footer stay fixed.

SidebarNav props

PropTypeDefaultDescription
aria-labelstringlocalized "Sidebar navigation"Accessible name of the <nav> landmark.
unstyledbooleanfalseHeadless mode — skips Zephora styling.
…restHTMLAttributes<HTMLElement>All native nav props are forwarded. Children render inside a <ul>.

SidebarGroup props

PropTypeDefaultDescription
labelReactNodeSmall heading above the group; hidden in icon-collapse mode.
unstyledbooleanfalseHeadless mode — skips Zephora styling.
…restLiHTMLAttributes<HTMLLIElement>All native li props are forwarded. Children render inside a nested <ul>.

SidebarItem props

PropTypeDefaultDescription
hrefstringLink target. Omitted while `disabled`.
iconReactNodeLeading icon; kept visible in icon-collapse mode.
activebooleanfalseMarks the current page: `aria-current="page"` + `data-active`, and signals every ancestor SidebarSub (active trail).
badgeReactNodeTrailing badge (e.g. a count); hidden in icon-collapse mode.
disabledbooleanfalseRemoves the href and sets aria-disabled + tabIndex=-1.
tooltipstringv1 tooltip: native `title` attribute on the link.
render(anchorProps: SidebarItemAnchorProps) => ReactNodeRouter bridge: render your own link (e.g. <Link>) with the computed anchor props instead of the built-in <a>.
unstyledbooleanfalseHeadless mode — skips Zephora styling.

SidebarSub props

PropTypeDefaultDescription
label *ReactNodeTrigger label.
iconReactNodeLeading icon on the trigger.
openbooleanControlled open state.
defaultOpenbooleanfalseInitial open state when uncontrolled. Uncontrolled subs on the active trail open automatically and close when entering icon-collapse mode.
onOpenChange(open: boolean) => voidCalled when the open state changes.
childrenReactNodeNested SidebarItems / SidebarSubs.
unstyledbooleanfalseHeadless mode — skips Zephora styling.

Keyboard

KeyAction
EscapeCloses the sidebar in overlay mode (focus is trapped inside while open).