SutraUI.Sidebar (Sutra UI v0.2.0)
View SourceA collapsible sidebar navigation component with mobile toggle support.
The sidebar provides a responsive navigation panel that can be toggled open/closed. It supports:
- Mobile overlay mode with backdrop
- Desktop persistent mode
- Left or right positioning
- Collapsible submenu sections
- Active page highlighting
- Custom header and footer sections
JavaScript Hook
The sidebar requires JavaScript for:
- Mobile toggle functionality
- Close on backdrop/outside click
- Responsive breakpoint handling
- Active page link detection and highlighting
- Managing open/closed state
The component uses a colocated JavaScript hook that is initialized by
providing a unique id attribute.
Examples
# Basic sidebar with simple links
<.sidebar id="main-sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/dashboard">Dashboard</a></li>
<li><a href="/settings">Settings</a></li>
</ul>
</.sidebar>
# Sidebar with header and footer
<.sidebar id="app-sidebar" side="left">
<:header>
<div class="flex items-center gap-2 p-2">
<img src="/logo.svg" alt="Logo" class="w-8 h-8" />
<span class="font-semibold">My App</span>
</div>
</:header>
<.sidebar_group label="Main">
<.sidebar_item href="/">Home</.sidebar_item>
<.sidebar_item href="/dashboard">Dashboard</.sidebar_item>
</.sidebar_group>
<:footer>
<.sidebar_item href="/settings">Settings</.sidebar_item>
</:footer>
</.sidebar>
# Sidebar with collapsible sections
<.sidebar id="nav-sidebar">
<.sidebar_group label="Navigation">
<.sidebar_item href="/">Overview</.sidebar_item>
<.sidebar_submenu label="Projects" open>
<.sidebar_item href="/projects/active">Active</.sidebar_item>
<.sidebar_item href="/projects/archived">Archived</.sidebar_item>
</.sidebar_submenu>
<.sidebar_item href="/team">Team</.sidebar_item>
</.sidebar_group>
</.sidebar>
# Right-side sidebar, initially closed
<.sidebar id="filter-sidebar" side="right" open={false}>
<.sidebar_group label="Filters">
<p>Filter options here...</p>
</.sidebar_group>
</.sidebar>Programmatic Control
You can control the sidebar state from JavaScript using custom events:
// Toggle sidebar
document.dispatchEvent(new CustomEvent('sutra-ui:sidebar', {
detail: { id: 'main-sidebar' }
}));
// Open sidebar
document.dispatchEvent(new CustomEvent('sutra-ui:sidebar', {
detail: { id: 'main-sidebar', action: 'open' }
}));
// Close sidebar
document.dispatchEvent(new CustomEvent('sutra-ui:sidebar', {
detail: { id: 'main-sidebar', action: 'close' }
}));Accessibility
- Uses semantic
<aside>and<nav>elements - Includes proper ARIA labels and
aria-hiddenstate - Sets
inertattribute when closed to prevent keyboard navigation - Automatically manages focus when opened/closed
- Active page links marked with
aria-current="page"
Mobile Behavior
On mobile (below breakpoint):
- Sidebar becomes a full-screen overlay
- Clicking outside the nav closes the sidebar
- Clicking links automatically closes the sidebar
- Use
data-keep-mobile-sidebar-openattribute to prevent auto-close on specific elements
CSS Variables
The sidebar uses these CSS variables:
--sidebar-width: Desktop sidebar width (default: 16rem)--sidebar-mobile-width: Mobile sidebar width (default: 18rem)--sidebar: Background color--sidebar-foreground: Text color--sidebar-accent: Hover/active background--sidebar-accent-foreground: Hover/active text color--sidebar-border: Border color--sidebar-ring: Focus ring color
Summary
Functions
Renders a sidebar navigation component.
Renders a sidebar group with an optional label/heading.
Renders a sidebar navigation item (link).
Renders a separator/divider in the sidebar.
Renders a collapsible sidebar submenu.
Functions
Renders a sidebar navigation component.
Attributes
id(required) - Unique identifier for the sidebar (required for hook)side- Which side to position the sidebar ("left" or "right", default: "left")open- Initial open state for desktop (default: true)mobile_open- Initial open state for mobile (default: false)breakpoint- Pixel width for mobile breakpoint (default: 768)label- ARIA label for navigation (default: "Sidebar navigation")class- Additional CSS classes for the aside container
Slots
header- Optional header content (rendered in nav > header)footer- Optional footer content (rendered in nav > footer)inner_block(required) - Main sidebar content (rendered in nav > section)
Attributes
id(:string) (required) - Unique identifier for the sidebar (required for hook).side(:string) - Which side to position the sidebar. Defaults to"left". Must be one of"left","right","top", or"bottom".open(:boolean) - Initial open state for desktop. Defaults totrue.mobile_open(:boolean) - Initial open state for mobile. Defaults tofalse.breakpoint(:integer) - Pixel width for mobile breakpoint. Defaults to768.label(:string) - ARIA label for navigation. Defaults to"Sidebar navigation".class(:string) - Additional CSS classes. Defaults tonil.
Slots
header- Optional header content.footer- Optional footer content.inner_block(required) - Main sidebar content.
Renders a sidebar group with an optional label/heading.
Attributes
label- Optional heading text for the groupclass- Additional CSS classes
Examples
<.sidebar_group label="Navigation">
<.sidebar_item href="/">Home</.sidebar_item>
<.sidebar_item href="/about">About</.sidebar_item>
</.sidebar_group>
<.sidebar_group>
<.sidebar_item href="/settings">Settings</.sidebar_item>
</.sidebar_group>Attributes
label(:string) - Optional heading for the group. Defaults tonil.class(:string) - Additional CSS classes. Defaults tonil.
Slots
inner_block(required)
Renders a sidebar navigation item (link).
Attributes
href(required) - URL for the linkvariant- Visual variant ("default" or "outline")size- Size variant ("default", "sm", or "lg")current- Whether this is the current pageclass- Additional CSS classesrest- Additional HTML attributes
Examples
<.sidebar_item href="/">Home</.sidebar_item>
<.sidebar_item href="/dashboard" variant="outline">
Dashboard
</.sidebar_item>
<.sidebar_item href="/settings" current>
Settings
</.sidebar_item>
<.sidebar_item href="/profile" size="sm">
Profile
</.sidebar_item>Attributes
href(:string) (required) - URL for the link.variant(:string) - Visual variant. Defaults to"default". Must be one of"default", or"outline".size(:string) - Size variant. Defaults to"default". Must be one of"default","sm", or"lg".current(:boolean) - Whether this is the current page. Defaults tofalse.class(:string) - Additional CSS classes. Defaults tonil.- Global attributes are accepted. Additional HTML attributes. Supports all globals plus:
["target", "rel", "data-ignore-current", "data-keep-mobile-sidebar-open"].
Slots
inner_block(required)
Renders a separator/divider in the sidebar.
Examples
<.sidebar_separator />