Sidebar
Sidebar renders persistent navigation on desktop and reuses modal Drawer behavior on small screens. Content stays consumer-owned while Akaza UI manages responsive state, collapse geometry, resizing, focus, dismissal, and accessibility.
Anatomy
#header: Fixed region for branding, workspace controls, or an internal collapse action.#default: Scrollable navigation or application content.#footer: Fixed region for account controls or secondary actions.#resize-handle: Optional content inside the generated accessible resize separator.
Every slot receives responsive state, size, and safe action functions. Toggle controls outside the sidebar should use v-model or useSidebar; Akaza does not require a separate trigger sub-component.
Usage
Dashboard
Resize the sidebar or reduce the preview width to see mobile modal behavior.
Selected: overview
Examples
Nested navigation
Compose Sidebar with a vertical NavigationMenu for groups, nested items, active state, badges, collapsed tooltips, and side flyouts. The sidebar owns responsive layout; the navigation menu owns navigation state.
akaza-ui
Selected navigation value
Collapse modes
Use icon when compact controls remain usable. Use offcanvas when the complete desktop panel should leave the layout.
<Sidebar v-model:collapsed="collapsed" collapsible="icon" />
<Sidebar v-model:collapsed="hidden" collapsible="offcanvas" />
<Sidebar :collapsible="false" />
In icon mode, slot content remains mounted and interactive. Use the slot's collapsed value to hide labels or replace content. Off-canvas content becomes inert and aria-hidden when collapsed.
Mobile dialog
breakpoint controls when the persistent sidebar becomes a modal drawer. mobile can override media-query detection for container-based layouts or tests.
<script setup lang="ts">
import { ref } from "vue";
const open = ref(false);
</script>
<template>
<button :aria-expanded="open" @click="open = true">Open navigation</button>
<Sidebar
v-model:open="open"
breakpoint="(max-width: 64rem)"
side="left"
aria-label="Main navigation"
>
<nav>...</nav>
</Sidebar>
</template>
Mobile mode traps focus, locks body scrolling, makes the outside tree inert, closes on Escape or backdrop interaction, restores focus, and supports directional swipe dismissal. Activating an unmodified same-window link closes the sidebar by default.
Resizing
Enable the generated separator with resizable. Size uses pixels and supports controlled or uncontrolled state.
<Sidebar
v-model:size="size"
resizable
:default-size="256"
:min-size="192"
:max-size="480"
:resize-step="8"
>
<template #resize-handle>
<span aria-hidden="true" />
</template>
</Sidebar>
The resize handle supports pointer, pen, touch, and keyboard input. Double-click resets to defaultSize.
Right sidebar
Placement also changes pointer and keyboard resize direction.
<Sidebar side="right" collapsible="icon" resizable aria-label="Inspector">
<template #header>Inspector</template>
Properties
</Sidebar>
Keyboard shortcut
Global shortcuts are opt-in to avoid application conflicts. keyboardShortcut="b" uses Command+B on macOS and Ctrl+B elsewhere.
<Sidebar keyboard-shortcut="b" collapsible="icon" />
Shortcuts are ignored while focus is inside an input, textarea, select, or editable element.
Custom behavior with useSidebar
Pass a component ref when controls live outside a sidebar. Each composable instance controls only the referenced sidebar, so an application can manage multiple sidebars independently.
<script setup lang="ts">
import type { SidebarController } from "akaza-ui";
import { Sidebar, useSidebar } from "akaza-ui";
import { useTemplateRef } from "vue";
const sidebarRef = useTemplateRef<SidebarController>("sidebar");
const sidebar = useSidebar(sidebarRef);
</script>
<template>
<button type="button" @click="sidebar.toggle">Toggle navigation</button>
<Sidebar ref="sidebar" collapsible="icon">...</Sidebar>
</template>
For state owned outside the component, useSidebar({ open, collapsed, breakpoint }) remains available. Persistence and route watching remain application concerns.
useSidebar
The composable has component-ref and controlled-state modes. See useSidebar for both signatures, options, returned state, event-safe actions, multiple-sidebar examples, and SSR behavior.
API Reference
Models
| Model | Type | Default | Description |
|---|---|---|---|
v-model:open | boolean | defaultOpen | Mobile dialog visibility. |
v-model:collapsed | boolean | defaultCollapsed | Desktop collapse state. Ignored when collapsible is false. |
v-model:size | number | defaultSize | Expanded desktop width in pixels. |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as | Component | string | "aside" | Desktop panel element. |
side | "left" | "right" | "left" | Sidebar edge. |
collapsible | false | "icon" | "offcanvas" | false | Desktop collapse behavior. |
defaultOpen | boolean | false | Initial uncontrolled mobile visibility. |
defaultCollapsed | boolean | false | Initial uncontrolled desktop collapse state. |
defaultSize | number | 256 | Initial expanded width in pixels. |
minSize | number | 192 | Minimum resized width. |
maxSize | number | 480 | Maximum resized width. |
collapsedSize | number | 48 | Width in icon collapse mode. |
mobileSize | number | 288 | Mobile drawer width. |
resizeStep | number | 8 | Keyboard resize amount in pixels. Shift multiplies it by ten. |
resizable | boolean | false | Render the accessible resize separator. |
transition | boolean | true | Enable desktop width and off-canvas transitions. |
mobile | boolean | media query | Force mobile or desktop rendering. |
breakpoint | string | "(max-width: 767px)" | Media query used when mobile is omitted. |
closeOnBackdropClick | boolean | true | Close the mobile dialog on backdrop interaction. |
closeOnNavigate | boolean | true | Close mobile mode after activating a same-window link. |
swipeToClose | boolean | true | Enable directional mobile swipe dismissal. |
teleport | string | false | "body" | Mobile drawer Teleport target. |
keyboardShortcut | string | false | false | Command/Ctrl shortcut key for responsive toggle. |
ariaLabel | string | "Sidebar" | Desktop landmark and mobile dialog accessible name. |
resizeAriaLabel | string | "Resize sidebar" | Resize separator accessible name. |
ui | SidebarUi | — | Classes for named structural parts. |
Slots
| Slot | Scoped props | Description |
|---|---|---|
header | SidebarSlotProps | Fixed header region. |
default | SidebarSlotProps | Scrollable body region. |
footer | SidebarSlotProps | Fixed footer region. |
resize-handle | SidebarSlotProps | Content inside the generated separator handle. |
SidebarSlotProps exposes open, collapsed, isMobile, state, size, openMobile, closeMobile, toggleMobile, expand, collapse, toggleCollapsed, toggle, and resetSize. On mobile, collapsed is always false.
Emits
| Event | Payload | Description |
|---|---|---|
open-change | [open, details] | Cancelable mobile visibility change. |
collapsed-change | [collapsed, details] | Cancelable desktop collapse change. |
size-change | [size, details] | Cancelable pointer, keyboard, or reset size change. Details include previousSize. |
Exposed methods
| Method | Description |
|---|---|
open / openMobile | Open mobile visibility. open is a concise alias. |
close / closeMobile | Close mobile visibility. close is a concise alias. |
toggleMobile | Toggle mobile visibility regardless of responsive state. |
toggle | Toggle mobile visibility or desktop collapse based on responsive state. |
expand / collapse | Change desktop collapse state. |
toggleCollapsed | Toggle desktop collapse state. |
resetSize | Restore defaultSize. |
Exposed values
| Value | Type | Description |
|---|---|---|
openValue | boolean | Current mobile visibility. |
collapsedValue | boolean | Current desktop collapse value. |
sizeValue | number | Current expanded width in pixels. |
isMobile | boolean | Current responsive mode. |
state | SidebarState | Current open, closed, expanded, or collapsed state. |
Prefer useSidebar(sidebarRef) when consuming these values outside the component.
UI Options
| Key | Description |
|---|---|
root | Responsive root and desktop width container. |
panel | Desktop panel or inner mobile panel. |
header | Fixed header region. |
body | Scrollable body region. |
footer | Fixed footer region. |
resizeHandle | Accessible resize separator. |
mobileOverlay | Mobile modal backdrop. |
mobileContent | Mobile Drawer dialog panel. |
mobileWrapper | Structural wrapper inside the mobile Drawer. |
Styling Hooks
| UI key | CSS class | Data attrs |
|---|---|---|
root | akaza-sidebar-root | data-akaza-state, data-akaza-side, data-akaza-mobile, data-akaza-collapsible, data-akaza-collapsed, data-akaza-resizing, data-akaza-transition |
panel | akaza-sidebar-panel | data-akaza-state, data-akaza-side, data-akaza-mobile |
header | akaza-sidebar-header | — |
body | akaza-sidebar-body | — |
footer | akaza-sidebar-footer | — |
resizeHandle | akaza-sidebar-resize-handle | data-akaza-side, data-akaza-resizing |
mobileOverlay | akaza-sidebar-mobile-overlay | Drawer data-akaza-state is also available on the same element. |
mobileContent | akaza-sidebar-mobile-content | Drawer data-akaza-state and data-akaza-side are also available on the same element. |
mobileWrapper | akaza-sidebar-mobile-wrapper | — |
Width and motion can also be configured through --akaza-sidebar-size, --akaza-sidebar-collapsed-size, --akaza-sidebar-mobile-size, --akaza-sidebar-transition-duration, and --akaza-sidebar-transition-easing.
Plain class applies to the single root. Use ui for the panel, regions, resize handle, and teleported mobile parts.
Keyboard
| Key | Behavior |
|---|---|
Arrow Left / Arrow Right | Resize by resizeStep; direction follows sidebar placement. |
Shift + Arrow Left / Shift + Arrow Right | Resize by ten times resizeStep. |
Home / End | Resize to minimum or maximum width. |
Escape | Close mobile mode and restore focus. |
Tab / Shift + Tab | Remain inside the open mobile dialog. |
Command/Ctrl + configured key | Toggle current responsive state when keyboardShortcut is enabled. |
Pointer, pen, and touch input can resize the desktop separator. Mobile mode supports backdrop and swipe dismissal. Desktop mode remains non-modal and never traps focus.