Skip to content

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

PropTypeDefaultDescription
isOpenbooleanfalseTwo-way bound open state. Use v-model:is-open.
titlestringrequiredHeader title.
subtitlestringOptional second line under the title.
position'left' | 'right''right'Which side the drawer slides in from on desktop. (Mobile always docks bottom.)
staticbooleanfalseDisable dismiss on overlay click and Escape.
beforeClose() => boolean | Promise<boolean>Async guard. Return false to prevent dismissal.

Drawer — Slots

SlotSlot propsDescription
default{ close }Drawer body — typically wraps <DrawerContent> and <DrawerFooter>. The close slot prop is a function you can call to dismiss.

Drawer — Events

EventDescription
closeFired 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.