Check out BugBytes overview of labb

Drawer

<c-lb.drawer /> Markdown

Drawer component for Django: build slide-out sidebars and off-canvas panels. Built with django-cotton, Tailwind CSS, and daisyUI 5. Zero JavaScript by default.

Drawer renders a CSS-driven slide-out panel using checkbox toggle state — no JavaScript needed. c-lb.drawer.side holds the panel content; c-lb.drawer.content holds the main page area.

Basic Drawer

<c-lb.drawer drawerId="a-basic-drawer" sideClass="z-99">
  <c-slot name="sideContent">
    <div class="p-4 h-full bg-base-200 w-64">
      <h3 class="text-lg font-semibold mb-4">Navigation Menu</h3>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Dashboard" />
        <c-lb.menu.item title="Profile" />
        <c-lb.menu.item title="Settings" />
        <c-lb.menu.item title="Messages" />
        <c-lb.menu.item title="Help" />
      </c-lb.menu>
    </div>
  </c-slot>

  <div class="flex flex-col items-center justify-center p-4">
    <c-lb.drawer.toggle for="a-basic-drawer" class="btn btn-primary">
      Open Drawer
    </c-lb.drawer.toggle>
  </div>
</c-lb.drawer>

Right Positioned Drawer

<c-lb.drawer drawerId="right-drawer" end sideClass="z-99">
  <c-slot name="sideContent">
    <div class="p-4 h-full bg-base-200 w-64">
      <h3 class="text-lg font-semibold mb-4">Right Side Menu</h3>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Notifications" />
        <c-lb.menu.item title="User Profile" />
        <c-lb.menu.item title="Preferences" />
        <c-lb.menu.item title="Logout" />
      </c-lb.menu>
    </div>
  </c-slot>

  <div class="flex flex-col items-center justify-center p-4">
    <c-lb.drawer.toggle for="right-drawer" class="btn btn-primary">
      Open Right Drawer
    </c-lb.drawer.toggle>
  </div>
</c-lb.drawer>

Open by Default

Open by Default

This drawer starts open when the page loads.

This drawer is open by default.

<c-lb.drawer drawerId="open-drawer" open sideClass="z-40 h-96">
  <c-slot name="sideContent">
    <div class="p-4 h-full bg-base-200 w-48 sm:w-64">
      <h3 class="text-lg font-semibold mb-4">Open by Default</h3>
      <p class="mb-4">This drawer starts open when the page loads.</p>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Home" active />
        <c-lb.menu.item title="About" />
        <c-lb.menu.item title="Contact" />
      </c-lb.menu>
    </div>
  </c-slot>

  <div class="flex flex-col items-center justify-center p-4 h-full">
    <p class="text-center">This drawer is open by default.</p>
  </div>
</c-lb.drawer>

Responsive Layout

A toggle button will show on small screens and hide on large screens

<c-lb.drawer drawerId="responsive-drawer" class="lg:drawer-open" sideClass="z-99 lg:z-40 h-full lg:h-96">
  <c-slot name="sideContent">
    <div class="p-4 h-full bg-base-200 w-64">
      <h3 class="text-lg font-semibold mb-4">Responsive Sidebar</h3>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Dashboard" />
        <c-lb.menu.item title="Analytics" />
        <c-lb.menu.item title="Reports" />
        <c-lb.menu.item title="Settings" />
      </c-lb.menu>
    </div>
  </c-slot>

  <div class="flex flex-col items-center justify-center p-4 h-full gap-4">
    <p>A toggle button will show on small screens and hide on large screens</p>
    <c-lb.drawer.toggle for="responsive-drawer" class="btn btn-primary lg:hidden">
      Toggle Sidebar
    </c-lb.drawer.toggle>
  </div>
</c-lb.drawer>

Icon Only Sidebar

Main content area. The sidebar collapses to icon-only mode on large screens and can be toggled.

