Toggle Sidebar B
header.lightDarkMode D

Dialog Responsive

Dialog on desktop, Drawer (vaul-vue) on mobile. Use this for almost every modal in the app. Reach for plain Dialog only for short confirmations that still look fine on a phone.

When to use DialogResponsive vs Dialog

Default to DialogResponsive for any modal that has a form or scrollable content. Plain Dialog is fine for short confirmations (delete, log out) and small popovers that read well on mobile without becoming a drawer.

Anatomy

Import all parts and piece them together.

vue
<script setup>
import {
  DialogResponsive,
} from "@/components/ui/dialog-responsive";
</script>

<template>
  <DialogResponsive>
    <template #trigger />
    <template #sticky-header />
    <template #default />
    <template #sticky-footer />
  </DialogResponsive>
</template>

Default

Use the trigger slot for the opener, the default slot for the content. Open state is controlled with v-model:open.

With form

Form pattern inside DialogResponsive: padding handled with a wrapper div, action buttons at the end.

Prevent close

preventClose blocks overlay clicks and Escape. The close-prevented event lets you show a confirmation prompt.

API Reference

Props, events, and slots for each sub-component.

DialogResponsive

Props

PropTypeDefaultDescription
openbooleanOpen state. Supports v-model:open.
isResponsivebooleantrueSet false to force the Drawer variant at every breakpoint.
dialogMaxWidthstring"400px"Max width of the desktop dialog.
dialogMaxHeightstring"calc(100% - 4rem)"Max height of the desktop dialog.
preventClosebooleanfalseBlock overlay click and Escape. Emits close-prevented.
drawerCloseButtonbooleanfalseShow a close button on the mobile drawer (default is swipe only).
hideOverlaybooleanfalseHide the dark backdrop.
flushContentbooleanfalseRender the content without the ScrollArea wrapper.
overflowContentbooleantrueEnable overflow-y-auto on the mobile drawer body.

Events

EventDescription
update:openFires when the open state changes.
close-preventedFires when the user tries to close with preventClose enabled.

Slots

SlotDescription
triggerThe opener button. Receives open from the scope.
defaultMain content. Receives data from the scope.
sticky-headerHeader that sticks to the top while scrolling.
sticky-footerFooter that sticks to the bottom while scrolling.

Accessibility

Keyboard shortcuts and ARIA behavior.

Keyboard

ShortcutDescription
SpaceWhen focus is on the trigger, opens the dialog.
EnterWhen focus is on the trigger, opens the dialog.
TabMoves focus to the next focusable element inside the content.
Shift+TabMoves focus to the previous focusable element.
EscCloses the overlay and returns focus to the trigger.
  • Adapts to a Dialog on desktop and a Drawer on mobile, keeping the same accessibility contract.
  • Focus is trapped within the content while open and restored to the trigger on close.
  • Provide a title so screen readers can announce the dialog via aria-labelledby.