Sidebar
A composable, collapsible navigation panel wired to a Stimulus controller. Build app shells with a persistent left (or right) drawer that collapses off-canvas.
Note
Because this docs page is itself rendered inside a sidebar layout, embedding a full
sidebar_wrapper in the preview
would create a nested layout conflict. Instead, the individual building blocks are shown
below. For a full working demo, see the
live sidebar test.
Usage โ individual pieces
sidebar_menu_button mirrors Rails
link_to:
pass a name + path and the active state is auto-detected via
current_page?.
sui.sidebar_menu_button "Dashboard", "#"
sui.sidebar_menu_button "Active item", "#", active: true
sui.sidebar_group_label "Platform"
sui.sidebar_separator
Full structure (code only)
Assemble these methods to build a complete sidebar shell. The
sidebar_wrapper owns the
Stimulus controller; sidebar_trigger
and sidebar_rail both dispatch
the toggle action.
sui.sidebar_wrapper do
sui.sidebar do
sui.sidebar_header do
tag.span "My App", class: "font-semibold text-sm px-2"
end
sui.sidebar_content do
sui.sidebar_group do
sui.sidebar_group_label "Platform"
sui.sidebar_group_content do
sui.sidebar_menu do
sui.sidebar_menu_item do
sui.sidebar_menu_button "Dashboard", root_path
end
sui.sidebar_menu_item do
sui.sidebar_menu_button "Settings", settings_path
end
end
end
end
sui.sidebar_separator
sui.sidebar_group do
sui.sidebar_group_label "Account"
sui.sidebar_group_content do
sui.sidebar_menu do
sui.sidebar_menu_item do
sui.sidebar_menu_button "Profile", profile_path
end
end
end
end
end
sui.sidebar_footer do
tag.span "Footer content"
end
sui.sidebar_rail
end
sui.sidebar_inset do
tag.header(class: "flex items-center gap-2 p-4") do
sui.sidebar_trigger
end
tag.div(class: "p-4") do
tag.p "Main content area"
end
end
end
API
| method | signature | description |
|---|---|---|
| sidebar_wrapper | (**opts, &block) | Outermost div. Mounts the Stimulus sidebar controller and sets CSS custom properties for width. |
| sidebar | (side:, variant:, collapsible:, **opts, &block) | The sidebar panel itself. side: is :left (default) or :right. |
| sidebar_header | (**opts, &block) | Flex column at the top of the sidebar, typically for a logo or app name. |
| sidebar_content | (**opts, &block) | Scrollable flex column that fills the remaining vertical space. |
| sidebar_group | (**opts, &block) | A labelled section inside sidebar_content, padded on all sides. |
| sidebar_group_label | (name = nil, **opts, &block) | Small muted heading above a group of links. |
| sidebar_group_content | (**opts, &block) | Wrapper div for the group's menu list. |
| sidebar_menu | (**opts, &block) | Unordered list (ul) that holds menu items with gap spacing. |
| sidebar_menu_item | (**opts, &block) | List item (li) wrapper for a single menu button. |
| sidebar_menu_button | (name, options, active: nil, **html_opts, &block) | An anchor styled as a sidebar row. Mirrors link_to. Auto-sets active via current_page?; pass active: true/false to override. |
| sidebar_separator | (**opts) | Horizontal rule styled with sidebar border colour, with side margins. |
| sidebar_footer | (**opts, &block) | Flex column pinned to the bottom of the sidebar. |
| sidebar_inset | (**opts, &block) | The main content area (main) that sits beside the sidebar, grows to fill remaining space. |
| sidebar_trigger | (**opts) | Icon button that dispatches shadcnrb--sidebar#toggle on click to expand/collapse the sidebar. |
| sidebar_rail | (**opts) | Narrow invisible hit-area along the sidebar edge โ also toggles on click, visible as a faint line on hover. |