Drawer
The Drawer component provides a slide-out panel from the bottom of the screen for displaying additional content, forms, or actions without leaving the current context.
Installation
Add the drawer component to your project:
Alpine.js Required: The drawer component requires Alpine.js for interactivity. Make sure Alpine.js is installed in your project.
Usage
Basic Drawer
Loading preview...
Failed to load preview
Code
Without Overlay
Loading preview...
Failed to load preview
Code
With Form
Loading preview...
Failed to load preview
Code
Interactive Example
Loading preview...
Failed to load preview
Code
Components
The Drawer component consists of several sub-components:
| Component | Purpose |
|---|---|
<x-ui.drawer> |
Main drawer container with Alpine.js state management |
<x-ui.drawer.trigger> |
Button that opens the drawer |
<x-ui.drawer.content> |
The slide-out panel content |
<x-ui.drawer.header> |
Header section with title and description |
<x-ui.drawer.title> |
Drawer title |
<x-ui.drawer.description> |
Optional description below title |
<x-ui.drawer.footer> |
Footer section for action buttons |
<x-ui.drawer.close> |
Button that closes the drawer |
Props
Drawer Root
| Prop | Type | Default | Description |
|---|---|---|---|
open |
boolean |
false |
Whether the drawer is initially open |
closeOnEscape |
boolean |
true |
Whether pressing Escape closes the drawer |
Drawer Content
| Prop | Type | Default | Description |
|---|---|---|---|
showOverlay |
boolean |
true |
Whether to show the dark backdrop overlay |
Drawer Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
target |
string |
required | ID of the drawer to open |
asChild |
boolean |
false |
Whether to render as child element instead of button |
Drawer Close
| Prop | Type | Default | Description |
|---|---|---|---|
target |
string |
required | ID of the drawer to close |
asChild |
boolean |
false |
Whether to render as child element instead of button |
Examples
Basic Drawer Structure
<x-ui.drawer id="my-drawer">
<x-ui.drawer.trigger target="my-drawer">
<x-ui.button>Open</x-ui.button>
</x-ui.drawer.trigger>
<x-ui.drawer.content>
<div class="mx-auto w-full max-w-sm">
<x-ui.drawer.header>
<x-ui.drawer.title>Title</x-ui.drawer.title>
</x-ui.drawer.header>
<div class="p-4">
Your content here
</div>
</div>
</x-ui.drawer.content>
</x-ui.drawer>
With Custom Trigger
<x-ui.drawer id="settings-drawer">
<x-ui.drawer.trigger as-child="true" target="settings-drawer">
<button class="px-4 py-2 bg-blue-500 text-white rounded">
Open Settings
</button>
</x-ui.drawer.trigger>
<x-ui.drawer.content>
<!-- content -->
</x-ui.drawer.content>
</x-ui.drawer>
Controlled with Alpine.js
<div x-data="{ open: false }">
<button @click="$dispatch('drawer-open', { drawerId: 'my-drawer' })">
Open Drawer
</button>
<x-ui.drawer id="my-drawer">
<x-ui.drawer.content>
<div class="p-4">
Drawer content
</div>
</x-ui.drawer.content>
</x-ui.drawer>
</div>
With Livewire
<div x-data="{ open: @entangle($drawerOpen).live }">
<button @click="open = true">Toggle</button>
<x-ui.drawer :open="open" id="livewire-drawer">
<x-ui.drawer.content>
<form wire:submit="save">
<!-- form fields -->
</form>
</x-ui.drawer.content>
</x-ui.drawer>
</div>
Multiple Drawers
<x-ui.drawer id="drawer-1">
<x-ui.drawer.trigger target="drawer-1">
<x-ui.button>Open Drawer 1</x-ui.button>
</x-ui.drawer.trigger>
<!-- content -->
</x-ui.drawer>
<x-ui.drawer id="drawer-2">
<x-ui.drawer.trigger target="drawer-2">
<x-ui.button>Open Drawer 2</x-ui.button>
</x-ui.drawer.trigger>
<!-- content -->
</x-ui.drawer>
Without Close on Escape
<x-ui.drawer :close-on-escape="false" id="important-drawer">
<x-ui.drawer.content>
<div class="p-4">
<p>This drawer requires explicit action to close.</p>
<x-ui.drawer.close target="important-drawer">
<x-ui.button>Close</x-ui.button>
</x-ui.drawer.close>
</div>
</x-ui.drawer.content>
</x-ui.drawer>
Accessibility
The Drawer component includes proper ARIA attributes and keyboard support:
- Focus Management: Focus is trapped within the drawer when open
- Escape Key: Closes the drawer by default (can be disabled)
- Click Outside: Clicking the overlay closes the drawer
- Scroll Lock: Body scroll is locked when drawer is open
- Screen Reader: Proper ARIA roles and labels
- Teleport: Content is teleported to body for proper z-index layering
Styling
The drawer uses Tailwind CSS utility classes:
- Overlay:
bg-black/50with fade transitions - Content:
fixed inset-x-0 bottom-0for bottom sheet style - Handle:
h-2 w-[100px]drag indicator at top - Animation: Slide up from bottom with
translate-y
Notes
- The drawer animates from the bottom of the screen (bottom sheet style)
- Click outside the drawer or press Escape to close
- The handle at the top provides a visual indicator for swipe gestures
- Content is automatically teleported to the body element
- Multiple drawers can be used on the same page with unique IDs
- Body scroll is locked when the drawer is open
Next Steps
- Explore Modal component
- Learn about Dialog component
- View Popover component