Skip to content

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

PropTypeDefaultDescription
modelValuebooleanfalseOpen state; use v-model
fullscreenbooleanfalseEdge-to-edge surface (fills the viewport)
size'sm' | 'md' | 'lg'Preset max width via --gk-dialog-max-width-*; omit for md (28rem)
scrollablebooleanfalseScroll overflow inside the surface (max-height when not fullscreen)
persistentbooleanfalsePassed to GkOverlay — scrim and Escape do not close
tostring | HTMLElement'body'Teleport target (GkOverlay)
zIndexnumber | string--gk-dialog-z-indexStack order
showScrimbooleantruePassed to GkOverlay
restoreFocusbooleantruePassed to GkOverlay
widthstring | numberSurface width (numbers become px)
maxWidthstring | numberSurface max-width
heightstring | numberSurface height
maxHeightstring | numberSurface max-height

Additional attributes (for example aria-labelledby, aria-describedby) are forwarded to GkOverlay (panel element).

Slots

SlotDescription
defaultDialog body (inside the styled surface)

Events

EventPayloadDescription
update:modelValuebooleanOpen state
click:outsideMouseEventScrim clicked (GkOverlay); not emitted when persistent
afterEnterOverlay transition finished entering
afterLeaveOverlay transition finished leaving

Tokens

TokenPurpose
--gk-dialog-z-indexDefault stacking (2400)
--gk-dialog-max-widthMax width cap when size is omitted or md (28rem)
--gk-dialog-max-width-smCap when size="sm" (20rem)
--gk-dialog-max-width-lgCap when size="lg" (42rem)
--gk-dialog-scroll-max-heightCap for scrollable body height
--gk-dialog-shadowPanel shadow (non-fullscreen)

Try It

Change common dialog options, preview the result, and copy generated Vue code.

vue
<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-labelledby and point it to a visible heading inside the dialog.
  • Add aria-describedby when 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.

Out of scope (v1)

Activator slot, VDefaultsProvider, router integration, focus-trap package, and parity with Vuetify overlay location/scroll/lazy stacks.

Released under the MIT License.