Persistent app-shell rail with collapse, inset, and a mobile drawer.
Introduction
Sidebar is a persistent app-shell rail. Mount SidebarProvider around Sidebar and SidebarInset as siblings. Put SidebarList or Accordion in the rail. Below the md breakpoint the panel opens as a Drawer.
Prefer Sidebar for app chrome that stays on screen. Prefer Drawer for temporary side panels, filters, and settings that overlay the page.
Mount SidebarProvider around the shell before using SidebarTrigger or useSidebar. BridgeUIProvider still holds theme, tokens, and defaultProps. It does not own instance open state.
Playgrounds sit in a bounded frame so the fixed rail stays in the preview. In an app, mount SidebarProvider at the shell root — it defaults to min-h-svh.
Use the framework selector in the site header to switch between React and Vue.
Import
import {
Sidebar,
SidebarInset,
SidebarList,
SidebarListItem,
SidebarProvider,
SidebarTrigger,
useSidebar,
} from "@bridge-ui/vue/Components/Sidebar";import {
Sidebar,
SidebarInset,
SidebarList,
SidebarListItem,
SidebarProvider,
SidebarTrigger,
useSidebar,
} from "@bridge-ui/react/Components/Sidebar";Basic usage
Compose the shell: provider, rail, inset, and trigger. SidebarList / SidebarListItem bind nav chrome to the nearest rail.
Header and footer
Put brand and account rows in the header and footer slots. SidebarList collapses those rows to the start avatar. The end chevron hides while collapsed. Give nav items a start icon so they stay visible on the icon rail. Header and footer lists use classes.root "p-0" because those slots are already padded.
Icon collapse
Set collapsible="icon" and use SidebarList / SidebarListItem. Collapsed items keep string primary as an aria-label and show it in a Tooltip on the whole item. Nested SidebarList and ListSection labels are hidden. The mobile drawer keeps labels.
Controlled
Control desktop expanded state on SidebarProvider. There is no cookie or localStorage — persist open in the app if you need it. There is no default keyboard shortcut; call toggleSidebar from useSidebar.
Right side
Set side to right to dock the rail to the opposite edge. Collapsed item tooltips open on the side opposite the rail.
Inset variant
variant="inset" pads and rounds the main column. The default sidebar variant is a flush rail.
Collapsible groups
Use Accordion with variant="plain" for nested nav groups. Put SidebarList in each panel. Plain panels hide while the icon rail is collapsed.
Related components
Accordion, Avatar, Button, Drawer, List, Tooltip
Accessibility
- The desktop panel is an aside with aria-label (default "Sidebar").
- An offcanvas collapsed panel is inert (out of the tab order). Icon collapse stays focusable.
- Mobile uses Drawer (dialog, overlay, Escape).
- SidebarTrigger sets aria-expanded and aria-controls. The default accessible name is Toggle sidebar.
- SidebarListItem copies string primary to aria-label when the icon rail is collapsed.
Anatomy
div <!-- SidebarProvider -->
div <!-- Sidebar root: in-flow gap + fixed aside -->
aside
header slot
content <!-- SidebarList / Accordion -->
footer slot
main <!-- SidebarInset -->
SidebarTrigger
childrenBelow md, the aside stays mounted and is hidden with CSS. Open state uses a portaled Drawer instead of swapping the rail on first paint.
API
SidebarProvider
| Prop | Type | Default | Description |
|---|---|---|---|
| @open-change | (open: boolean) => void | — | Emitted when desktop open should change. |
| classes | SidebarProviderClasses | — | Classes for root. |
| customProps | SidebarProviderCustomProps | — | Extra props for the layout wrapper. |
| defaultOpen | boolean | true | Uncontrolled initial desktop expanded state. |
| v-model | boolean | — | Controlled desktop expanded state. |
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Sidebar, SidebarInset, and other shell. |
| classes | SidebarProviderClasses | — | Classes for root. |
| customProps | SidebarProviderCustomProps | — | Extra props for the layout wrapper. |
| defaultOpen | boolean | true | Uncontrolled initial desktop expanded state. |
| onOpenChange | (open: boolean) => void | — | Called when desktop open should change. |
| open | boolean | — | Controlled desktop expanded state. |
Sidebar
| Slot | Description |
|---|---|
| default | Rail content (SidebarList / Accordion). |
| footer | Sticky footer. |
| header | Sticky header. |
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Rail content (SidebarList / Accordion). |
| slots | SidebarSlots | — | header, footer. |
| Prop | Type | Default | Description |
|---|---|---|---|
| ariaLabel | string | "Sidebar" | Accessible name for the aside and the mobile drawer. |
| classes | SidebarClasses | — | Part classes (root, header, content, footer, gap, panel). |
| collapsible | "icon" | "none" | "offcanvas" | "offcanvas" | How the desktop rail hides. |
| customProps | SidebarCustomProps | — | Extra props for internal parts. |
| side | "left" | "right" | "left" | Edge the rail docks to. |
| variant | "inset" | "sidebar" | "sidebar" | Flush rail or padded main column. |
SidebarInset
| Prop | Type | Default | Description |
|---|---|---|---|
| classes | SidebarInsetClasses | — | Classes for root. |
| customProps | SidebarInsetCustomProps | — | Extra props for the inset root. |
SidebarTrigger
Renders a Button. Forwards native button attributes. Default accessible name is Toggle sidebar. Pass children to replace the default icon.
SidebarList
Same as List, plus:
| Prop | Type | Default | Description |
|---|---|---|---|
| iconOnly | boolean | — | Collapse items to leading icons. Defaults to the collapsed icon rail. Nested lists and ListSection labels are hidden. |
Applies stacked nav chrome (gap, compact rows, nested guide). Override with iconOnly.
SidebarListItem
Same as ListItem, plus:
| Prop | Type | Default | Description |
|---|---|---|---|
| tooltip | string | — | Tooltip label while the icon rail is collapsed. When omitted, string primary is used. No effect on the mobile drawer or an expanded rail. |
| tooltipPlacement | PositionPlacement | opposite the rail | Placement of the collapsed-rail tooltip. |
Applies compact nav chrome. Tooltips only show while the icon rail is collapsed.
useSidebar
Must be called under SidebarProvider. Vue returns a computed context object (sidebar.value.open, …).
| Field | Type | Description |
|---|---|---|
| collapsible | "icon" | "none" | "offcanvas" | Mode from the nearest Sidebar. |
| isMobile | boolean | Viewport is below md. |
| open | boolean | Desktop expanded state. |
| openMobile | boolean | Mobile drawer visibility. |
| setOpen | (open: boolean) => void | Sets desktop open. |
| setOpenMobile | (open: boolean) => void | Sets mobile drawer visibility. |
| side | "left" | "right" | Dock edge. |
| state | "collapsed" | "expanded" | Desktop visual state. |
| toggleSidebar | () => void | Toggles desktop open or mobile openMobile. |
| variant | "inset" | "sidebar" | Visual variant. |