useSidebar
Headless hooks for managing sidebar state, collapse behavior, layout coordination, and collapsible menu items.
Dashboard
Select an item from the sidebar to get started.
Usage#
import { useSidebar, useSidebarLayout, useSidebarMenuItem } from '@primereact/headless/sidebar';const layout = useSidebarLayout({});
const sidebar = useSidebar({ id: 'nav', layout, collapsible: 'icon' });
return <aside {...sidebar.rootProps}>...</aside>;The sidebar family splits concerns across three hooks: useSidebar drives a single sidebar's open/collapse state, useSidebarLayout coordinates multiple sidebars and the shared backdrop, and useSidebarMenuItem manages expandable submenus inside the sidebar. See Primitive for a component-based API.
Features#
- Open/collapse lifecycle — controlled or uncontrolled open state with icon, offcanvas, or non-collapsible modes
- Layout coordination —
useSidebarLayoutregisters multiple sidebars, exposes a shared backdrop, and drives cross-sidebar toggles - Hover-to-open — optional pointer-enter expansion with configurable open/close delays
- Positional variants —
left/rightplacement plussidebar,floating, andinsetvisual variants - Collapsible menu items —
useSidebarMenuItemexposes expandable submenu state with spread-ready trigger and content props - Data-driven styling —
data-state,data-variant,data-collapsible,data-side, anddata-overlayattributes make CSS targeting declarative
Working with callbacks#
Composing layout with sidebars#
Create a layout once and pass it to each sidebar that should coordinate backdrop, toggles, and registration.
const layout = useSidebarLayout({});
const left = useSidebar({ id: 'nav', layout, side: 'left' });
const right = useSidebar({ id: 'details', layout, side: 'right' });
<li>
<button {...triggerProps}>Menu Item</button>
{state.open && <ul {...contentProps}>...</ul>}
</li>;Controlled open state#
Drive the sidebar from external state by pairing open with onOpenChange.
const [open, setOpen] = React.useState(true);
const sidebar = useSidebar({
open,
onOpenChange: (e) => setOpen(e.value)
});Opening on hover#
Enable openOnHover for icon-collapsed sidebars that should reveal on pointer enter. Tune the timing with hoverOpenDelay and hoverCloseDelay to reduce flicker.
const sidebar = useSidebar({
collapsible: 'icon',
openOnHover: true,
hoverOpenDelay: 100,
hoverCloseDelay: 200
});Triggering sidebars from elsewhere#
Use the layout's imperative helpers to toggle or collapse sidebars from buttons outside the aside — for example a header toggle.
<button onClick={() => layout.toggle('nav')}>Toggle nav</button>
<button onClick={() => layout.collapse()}>Collapse all</button>Collapsible menu items#
useSidebarMenuItem returns triggerProps and contentProps for expandable groups. Render the content conditionally from state.open.
const { state, triggerProps, contentProps } = useSidebarMenuItem({
collapsible: true,
defaultOpen: false
});Styling with data attributes#
rootProps from useSidebar expose state through data-* attributes so CSS can react without className juggling.
| Attribute | Values |
|---|---|
data-state | expanded | collapsed |
data-variant | sidebar | floating | inset |
data-collapsible | offcanvas | icon | (empty when expanded) |
data-collapsible-mode | offcanvas | icon | none (always present) |
data-side | left | right |
data-overlay | present when overlay is true |
[data-scope='sidebar'][data-state='collapsed'][data-collapsible='icon'] {
width: 3rem;
}
[data-scope='sidebar'][data-side='right'] {
border-left: 1px solid var(--p-content-border-color);
}API#
useSidebar#
| Name | Type | Default |
|---|---|---|
layout | useSidebarLayoutExposes | — |
| Layout context for registering/notifying within a Sidebar.Layout. | ||
id | string | — |
| Unique identifier for the sidebar, used by Trigger target. | ||
side | "left" | "right" | 'left' |
| Sidebar position. | ||
variant | "sidebar" | "floating" | "inset" | 'sidebar' |
| Visual variant of the sidebar. | ||
collapsible | "icon" | "none" | "offcanvas" | 'icon' |
| Collapse behavior. | ||
overlay | boolean | false |
| Whether the sidebar overlays content instead of pushing it. | ||
open | boolean | — |
| Controls the open state of the sidebar. | ||
defaultOpen | boolean | true |
| Initial open state. | ||
onOpenChange | (event: useSidebarOpenChangeEvent) => void | — |
| Callback when the open state changes. | ||
openOnHover | boolean | false |
| Whether the sidebar opens on hover. | ||
hoverOpenDelay | number | 50 |
| Delay before opening on hover (ms). | ||
hoverCloseDelay | number | 100 |
| Delay before closing on hover leave (ms). | ||
dismissable | boolean | true |
| Whether clicking the backdrop closes the sidebar. | ||
hideOnOutsideClick | boolean | true |
| When `overlay` is true, clicking inside the `Sidebar.Main` area collapses the sidebar. Clicks on a `Sidebar.Trigger` are excluded so opening via the trigger is not immediately undone. | ||
width | string | '16rem' |
| Sidebar width when expanded. | ||
iconWidth | string | '3rem' |
| Sidebar width when collapsed to icon mode. | ||
useSidebarLayout#
| Name | Type | Default |
|---|---|---|
useSidebarMenuItem#
| Name | Type | Default |
|---|---|---|
collapsible | boolean | — |
open | boolean | — |
defaultOpen | boolean | — |
disabled | boolean | — |
onOpenChange | (event: { originalEvent: SyntheticEvent; value: boolean }) => void | — |
Accessibility#
Arrow keys navigate items, Enter activates links, and Right/Left expand or collapse nested groups. See Primitive for full WAI-ARIA compliance details.