<c-lb.drawer drawerId="icon-only-drawer" class="lg:drawer-open" sideClass="z-99 lg:z-40 h-full lg:h-96 is-drawer-close:overflow-visible">
  <c-slot name="sideContent">
    <div class="flex flex-col items-start h-full bg-base-200 transition-[width] is-drawer-close:w-14 is-drawer-open:w-64">
      <ul class="menu w-full grow">
        <li>
          <a href="#" class="is-drawer-close:tooltip is-drawer-close:tooltip-right" data-tip="Home">
            <c-lbi n="rmx.home" w="1em" h="1em" class="my-1.5 shrink-0" />
            <span class="is-drawer-close:hidden">Home</span>
          </a>
        </li>
        <li>
          <a href="#" class="is-drawer-close:tooltip is-drawer-close:tooltip-right" data-tip="Analytics">
            <c-lbi n="rmx.bar-chart-2" w="1em" h="1em" class="my-1.5 shrink-0" />
            <span class="is-drawer-close:hidden">Analytics</span>
          </a>
        </li>
        <li>
          <a href="#" class="is-drawer-close:tooltip is-drawer-close:tooltip-right" data-tip="Reports">
            <c-lbi n="rmx.file-list" w="1em" h="1em" class="my-1.5 shrink-0" />
            <span class="is-drawer-close:hidden">Reports</span>
          </a>
        </li>
        <li>
          <a href="#" class="is-drawer-close:tooltip is-drawer-close:tooltip-right" data-tip="Settings">
            <c-lbi n="rmx.settings-3" w="1em" h="1em" class="my-1.5 shrink-0" />
            <span class="is-drawer-close:hidden">Settings</span>
          </a>
        </li>
      </ul>
    </div>
  </c-slot>

  <div class="flex flex-col h-full lg:h-96">
    <nav class="navbar bg-base-300 w-full">
      <c-lb.drawer.toggle for="icon-only-drawer" class="btn btn-square btn-ghost">
        <c-lbi n="rmx.sidebar-fold" w="1em" h="1em" />
      </c-lb.drawer.toggle>
      <div class="px-4 font-bold">My App</div>
    </nav>
    <div class="p-6 flex-1">
      <p class="text-base-content/70">Main content area. The sidebar collapses to icon-only mode on large screens and can be toggled.</p>
    </div>
  </div>
</c-lb.drawer>

Custom Overlay

Custom Overlay

This drawer has a custom dark overlay.

<c-lb.drawer drawerId="custom-overlay-drawer" overlayClass="bg-black bg-opacity-50" sideClass="z-99">
  <c-slot name="sideContent">
    <div class="p-4 h-full bg-base-200 w-64">
      <h3 class="text-lg font-semibold mb-4">Custom Overlay</h3>
      <p class="mb-4">This drawer has a custom dark overlay.</p>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Dashboard" />
        <c-lb.menu.item title="Analytics" />
        <c-lb.menu.item title="Reports" />
        <c-lb.menu.item title="Settings" />
      </c-lb.menu>
    </div>
  </c-slot>

  <div class="flex flex-col items-center justify-center p-4">
    <c-lb.drawer.toggle for="custom-overlay-drawer" class="btn btn-secondary">
      Open with Custom Overlay
    </c-lb.drawer.toggle>
  </div>
</c-lb.drawer>

With Submenus

<c-lb.drawer drawerId="submenu-drawer" sideClass="z-99">
  <c-slot name="sideContent">
    <div class="p-4 h-full bg-base-200 w-64">
      <h3 class="text-lg font-semibold mb-4">With Submenus</h3>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Dashboard" />
        <c-lb.menu.item type="submenu-details" title="Products" open>
          <c-lb.menu.item title="All Products" />
          <c-lb.menu.item title="Categories" />
          <c-lb.menu.item title="Inventory" />
        </c-lb.menu.item>
        <c-lb.menu.item type="submenu-details" title="Users">
          <c-lb.menu.item title="All Users" />
          <c-lb.menu.item title="Roles" />
          <c-lb.menu.item title="Permissions" />
        </c-lb.menu.item>
        <c-lb.menu.item title="Settings" />
      </c-lb.menu>
    </div>
  </c-slot>

  <div class="flex flex-col items-center justify-center p-4">
    <c-lb.drawer.toggle for="submenu-drawer" class="btn btn-accent">
      Open with Submenus
    </c-lb.drawer.toggle>
  </div>
