Sidebar

A composable, themeable and customizable sidebar component.

Stimulus: shadcn--sidebar

Dashboard

Welcome to your dashboard. Use the sidebar to navigate.

Installation

Add the sidebar components to your project:

rails generate shadcn:component sidebar

Usage

<%= render Shadcn::SidebarProviderComponent.new do |provider| %>
  <% provider.with_sidebar do |sidebar| %>
    <% sidebar.with_header do %>
      <div class="flex items-center gap-2 px-4 py-2">
        <span class="font-semibold">My App</span>
      </div>
    <% end %>
    <% sidebar.with_sidebar_content do |content| %>
      <%= render Shadcn::SidebarGroupComponent.new do |group| %>
        <% group.with_label { "Navigation" } %>
        <% group.with_group_content do %>
          <%= render Shadcn::SidebarMenuComponent.new do |menu| %>
            <%= render Shadcn::SidebarMenuItemComponent.new do |item| %>
              <% item.with_button(href: "/dashboard") { "Dashboard" } %>
            <% end %>
            <%= render Shadcn::SidebarMenuItemComponent.new do |item| %>
              <% item.with_button(href: "/settings") { "Settings" } %>
            <% end %>
          <% end %>
        <% end %>
      <% end %>
    <% end %>
  <% end %>
<% end %>

Structure

The sidebar component is built from many composable parts:

Component Description
SidebarProviderComponent Root wrapper that provides sidebar context and state
SidebarComponent The main sidebar container
SidebarHeaderComponent Header section (logo, app name)
SidebarContentComponent Scrollable content area
SidebarFooterComponent Footer section (user profile, settings)
SidebarGroupComponent Group container for menu items
SidebarGroupLabelComponent Label for a group section
SidebarMenuComponent Menu container
SidebarMenuItemComponent Individual menu item
SidebarMenuButtonComponent Button/link within menu item
SidebarMenuBadgeComponent Badge for menu items (counts, status)
SidebarMenuSubComponent Submenu container
SidebarRailComponent Thin rail for collapsed sidebar
SidebarTriggerComponent Toggle button for sidebar
SidebarInsetComponent Content area with margin for sidebar

Examples

Variants

The sidebar supports three visual variants.

  • variant: :sidebar - Default fixed sidebar
  • variant: :floating - Floating sidebar with padding
  • variant: :inset - Inset sidebar with background transparency

Collapsible Modes

Control how the sidebar collapses.

  • collapsible: :offcanvas - Slides off screen when collapsed
  • collapsible: :icon - Collapses to icon-only mode
  • collapsible: :none - Non-collapsible sidebar

Side

Position the sidebar on either side of the viewport.

  • side: :left - Left side (default)
  • side: :right - Right side

Keyboard Shortcut

Toggle the sidebar with Cmd/Ctrl + B. The shortcut key is customizable:

<%= render Shadcn::SidebarProviderComponent.new(keyboard_shortcut: "s") do |provider| %>
  <!-- Sidebar will toggle with Cmd/Ctrl + S -->
<% end %>

API Reference

SidebarProviderComponent

API Reference

Prop Type Default Description
default_open Boolean true Whether sidebar starts open
open Boolean nil Controlled open state
keyboard_shortcut String "b" Key for Cmd/Ctrl shortcut

SidebarComponent

API Reference

Prop Type Default Description
side Symbol :left Side to show sidebar (:left, :right)
variant Symbol :sidebar Visual style (:sidebar, :floating, :inset)
collapsible Symbol :offcanvas Collapse mode (:offcanvas, :icon, :none)
default_open Boolean true Whether sidebar starts open

SidebarComponent Slots

Slot Description
with_header Header section with logo/title
with_sidebar_content Main scrollable content area
with_footer Footer section for user info
with_rail Thin rail for collapsed state

Stimulus Controller

This component requires JavaScript. The Stimulus controller docs provides interactivity.

Manages sidebar open/closed state, keyboard shortcuts, and responsive behavior.

Installation

Add to your config/importmap.rb:

pin "shadcn-rails", to: "shadcn/index.js"

Then in your app/javascript/controllers/index.js:

import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"

const application = Application.start()
registerShadcnControllers(application)

Or import just this controller:

import DocsController from "shadcn-rails/controllers/docs_controller"

application.register("docs", DocsController)

Values

Name Type Default Description
open Boolean Whether sidebar is open (desktop)
openMobile Boolean Whether sidebar is open (mobile)
keyboardShortcut String Key for Cmd/Ctrl shortcut

Actions

Action Description
toggle Toggle sidebar open/closed
open Open the sidebar
close Close the sidebar
clickOutside Close on outside click (mobile)

TypeScript

Type definitions are included. Import types as needed:

import type { DocsController } from "shadcn-rails"

Accessibility

  • Keyboard shortcut: Cmd/Ctrl + B to toggle
  • State is persisted in a cookie across page loads
  • Responsive behavior: collapses automatically on mobile screens
  • Click outside to close on mobile devices
  • Smooth transitions between expanded and collapsed states

Theming

The sidebar uses CSS custom properties for theming:

Variable Default Description
--sidebar-width 16rem Width of expanded sidebar
--sidebar-width-icon 3rem Width when collapsed to icons
--sidebar-background hsl(var(--sidebar)) Background color
--sidebar-foreground hsl(var(--sidebar-foreground)) Text color