GkDialog
A dialog shell built on GkOverlay: v-model, scrim, Escape / scrim dismiss (unless persistent), body scroll lock, role="dialog" / aria-modal, and forwarded attributes for aria-labelledby / aria-describedby.
Unlike Vuetify’s VDialog, there is no activator slot, VDefaultsProvider, router back, location/scroll strategies, or global overlay stack — compose with a button and v-model (see demo).
When to use
Use for focused modal workflows that require acknowledgement or completion before users continue (confirmations, form steps, destructive actions).
Live Examples
Standard dialog
Compose GkDialog with a button and v-model.
Best practice: Always provide aria-labelledby and keep an explicit close or completion action inside the dialog.
Scrollable dialog
Use scrollable when body content can exceed the available height.
Best practice: Keep primary actions reachable and avoid putting critical controls below long scrolling content.
Size presets (sm, md, lg)
Control default width with the size prop; override tokens in CSS if needed.
Best practice: Pick sm for confirmations, md for typical forms, lg for rich content or two-column layouts.
Fullscreen dialog
Use fullscreen for immersive or mobile-first flows.
Best practice: Fullscreen dialogs should still include a visible heading and close affordance.
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | false | Open state; use v-model |
fullscreen | boolean | false | Edge-to-edge surface (fills the viewport) |
size | 'sm' | 'md' | 'lg' | — | Preset max width via --gk-dialog-max-width-*; omit for md (28rem) |
scrollable | boolean | false | Scroll overflow inside the surface (max-height when not fullscreen) |
persistent | boolean | false | Passed to GkOverlay — scrim and Escape do not close |
to | string | HTMLElement | 'body' | Teleport target (GkOverlay) |
zIndex | number | string | --gk-dialog-z-index | Stack order |
showScrim | boolean | true | Passed to GkOverlay |
restoreFocus | boolean | true | Passed to GkOverlay |
width | string | number | — | Surface width (numbers become px) |
maxWidth | string | number | — | Surface max-width |
height | string | number | — | Surface height |
maxHeight | string | number | — | Surface max-height |
Additional attributes (for example aria-labelledby, aria-describedby) are forwarded to GkOverlay (panel element).
Slots
| Slot | Description |
|---|---|
default | Dialog body (inside the styled surface) |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | boolean | Open state |
click:outside | MouseEvent | Scrim clicked (GkOverlay); not emitted when persistent |
afterEnter | — | Overlay transition finished entering |
afterLeave | — | Overlay transition finished leaving |
Tokens
| Token | Purpose |
|---|---|
--gk-dialog-z-index | Default stacking (2400) |
--gk-dialog-max-width | Max width cap when size is omitted or md (28rem) |
--gk-dialog-max-width-sm | Cap when size="sm" (20rem) |
--gk-dialog-max-width-lg | Cap when size="lg" (42rem) |
--gk-dialog-scroll-max-height | Cap for scrollable body height |
--gk-dialog-shadow | Panel shadow (non-fullscreen) |
Try It
Change common dialog options, preview the result, and copy generated Vue code.
<script setup lang="ts">
import { ref } from 'vue'
import { GkButton, GkDialog } from 'god-kit/vue'
const open = ref(false)
</script>
<template>
<GkButton type="button" @click="open = true">Open dialog</GkButton>
<GkDialog
v-model="open"
aria-labelledby="dialog-title"
>
<h2 id="dialog-title">Dialog title</h2>
<p>Dialog content.</p>
<GkButton type="button" @click="open = false">Close</GkButton>
</GkDialog>
</template>Accessibility notes
- Always provide
aria-labelledbyand point it to a visible heading inside the dialog. - Add
aria-describedbywhen the dialog body includes guidance text users must hear before acting. - Keep at least one keyboard-focusable control inside the dialog body or actions region.
Related components
Out of scope (v1)
Activator slot, VDefaultsProvider, router integration, focus-trap package, and parity with Vuetify overlay location/scroll/lazy stacks.
