Dialog

Modal messages that interrupt the user: alerts, confirmation, and a blocking loader. Button texts default to core.locale and can be overridden per call or in core.messages.

Source in the kit: composables/useDialog.ts · components/Dialog/

Alerts

examples/feedback/DialogTypes.vue

Options: title , description , confirmText , icon , isHideIcon .

<template>
  <div class="flex flex-wrap gap-2">
    <Button
      label="success"
      color="success"
      @click="
        dialog.success({
          title: 'Saved',
          description: 'Your changes are live.',
        })
      "
    />
    <Button
      label="error"
      color="error"
      @click="
        dialog.error({
          title: 'Could not save',
          description: 'The server did not answer.',
        })
      "
    />
    <Button
      label="warning"
      color="warning"
      @click="dialog.warning({ title: 'Storage almost full' })"
    />
    <Button
      label="info"
      color="info"
      @click="
        dialog.info({
          title: 'New version available',
          confirmText: 'Got it',
        })
      "
    />
  </div>
</template>

<script lang="ts" setup>
// Each call returns a promise that resolves when the user closes the dialog, so it can be awaited:
//   await dialog.success({ title: 'Saved' }); navigateTo('/users')
const dialog = useDialog()
</script>

Confirm

examples/feedback/DialogConfirm.vue

Read the comment about rejection on cancel : it is the most common mistake with this API.

<template>
  <div class="flex flex-wrap gap-2">
    <Button
      label="Delete with then / catch"
      color="error"
      variant="soft"
      @click="removeWithThen"
    />
    <Button
      label="Delete with async / await"
      color="error"
      variant="soft"
      @click="removeWithAwait"
    />
  </div>
</template>

<script lang="ts" setup>
const dialog = useDialog()
const answer = ref('-')

const ask = () =>
  dialog.confirm({
    title: 'Delete this user?',
    description: 'This cannot be undone.',
    type: DialogType.ERROR,
    confirmText: 'Delete',
    cancelText: 'Keep',
  })

// IMPORTANT: confirm() resolves on confirm and REJECTS on cancel.
// Without a catch, cancelling shows up as an unhandled promise rejection.
const removeWithThen = () => {
  ask()
    .then(() => {
      answer.value = 'confirmed'
    })
    .catch(() => {
      answer.value = 'cancelled'
    })
}

const removeWithAwait = async () => {
  try {
    await ask()
    answer.value = 'confirmed'
  } catch {
    answer.value = 'cancelled'
  }
}

defineExpose({
  debug: computed(() => ({
    answer: answer.value,
  })),
})
</script>

Blocking loader

examples/feedback/DialogLoading.vue
<template>
  <Button
    label="Export report (2s)"
    @click="exportReport"
  />
</template>

<script lang="ts" setup>
const dialog = useDialog()
const notification = useNotification()

// loading() blocks the page with a spinner until close(): use it for actions the user must wait for
const exportReport = async () => {
  dialog.loading({
    title: 'Building your report…',
  })

  try {
    await new Promise((resolve) => setTimeout(resolve, 2000))

    notification.success({
      title: 'Report ready',
    })
  } finally {
    // Always close in finally, or an error leaves the page blocked
    dialog.close()
  }
}
</script>