Lumeo

Drawer

A panel that slides up from the bottom of the screen on mobile devices.

Installation

dotnet add package Lumeo

One-time app setup (AddLumeo(), CSS & JS) is covered in the installation guide.

Usage

@using Lumeo

<Drawer />

When to Use

  • Present mobile-first overlays that slide up from the bottom of the screen
  • Build bottom sheets for action selection, filters, or confirmations
  • Show supplementary content without navigating away from the current page
  • Provide a gesture-friendly overlay that supports swipe-to-dismiss
  • Display quick-action menus on touch devices

Bottom drawer with snap points at 40% / 75% / 100%. On a touch device (or DevTools device emulation), drag the handle to move between snaps; a quick flick down dismisses. On desktop it opens at the active snap so you can still see the resting position. Active snap: 75% (index 1).

Pick a value to see it applied live.

Sizes

Click any trigger below to open the drawer at that size — DrawerContent.DrawerSize covers every value. On the default Bottom side, size controls the panel's max height; on Left/Right it controls max width instead (the panel's own 3/4-viewport base width is unaffected — mirrors SheetContent.SheetSize.Full's own Left/Right precedent). Full on Top/Bottom takes the entire viewport, the mobile-fullscreen bottom-sheet pattern.

DrawerContent.DrawerSize

Sm
Default
Lg
Xl
Full

Intercepting close

OnBeforeClose fires for every close path including swipe-down on touch devices. The handler receives a DismissEventArgs with a Reason string — "escape", "outside", "swipe", "close", "action", or "cancel". Set e.Cancel = true to keep the drawer open.

Nested stacking. Drawers stack automatically on top of Dialogs, Sheets, AlertDialogs, or other Drawers — z-index is allocated per overlay, and Escape closes only the top-most one. No API change.

Keyboard Interactions

Key Action
EscapeClose the drawer (unless PreventClose is enabled)
TabCycle focus through focusable elements within the drawer
Shift + TabMove focus to the previous focusable element within the drawer

On touch devices, swiping down on the drawer handle also dismisses it.

Exit animation

Closing a drawer plays a slide-and-fade-out animation and keeps the panel mounted until it finishes, so the dismissal reads as deliberate rather than an abrupt pop. This is on by default. Set PlayExitAnimation="false" on DrawerContent to opt out and unmount immediately — useful inside another animating container or for reduced-motion contexts.

vaul separates two independent questions: modal — does the drawer block the page (backdrop, focus trap, scroll lock)? — and dismissible — can the user close it at all (swipe, backdrop click, Escape)? Lumeo maps these onto two DrawerContent parameters that compose freely:

vaul Lumeo Default Effect when set to the non-default value
modal Modal true Modal="false": no backdrop, no focus trap, no scroll lock — the page stays fully interactive while the drawer is open.
dismissible PreventClose (inverted) false PreventClose="true": Escape, backdrop-click and swipe are all disabled; the drawer only closes programmatically (or, in snap mode, settles at the lowest snap).

The two compose freely — e.g. Modal="false" with PreventClose="true" is a drawer that never blocks the page AND can only be dismissed programmatically.

Built-in close button

ShowCloseButton renders a top-end X, mirroring SheetContent.ShowCloseButton exactly — same parameter name, same default coupling to PreventClose (null), and the same override semantics: true forces the X on even when PreventClose is set (it still routes through the dismiss guard), false hides it for custom chrome. No more manual DrawerClose required just to get an X.

Background scaling

Drawer.ScaleBackground (default false) mirrors vaul's shouldScaleBackground — while a Bottom drawer is open, the page behind it scales down, gains rounded corners, and nudges down slightly, mimicking the native iOS "page recedes behind the sheet" effect. Top/Left/Right drawers never trigger it, matching vaul's own bottom-sheet-only scope.

<!-- MainLayout.razor (or index.html's app root) -->
<div data-lumeo-drawer-wrapper>
    <Router ...>
        ...
    </Router>
</div>

<!-- Anywhere a bottom Drawer is opened: -->
<Drawer @bind-Open="_open" ScaleBackground="true">
    <DrawerContent>
        ...
    </DrawerContent>
</Drawer>

API Reference

Drawer

DrawerContent

The panel that slides up from the bottom of the screen. Includes focus trap, scroll lock, and swipe-to-dismiss gesture. Sub-components DrawerTrigger, DrawerClose, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription mirror the Dialog/Sheet API.

DrawerTrigger

  • Sheet — Use for side-panel overlays on desktop; Drawer is optimized for bottom-sheet mobile interactions
  • Dialog — Use for centered modal overlays that require explicit user decisions
  • Popover — Use for small contextual overlays anchored to a trigger element