</c-lb.drawer>

Default Slot Only

Default Slot Only

This drawer only uses the default slot - no sidebar.

<c-lb.drawer drawerId="default-slot-drawer">
  <div class="flex flex-col items-center justify-center p-4 text-center">
    <h2 class="text-2xl font-bold mb-4">Default Slot Only</h2>
    <p class="mb-4">This drawer only uses the default slot - no sidebar.</p>
    <c-lb.button variant="primary">Simple Button</c-lb.button>
  </div>
</c-lb.drawer>

Custom Checkbox

Custom Checkbox

This drawer uses a custom checkbox slot.

<c-lb.drawer drawerId="custom-checkbox-drawer" sideClass="z-99">
  <c-slot name="checkbox">
    <c-lb.drawer.checkbox id="custom-checkbox-drawer" />
  </c-slot>

  <c-slot name="sideContent">
    <div class="p-4 h-full bg-base-200 w-64">
      <h3 class="text-lg font-semibold mb-4">Custom Checkbox</h3>
      <p class="mb-4">This drawer uses a custom checkbox slot.</p>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Home" />
        <c-lb.menu.item title="About" />
        <c-lb.menu.item title="Contact" />
      </c-lb.menu>
    </div>
  </c-slot>

  <div class="flex flex-col items-center justify-center p-4">
    <c-lb.drawer.toggle for="custom-checkbox-drawer" class="btn btn-primary">
      Open with Custom Checkbox
    </c-lb.drawer.toggle>
  </div>
</c-lb.drawer>

Custom Content

Custom Content

The main content area was completely customized.

Custom Content Area

This drawer uses a custom content slot with a main element.

<c-lb.drawer drawerId="custom-content-drawer" sideClass="z-99">
  <c-slot name="content">
    <c-lb.drawer.content as="main" class="flex flex-col items-center justify-center p-4 text-center">
      <h2 class="text-2xl font-bold mb-4">Custom Content Area</h2>
      <p class="mb-4">This drawer uses a custom content slot with a main element.</p>
      <c-lb.drawer.toggle for="custom-content-drawer" class="btn btn-secondary">
        Open Drawer
      </c-lb.drawer.toggle>
    </c-lb.drawer.content>
  </c-slot>

  <c-slot name="sideContent">
    <div class="p-4 h-full bg-base-200 w-64">
      <h3 class="text-lg font-semibold mb-4">Custom Content</h3>
      <p class="mb-4">The main content area was completely customized.</p>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Dashboard" />
        <c-lb.menu.item title="Profile" />
        <c-lb.menu.item title="Settings" />
      </c-lb.menu>
    </div>
  </c-slot>
</c-lb.drawer>

Custom Side

Custom Side

This drawer uses a custom side slot with gradient background.

<c-lb.drawer drawerId="custom-side-drawer" sideClass="z-99">
  <c-slot name="side">
    <c-lb.drawer.side class="z-99">
      <c-lb.drawer.overlay for="custom-side-drawer" />
      <div class="p-4 h-full bg-gradient-to-b from-primary to-secondary text-primary-content w-64">
        <h3 class="text-lg font-semibold mb-4">Custom Side</h3>
        <p class="mb-4">This drawer uses a custom side slot with gradient background.</p>
        <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
          <c-lb.menu.item title="Home" />
          <c-lb.menu.item title="About" />
          <c-lb.menu.item title="Contact" />
        </c-lb.menu>
      </div>
    </c-lb.drawer.side>
  </c-slot>

  <div class="flex flex-col items-center justify-center p-4">
    <c-lb.drawer.toggle for="custom-side-drawer" class="btn btn-primary">
      Open with Custom Side
    </c-lb.drawer.toggle>
  </div>
</c-lb.drawer>

All Slots Custom

All Custom Slots

Checkbox, content, and side are all customized.

All Slots Custom

This drawer customizes all available slots.

