0.9.1
DU

Drawer Layout

A responsive layout system with header, sidebar, and main content areas. Includes mobile drawer support with Stimulus-powered toggle.

Interactive Demo

A miniature drawer layout inside a fixed-height container. Try the hamburger button to toggle the mobile sidebar.

B
Demo App
DU

Main Content Area

This is a miniature version of the drawer layout. Resize the browser or use the hamburger button to see the responsive behavior.

Users

128

Active

96

<%= render BetterUi::Drawer::LayoutComponent.new(
  sidebar_position: :left,
  sidebar_breakpoint: :lg
) do |layout| %>
  <% layout.with_header(variant: :light, sticky: true, height: :md) do |header| %>
    <% header.with_mobile_menu_button do %>
      <button data-action="click->better-ui--drawer--layout#toggle">Menu</button>
    <% end %>
    <% header.with_logo { "Logo" } %>
    <% header.with_actions { "Actions" } %>
  <% end %>
  <% layout.with_sidebar(variant: :light, width: :md) do |sidebar| %>
    <% sidebar.with_navigation { render "sidebar_nav" } %>
  <% end %>
  <% layout.with_main { yield } %>
<% end %>

Header Variants

Four visual variants for the header: light, dark, primary, and transparent

Light (variant: :light)

B
BetterUi
light

Dark (variant: :dark)

B
BetterUi
dark

Primary (variant: :primary)

B
BetterUi
primary

Transparent (variant: :transparent)

B
BetterUi
transparent
<%# Light header (default) %>
<%= bui_drawer_header(variant: :light) do |header| %>
  <% header.with_logo { "Logo" } %>
  <% header.with_actions { "Actions" } %>
<% end %>

<%# Dark header %>
<%= bui_drawer_header(variant: :dark) do |header| %>
  <% header.with_logo { "Logo" } %>
<% end %>

<%# Primary header %>
<%= bui_drawer_header(variant: :primary) do |header| %>
  <% header.with_logo { "Logo" } %>
<% end %>

Header Heights

Three height options: sm (h-12), md (h-16), lg (h-20)

Small (h-12) (height: :sm)

height: :sm
Small (h-12)

Medium (h-16) (height: :md)

height: :md
Medium (h-16)

Large (h-20) (height: :lg)

height: :lg
Large (h-20)
<%= bui_drawer_header(height: :sm) do |header| %>
  <% header.with_logo { "Compact" } %>
<% end %>

<%= bui_drawer_header(height: :md) do |header| %>  <%# default %>
  <% header.with_logo { "Standard" } %>
<% end %>

<%= bui_drawer_header(height: :lg) do |header| %>
  <% header.with_logo { "Tall" } %>
<% end %>

Sidebar Variants

Three visual variants for the sidebar: light, dark, and primary

Light

Dark

Primary

<%= bui_drawer_sidebar(variant: :light) do |sidebar| %>
  <% sidebar.with_navigation { ... } %>
<% end %>

<%= bui_drawer_sidebar(variant: :dark) do |sidebar| %>
  <% sidebar.with_navigation { ... } %>
<% end %>

<%= bui_drawer_sidebar(variant: :primary) do |sidebar| %>
  <% sidebar.with_navigation { ... } %>
<% end %>

Sidebar Widths

Three width options: sm (w-16, icon-only), md (w-64, standard), lg (w-80, wide)

Small (w-16) - Icon-only sidebar

Medium (w-64) - Standard sidebar

Large (w-80) - Wide sidebar

<%# Icon-only sidebar %>
<%= bui_drawer_sidebar(width: :sm) do |sidebar| %>
  <% sidebar.with_navigation { ... } %>
<% end %>

<%# Standard sidebar (default) %>
<%= bui_drawer_sidebar(width: :md) do |sidebar| %>
  <% sidebar.with_navigation { ... } %>
<% end %>

<%# Wide sidebar %>
<%= bui_drawer_sidebar(width: :lg) do |sidebar| %>
  <% sidebar.with_navigation { ... } %>
<% end %>

NavGroup with NavItems

Navigation groups with titled sections, icons, active states, and badges

<%# NavGroup without title %>
<%= bui_drawer_nav_group do |group| %>
  <% group.with_item(label: "Dashboard", href: "/", active: true) do |item| %>
    <% item.with_icon { svg_icon } %>
  <% end %>
  <% group.with_item(label: "Analytics", href: "/analytics") do |item| %>
    <% item.with_icon { svg_icon } %>
  <% end %>
<% end %>

<%# NavGroup with title and badges %>
<%= bui_drawer_nav_group(title: "Management") do |group| %>
  <% group.with_item(label: "Users", href: "/users") do |item| %>
    <% item.with_icon { svg_icon } %>
    <% item.with_badge { "24" } %>
  <% end %>
<% end %>

<%# Dark variant for dark sidebars %>
<%= bui_drawer_nav_group(title: "Menu", variant: :dark) do |group| %>
  <% group.with_item(label: "Home", href: "/") do |item| %>
    <% item.with_icon { svg_icon } %>
  <% end %>
<% end %>

Fullscreen Demo

See the drawer layout in action as a full-page application layout

The examples above show individual drawer components. To see them working together as a complete application layout (which is also how this demo site itself is built), visit the fullscreen demo.

Open Fullscreen Demo
<%# Full application layout (e.g., in layouts/application.html.erb) %>
<%= render BetterUi::Drawer::LayoutComponent.new(
  sidebar_position: :left,
  sidebar_breakpoint: :lg
) do |layout| %>
  <% layout.with_header(variant: :dark, sticky: true, height: :md) do |header| %>
    <% header.with_mobile_menu_button do %>
      <button data-action="click->better-ui--drawer--layout#toggle">
        <svg class="w-6 h-6"><!-- hamburger icon --></svg>
      </button>
    <% end %>
    <% header.with_logo { image_tag("logo.svg") } %>
    <% header.with_navigation { render "shared/main_nav" } %>
    <% header.with_actions { render "shared/user_menu" } %>
  <% end %>

  <% layout.with_sidebar(variant: :dark, width: :md) do |sidebar| %>
    <% sidebar.with_header { "App Name" } %>
    <% sidebar.with_navigation { render "shared/sidebar_nav" } %>
    <% sidebar.with_footer { render "shared/sidebar_footer" } %>
  <% end %>

  <% layout.with_main { yield } %>
<% end %>