ShellUI Logo
ShellUI

Drawer

Mobile-friendly slide-out drawer component

The Drawer component is a mobile-optimized slide-out panel with touch gesture support. It provides a familiar interaction pattern for mobile interfaces while still working well on desktop.

Installation

shellui add drawer

Basic Usage

<Button OnClick="() => isOpen = true">Open Drawer</Button>

<Drawer IsOpen="@isOpen" IsOpenChanged="@((v) => isOpen = v)" Title="Drawer Title" Description="Swipe down to close.">
  <p>Drawer content goes here.</p>
</Drawer>

@code {
    private bool isOpen = false;
}

Side Variants

Control which edge the drawer appears from:

Bottom (Default)

<Drawer IsOpen="@isOpen" IsOpenChanged="@((v) => isOpen = v)" Side="DrawerSide.Bottom" Title="Options">
  <div class="space-y-2">
    <Button Variant="ButtonVariant.Outline" Class="w-full">Share</Button>
    <Button Variant="ButtonVariant.Outline" Class="w-full">Export</Button>
    <Button Variant="ButtonVariant.Destructive" Class="w-full">Delete</Button>
  </div>
</Drawer>

Top

<Drawer IsOpen="@isOpen" IsOpenChanged="@((v) => isOpen = v)" Side="DrawerSide.Top" Title="Search">
  <Input Placeholder="Search..." />
</Drawer>

Left / Right

<Drawer IsOpen="@isOpen" IsOpenChanged="@((v) => isOpen = v)" Side="DrawerSide.Left" Title="Menu">
  <nav class="space-y-2">
    <a href="/" class="block py-2">Home</a>
    <a href="/about" class="block py-2">About</a>
    <a href="/contact" class="block py-2">Contact</a>
  </nav>
</Drawer>

Mobile Action Sheet

A common mobile pattern for presenting actions:

<Button OnClick="() => isOpen = true">Actions</Button>

<Drawer IsOpen="@isOpen" IsOpenChanged="@((v) => isOpen = v)" Title="Actions" Description="Choose an action below.">
  <div class="grid gap-2 py-4">
    <Button Variant="ButtonVariant.Ghost" Class="justify-start" OnClick="HandleEdit">Edit Item</Button>
    <Button Variant="ButtonVariant.Ghost" Class="justify-start" OnClick="HandleDuplicate">Duplicate</Button>
    <Separator />
    <Button Variant="ButtonVariant.Ghost" Class="justify-start text-destructive" OnClick="HandleDelete">Delete</Button>
  </div>
</Drawer>

@code {
    private bool isOpen = false;
    private void HandleEdit() => isOpen = false;
    private void HandleDuplicate() => isOpen = false;
    private void HandleDelete() => isOpen = false;
}

API Reference

PropertyTypeDefaultDescription
IsOpenboolfalseControls the drawer open state
IsOpenChangedEventCallback<bool>Callback when open state changes
Titlestring?nullDrawer header title
Descriptionstring?nullDrawer header description
SideDrawerSideDrawerSide.BottomWhich edge the drawer appears from
ChildContentRenderFragmentnullDrawer body content
Classstring?nullAdditional CSS classes

DrawerSide Enum

  • DrawerSide.Top
  • DrawerSide.Bottom
  • DrawerSide.Left
  • DrawerSide.Right

Accessibility

The Drawer component includes:

  • Touch gesture support (swipe to dismiss)
  • Focus trap when open
  • Escape key to close
  • Proper role="dialog" and ARIA attributes
  • Screen reader announcements
  • Reduced motion support via prefers-reduced-motion

On this page