Drawer
Side panel overlay that slides in from the edge of the screen. Used for navigation menus, filter panels, edit forms, and additional context that doesn't warrant a full modal.
Conceptually parallel to Modal — same BaseDialog underneath — but slides from the left or right of the viewport on desktop, and docks to the bottom with a drag-to-close grabber on mobile.
Drawer, DrawerContent, and DrawerFooter are exported from @scaler-tech/aurora/modal (same subpath as the Modal exports — they share the underlying BaseDialog).
Basic — right side
html
<Button @click="isOpen = true">Open drawer</Button>
<Drawer v-model:is-open="isOpen" title="Drawer title">
<DrawerContent>
<p>Body content goes inside <code>DrawerContent</code>.</p>
</DrawerContent>
<DrawerFooter>
<Button variant="secondary" @click="isOpen = false">Cancel</Button>
<Button @click="isOpen = false">Save</Button>
</DrawerFooter>
</Drawer>Left side
html
<Drawer v-model:is-open="isOpen" title="Filters" position="left">
<DrawerContent>…</DrawerContent>
<DrawerFooter>…</DrawerFooter>
</Drawer>With subtitle
html
<Drawer
v-model:is-open="isOpen"
title="Edit asset"
subtitle="Changes apply to all properties in this group."
>
<DrawerContent>…</DrawerContent>
<DrawerFooter>…</DrawerFooter>
</Drawer>beforeClose guard
Block dismissal when the user has unsaved changes. beforeClose returns false (or a Promise resolving to false) to prevent closing.
html
<Drawer
v-model:is-open="isOpen"
title="Edit"
:before-close="confirmDiscard"
>
…
</Drawer>ts
async function confirmDiscard() {
if (!hasUnsavedChanges.value) return true
return await confirm({ title: 'Discard changes?', message: 'Unsaved edits will be lost.' })
}Static (no overlay-click dismiss)
html
<Drawer v-model:is-open="isOpen" title="Confirm before closing" static>
…
</Drawer>Mobile behavior
Below the Tailwind md breakpoint (768px), Drawer switches to a bottom sheet:
- 75% of viewport height
- A drag handle (grabber) at the top
- Drag down to dismiss
This is automatic — same <Drawer> component, no extra props.
Drawer — Props
| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | false | Two-way bound open state. Use v-model:is-open. |
title | string | required | Header title. |
subtitle | string | — | Optional second line under the title. |
position | 'left' | 'right' | 'right' | Which side the drawer slides in from on desktop. (Mobile always docks bottom.) |
static | boolean | false | Disable dismiss on overlay click and Escape. |
beforeClose | () => boolean | Promise<boolean> | — | Async guard. Return false to prevent dismissal. |
Drawer — Slots
| Slot | Slot props | Description |
|---|---|---|
default | { close } | Drawer body — typically wraps <DrawerContent> and <DrawerFooter>. The close slot prop is a function you can call to dismiss. |
Drawer — Events
| Event | Description |
|---|---|
close | Fired when the drawer is dismissed (close button, overlay click, drag-down on mobile, or Escape). |
DrawerContent
Body container with scrollable overflow when content exceeds the available height. Slot-only.
DrawerFooter
Footer container — flex justify-between p-4. Place action buttons here.