SutraUI.Sidebar (Sutra UI v0.2.0)

View Source

A 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-hidden state
  • Sets inert attribute 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-open attribute 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

sidebar(assigns)

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 to true.
  • mobile_open (:boolean) - Initial open state for mobile. Defaults to false.
  • breakpoint (:integer) - Pixel width for mobile breakpoint. Defaults to 768.
  • label (:string) - ARIA label for navigation. Defaults to "Sidebar navigation".
  • class (:string) - Additional CSS classes. Defaults to nil.

Slots

  • header - Optional header content.
  • footer - Optional footer content.
  • inner_block (required) - Main sidebar content.