vael-ui v0.3.10

Overlays

Drawer

A panel that slides in from a viewport edge, for navigation or side content.

Install

import { Drawer } from 'vael-ui'

Playground

import { Drawer } from 'vael-ui'

<Drawer side="right" size="md" closeOnEsc :forceMount="false" teleportTo="" scrollFade title="" description="" role="dialog" showClose modal :flush="false" closeOnOverlay :closeOnHistoryBack="false" :maximizable="false">Drawer</Drawer>

Props

NameTypeDefaultDescription
side"top" | "right" | "bottom" | "left""right"Which viewport edge the panel slides in from.
size"md" | "sm" | "lg""md"Panel width: sm 22rem / md 28rem / lg 38rem.
uiPartial<{ overlay: UiPartValue; panel: UiPartValue; header: UiPartValue; title: UiPartValue; description: UiPartValue; body: UiPartValue; footer: UiPartValue; maximize: UiPartValue; close: UiPartValue; }> | undefinedPer-instance part-class/style overrides.
closeOnEscboolean | undefinedtrueEscape key closes the panel.
beforeClose((done: () => void) => void) | undefinedCustom exit animation; call `done()` when it's complete. Delays the actual close/unmount until then.
forceMountboolean | undefinedfalseWhen true, presence is v-show-driven and owned by the consumer (e.g. AnimatePresence).
teleportTostring | undefinedTeleport target for the panel/overlay.
scrollFadeboolean | undefinedtrueMasks the panel's top/bottom edge as its content scrolls under it, signaling there's more.
titlestring | undefinedRenders the default header and wires aria-labelledby automatically.
descriptionstring | undefinedMuted line under the title; wires aria-describedby automatically.
role"dialog" | "alertdialog""dialog"`alertdialog` for urgent messages requiring a response (e.g. confirmations) — announced more assertively by screen readers.
containerDOMTarget | undefinedScopes the dialog to one element instead of the viewport: the overlay dims only that box, scroll lock and modality apply only inside it, and the rest of the page stays interactive. Also becomes the teleport target unless `teleportTo` is set. Given a positioning context automatically if it doesn't already have one.
scrollTargetDOMTarget | undefinedElement whose scrolling is locked while open. Defaults to `container`. Pass the inner scroller when the container itself doesn't scroll - an absolutely-positioned panel scrolls away with its container's content.
initialFocus(() => HTMLElement | null | undefined) | undefinedCustom initial focus; return null/undefined to use default (first focusable).
showCloseboolean | undefinedtrueHide the built-in × when the footer carries the only sensible actions.
modalboolean | undefinedtrue`false` disables overlay, scroll lock, and focus trap. Escape-close and layer stacking still apply.
flushboolean | undefined`true` removes edge padding; `top`/`bottom` panels sit flush to the viewport edge instead of floating.
closeOnOverlayboolean | undefinedtrueClicking the overlay closes the panel. No-op when `modal` is false (no overlay to click).
closeOnHistoryBackboolean | undefinedfalsePushes a history entry on open so the mobile hardware/gesture back action closes this panel instead of navigating the page away, popping that entry again on any other close path. Default false — opt in per instance.
maximizableboolean | undefinedAdds a maximize/restore toggle to the header, filling the viewport when active.
openboolean | undefinedfalseWhether the drawer is open.
maximizedboolean | undefinedfalseWhether the panel currently fills the viewport. Self-managed by Dialog's built-in toggle unless the consumer binds it.

Slots

NameTypeDescription
default{ close: () => void; open: boolean; isClosing: boolean; cancelClose: () => void; panelEl: HTMLElement | null; }
header{ close: () => void; }
footer{ close: () => void; }

Events

NameTypeDescription
open-change[value: boolean, details: DialogOpenChangeDetails]
update:open[value: boolean]
update:maximized[value: boolean]

Exposed

NameTypeDescription
panelElHTMLElement | null
isClosingboolean
close() => void | undefined
cancelClose() => void | undefined