Overlays
Dialog
A focused, modal task on top of the page. It traps focus, locks scroll, closes on Escape and gives focus back when it’s done.
Installation #
With the Nuxt module, every component is auto-imported — there is nothing to add. In a plain Vue project, import what you use:
Copy
import { JDialog } from '@juxtui/ui'Usage #
Copy
<JButton @click="open = true">Edit profile</JButton>
<JDialog v-model:open="open" title="Edit profile" description="Changes are visible to your team.">
<JInput v-model="name" label="Name" />
<template #footer="{ close }">
<JButton variant="ghost" @click="close">Cancel</JButton>
<JButton @click="save">Save</JButton>
</template>
</JDialog>On screens narrower than 640px the dialog becomes a sheet anchored to the bottom edge, within reach of a thumb. Footer actions stack full-width.
Variants & examples #
Destructive confirmation#
For irreversible actions, say exactly what will happen and name the consequence on the button.
Required decision#
With close-on-overlay and close-on-escape off, dismissal attempts get a small nudge instead.
API #
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Bound with v-model:open. |
| title | string | — | Heading. Labels the dialog. |
| description | string | — | Supporting text. Describes the dialog. |
| size | 'sm' | 'md' | 'lg' | 'md' | Maximum width: 400, 480 or 640px. |
| closeOnOverlay | boolean | true | Close when the backdrop is clicked. |
| closeOnEscape | boolean | true | Close when Escape is pressed. |
| hideClose | boolean | false | Hide the close button in the corner. |
| ariaLabel | string | — | Accessible name when there is no visible title. |
Events
| Event | Payload | Description |
|---|---|---|
| update:open | boolean | Emitted when the dialog asks to close. |
| afterClose | — | After the leave transition — a good moment to reset form state. |
Slots
| Slot | Props | Description |
|---|---|---|
| default | { close } | Body content. |
| footer | { close } | Actions, right-aligned. |
| header | { titleId, descriptionId } | Replace the header. Put titleId on your heading to keep the dialog labelled. |
Accessibility #
role="dialog"witharia-modal, labelled by the title and described by the description.- On open, focus moves to an element marked
autofocus, else the first form field, else the dialog itself — never to a random button. - On close, focus returns to whatever opened the dialog.
- Dialogs stack: Escape and outside clicks only affect the top-most layer, so a select open inside a dialog closes first.
- A click only dismisses when it both starts and ends on the backdrop — dragging a text selection out of the dialog never closes it.
Keyboard #
| Key | Action |
|---|---|
| Tab | Moves focus to the next element inside the dialog, wrapping at the end. |
| ShiftTab | Moves focus backwards, wrapping at the start. |
| Esc | Closes the dialog (unless `close-on-escape` is off). |