<c-lb.drawer drawerId="all-custom-drawer" end sideClass="z-99">
  <c-slot name="checkbox">
    <c-lb.drawer.checkbox id="all-custom-drawer" />
  </c-slot>

  <c-slot name="content">
    <c-lb.drawer.content as="section" class="flex flex-col items-center justify-center p-4 bg-base-200 text-center">
      <h2 class="text-2xl font-bold mb-4">All Slots Custom</h2>
      <p class="mb-4">This drawer customizes all available slots.</p>
      <c-lb.drawer.toggle for="all-custom-drawer" class="btn btn-accent">
        Open All Custom Drawer
      </c-lb.drawer.toggle>
    </c-lb.drawer.content>
  </c-slot>

  <c-slot name="side">
    <c-lb.drawer.side class="z-99">
      <c-lb.drawer.overlay for="all-custom-drawer" class="bg-black bg-opacity-75" />
      <div class="p-4 h-full bg-base-200 w-64">
        <h3 class="text-lg font-semibold mb-4">All Custom Slots</h3>
        <p class="mb-4">Checkbox, content, and side are all customized.</p>
        <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
          <c-lb.menu.item title="Custom Item 1" />
          <c-lb.menu.item title="Custom Item 2" />
          <c-lb.menu.item title="Custom Item 3" />
        </c-lb.menu>
      </div>
    </c-lb.drawer.side>
  </c-slot>
</c-lb.drawer>

Direct Sub-components

Direct Sub-components

This drawer uses all sub-components directly without any slot overrides.

Direct Components

Every part is explicitly defined using sub-components.

<div class="drawer">
  <c-lb.drawer.checkbox id="direct-drawer" />

  <c-lb.drawer.content>
    <div class="flex flex-col items-center justify-center p-4 text-center">
      <h2 class="text-2xl font-bold mb-4">Direct Sub-components</h2>
      <p class="mb-4 text-center">This drawer uses all sub-components directly without any slot overrides.</p>
      <c-lb.drawer.toggle for="direct-drawer" class="btn btn-primary">
        Open Direct Drawer
      </c-lb.drawer.toggle>
    </div>
  </c-lb.drawer.content>

  <c-lb.drawer.side class="z-99">
    <c-lb.drawer.overlay for="direct-drawer" />
    <div class="p-4 h-full bg-base-200 w-64">
      <h3 class="text-lg font-semibold mb-4">Direct Components</h3>
      <p class="mb-4">Every part is explicitly defined using sub-components.</p>
      <c-lb.menu class="bg-base-200 text-base-content rounded-box w-full">
        <c-lb.menu.item title="Home" />
        <c-lb.menu.item title="About" />
        <c-lb.menu.item title="Contact" />
        <c-lb.menu.item title="Settings" />
      </c-lb.menu>
    </div>
  </c-lb.drawer.side>
</div>

API Reference

c-lb.drawer

Property Type Default Required Description
drawerId string drawer No Drawer ID for checkbox linking
class string - No Additional CSS classes to apply
end boolean False No Position drawer on the right side
open boolean False No Whether the drawer is initially open
sideClass string - No Additional CSS classes to apply to the drawer side
overlayClass string - No Additional CSS classes to apply to the drawer overlay
Slot Name Description
default Main drawer content that gets wrapped in <c-lb.drawer.content> when content slot is not used
checkbox Custom drawer toggle checkbox. Defaults to <c-lb.drawer.checkbox> if not provided
content Complete custom drawer content area. Defaults to <c-lb.drawer.content> wrapping the default slot
sideContent Sidebar content that gets wrapped in <c-lb.drawer.side> with overlay automatically added
side For custom sidebar component as alternative to sideContent slot

c-lb.drawer.checkbox

Property Type Default Required Description
class string - No Additional CSS classes to apply

c-lb.drawer.content

Property Type Default Required Description
class string - No Additional CSS classes to apply
as
div main section article
div No HTML element to render as

c-lb.drawer.side

Property Type Default Required Description
class string - No Additional CSS classes to apply

c-lb.drawer.toggle

Property Type Default Required Description
class string - No Additional CSS classes to apply
for string - No ID of the drawer checkbox to control (for label elements)

c-lb.drawer.overlay

Property Type Default Required Description
class string - No Additional CSS classes to apply