DRAWER: Side panel overlay for sub-level content
CLASSES: .drawer | .drawer-header | .drawer-title | .drawer-body | .drawer-footer | .drawer-backdrop
VARIANTS: Default (right) | .drawer-start (left) | .drawer-sm | .drawer-lg | .drawer-wide
COMPOSES: Button (.btn, .btn-icon, .btn-tertiary, .btn-primary, .btn-secondary) | Form controls
Drawer slides in from the edge of the screen to display secondary content such as filters, settings, or forms. It overlays the page content and can optionally include a backdrop. Uses existing button components for the close icon and footer actions.
Default: Slides in from the right edge. 480px wide with header, scrollable body, and footer.
The close button reuses .tw-btn .tw-btn-icon .tw-btn-tertiary. Footer buttons reuse
.tw-btn .tw-btn-secondary and .tw-btn .tw-btn-primary.
<div class="tw-drawer"><div class="tw-drawer-header">...</div><div class="tw-drawer-body">...</div><div class="tw-drawer-footer">...</div></div>
.tw-drawer-start: Slides in from the left edge instead of the right. Shadow is mirrored to the right side.
<div class="tw-drawer tw-drawer-start">...</div>
Sizes: .tw-drawer-sm (360px) | default (480px) |
.tw-drawer-lg (600px) | .tw-drawer-wide (720px).
All sizes become full-width on mobile screens (< 640px).
<div class="tw-drawer tw-drawer-sm"> | <div class="tw-drawer tw-drawer-lg"> | <div class="tw-drawer tw-drawer-wide">
No footer: Omit the .tw-drawer-footer section for informational or read-only drawers.
The body expands to fill the remaining space.
<div class="tw-drawer"><div class="tw-drawer-header">...</div><div class="tw-drawer-body">...</div></div>
Overflow: When body content exceeds the available height, the
.tw-drawer-body scrolls independently while the header and footer remain fixed.
No backdrop: Omit the .tw-drawer-backdrop element for drawers that
don't need to dim the background. The drawer still supports Escape key to close.
<!-- Simply omit .tw-drawer-backdrop element -->
Accessibility: The drawer traps focus while open, supports Escape to close, and returns focus to the trigger element on close.
| Key | Action |
|---|---|
Escape |
Close the drawer and return focus to trigger |
Tab |
Move focus to next focusable element (trapped within drawer) |
Shift + Tab |
Move focus to previous focusable element (trapped within drawer) |
Container: .tw-drawer | .tw-drawer.tw-show | .tw-drawer-start | .tw-drawer-sm | .tw-drawer-lg | .tw-drawer-wide
Sections: .tw-drawer-header | .tw-drawer-title | .tw-drawer-body | .tw-drawer-footer
Overlay: .tw-drawer-backdrop | .tw-drawer-backdrop.tw-show
Close button: .tw-btn .tw-btn-icon .tw-btn-tertiary (existing component)
Footer buttons: .tw-btn .tw-btn-secondary | .tw-btn .tw-btn-primary (existing components)
Controller: data-controller="drawer" | data-action="click->drawer#open" | data-action="click->drawer#close"