Dialog Message for Quasar

🇪🇸 Versión en español | 🇧🇷 Versão em português

npm version license Vue Quasar TypeScript Node

Quasar extension for modal message dialogs (alerts and confirmation) in Vue 3 + Quasar apps, with an imperative composable-based API.

Table of contents

In 30 seconds

Recommended flow:

  1. Install the extension in your Quasar app (quasar ext add).
  2. Ensure the host Pinia boot runs before this extension’s boot.
  3. Import useDialogMessage() where you show feedback to the user.
  4. Call await message.success() (i18n preset) or await message.success({ text: '...' }); for confirm: const ok = await message.confirm({ text: '...' }).

The extension registers boots and CSS in the host project automatically after quasar ext add.

What it is and what it includes

Global modal dialog controlled by useDialogMessage() — not an embeddable component.

Requirements and compatibility

Item Value
Node >= 20.0.0
Quasar ^2.6.0
Vue ^3.4.18
Pinia ^2.0.11 | ^3.0.0
Package format ES modules
Recommended CLI @quasar/app-vite ^2.x or ^3.x

The host Pinia boot must run before this extension’s boot.

Install in a Quasar app

quasar ext add @benjaminor-dev/dialog-message

Remove:

quasar ext remove @benjaminor-dev/dialog-message

After quasar ext add, the extension registers boots and CSS in your app automatically. No extra steps are needed for a normal npm install.

What the extension adds to the host

Resources installed or registered by the extension:

Resource npm path
Dialog boot ~@benjaminor-dev/quasar-app-extension-dialog-message/boot/dialog
Styles ~@benjaminor-dev/quasar-app-extension-dialog-message/main.css
Boot defaults (host) src/boot/bor/bor-dialog-message-defaults.ts — created on install; Skip/Overwrite if it already exists

Install (quasar ext add / invoke): creates src/boot/bor/bor-dialog-message-defaults.ts (or .js) and registers it in quasar.configboot: [] automatically. No manual editing needed in a normal install. Package boot (boot/dialog) and main.css are injected on every dev/build (they do not appear as short entries in quasar.config).

Remove (quasar ext remove): removes the defaults boot and its quasar.config entry.

Minimum boot order:

1. Pinia (host)
2. Dialog Message — boot/dialog
3. bor/bor-dialog-message-defaults (host)

In quasar.config you only see bor/bor-dialog-message-defaults; the package boot/dialog is added by the extension runner at compile time.

The boot mounts the dialog in the document and connects the host Pinia store. You do not need to import DialogMessage in App.vue.

Global defaults (boot)

Avoid repeating titles, icons, labels, and measurements on every call. Priority: per-call options → host boot → i18n (locale / $q.lang / en).

After quasar ext add, review src/boot/bor/bor-dialog-message-defaults.ts — template with language instructions in the file comment.

// src/boot/bor/bor-dialog-message-defaults.ts
import { configureDialogMessageDefaults } from "@benjaminor-dev/quasar-app-extension-dialog-message";

configureDialogMessageDefaults({
  // locale: "es", // uncomment to pin a specific language for Dialog Message
  width: "420px",
  persistent: true,
  zIndex: 7000,
  gap: "1rem",
  actionsGap: "2rem",
  font: {
    family: "Arial, sans-serif",
    sizeTitle: "1.4rem",
    sizeText: "1.2rem",
  },
  buttonStyle: {
    light: {
      acceptColor: "primary",
      acceptVariant: "unelevated",
      cancelColor: "primary",
      cancelVariant: "outline",
    },
    dark: {
      acceptColor: "primary",
      acceptVariant: "unelevated",
      cancelColor: "white",
      cancelVariant: "outline",
    },
  },
});

Language (i18n)

Built-in en, es, and pt for preset titles, texts, and labels (success, info, warn, error, confirm). By default follows $q.lang; without a Quasar language, falls back to en.

Locale resolution: boot locale$q.lang.isoName prefix (es*es, pt*pt) → en.

Text resolution: per-call options → boot presets.<variant> → boot messages → built-in catalog → en. Icons and default colors come from built-in visuals; override visuals in boot presets.

Option When to use it
framework.lang in quasar.config.ts Recommended — aligns Dialog Message with Quasar
locale: 'es' in boot Pin a specific language (en | es | pt); ignores $q.lang changes
messages / presets in boot Partial override (one preset or one label)

Spanish across the whole app:

// quasar.config.ts
framework: {
  lang: "es",
},

Override a single preset (visual + text):

configureDialogMessageDefaults({
  presets: {
    confirm: { title: "Delete record?", acceptLabel: "Delete" },
  },
});

Override i18n strings without changing icons:

configureDialogMessageDefaults({
  messages: {
    acceptLabel: "Got it",
    presets: { warn: { title: "Heads up", text: "Check your input" } },
  },
});

configureDialogMessage is an alias of configureDialogMessageDefaults.

Boot option Built-in default Description
locale (follows $q.lang) Fixes en | es | pt for preset texts
messages (per locale) Partial i18n override (presets.success.title, …)
acceptLabel "OK" (i18n) Global fallback for the Accept button
cancelLabel "No" (i18n) Global fallback for the Cancel button in confirm
width "420px" Maximum card width
persistent true Blocks close via backdrop / Esc
zIndex 7000 Dialog layer relative to the rest of the UI
gap "1rem" Spacing icon ↔ title ↔ text
actionsGap "2rem" Spacing text block ↔ buttons
font.sizeTitle "1.4rem" CSS font-size for the title
font.sizeText "1.2rem" CSS font-size for the body
font.family "Arial, sans-serif" CSS font-family for title and text
buttonStyle See boot template Button colors and variants per theme (light / dark)
presets.<variant> (i18n + icons) Override title, text, icon, iconColor, labels

Each preset includes title, text, and labels per language. Boot presets can override both text and visuals (icon, iconColor, button styles); boot messages overrides text only.

Preset variants: success, info, warn, error, confirm.

Per-field priority: callpreset (boot)i18nglobal (boot). Within buttons, buttonStyle.<theme> wins over flat acceptColor / cancelColor at the same level.

Quick start

<script setup lang="ts">
import { useDialogMessage } from "@benjaminor-dev/quasar-app-extension-dialog-message";

const message = useDialogMessage();

async function onSave() {
  try {
    await api.save(formData);
    await message.success(); // i18n preset (title + text)
    // await message.success({ text: "Record saved" });
  } catch (error) {
    await message.error({ text: "Could not save" });
  }
}

async function onDelete(item: { id: string }) {
  const confirmed = await message.confirm({
    title: "Delete record",
    text: "The selected record will be deleted. Do you want to continue?",
  });
  if (!confirmed) return;

  await api.delete(item.id);
  await message.success({ text: "Record deleted" });
}
</script>

<template>
  <q-btn label="Save" @click="onSave" />
  <q-btn label="Delete" color="negative" @click="onDelete({ id: '1' })" />
</template>

Alert with a one-off title and icon override:

await message.info({
  title: "Important notice",
  text: "Review the data before continuing",
  icon: "campaign",
  iconColor: "warning",
});

Confirm with button override only in dark mode:

const ok = await message.confirm({
  text: "Do you want to continue?",
  buttonStyle: {
    dark: { cancelColor: "grey-4" },
  },
});
if (!ok) return;

Side-effect on accept (e.g. logout):

await message.warn({
  text: "Your session will expire in 5 minutes",
  onAccept: async () => {
    await auth.refreshSession();
  },
});

TypeScript in your IDE

Do not memorize the API — let autocomplete guide you.

If something does not appear in autocomplete, it is usually a non-existent prop or a wrong import — check the main entrypoint before searching the README.

Public API

Entry point: useDialogMessage().

import { useDialogMessage } from "@benjaminor-dev/quasar-app-extension-dialog-message";

const message = useDialogMessage();

Methods

Method Return Description
success(options?) Promise<void> Success alert (success preset; optional options)
info(options?) Promise<void> Informational alert
warn(options?) Promise<void> Warning alert
error(options?) Promise<void> Error alert
confirm(options?) Promise<boolean> Confirmation with two buttons; true = confirm
hide() void Closes without onAccept; on confirm resolves false

Reactive state (read-only)

Ref Description
visible Whether the dialog is visible

Per-call options (DialogMessageOptions)

Field Description
title? Title; omit → boot preset; "" hides the title
text? Message body
icon? Material Icons icon (Quasar)
iconColor? Icon color: string or { light?, dark? }
acceptLabel? Primary button label
acceptColor? Quasar color for the primary button (flat; both themes)
acceptVariant? Quasar variant: flat | outline | unelevated | push
buttonStyle? Partial override { light?, dark? } of button colors/variants
onAccept? Callback when Accept / Confirm is pressed

DialogMessageConfirmOptions extends the above with:

Field Description
cancelLabel? Cancel button label
cancelColor? Quasar color for the Cancel button (flat)
cancelVariant? Quasar variant for the Cancel button
onCancel? Callback when Cancel is pressed

Visual presets

Configure each preset in boot presets (or use the built-ins). Texts follow i18n; icons and default colors are locale-independent unless you override them in boot.

Preset Typical use Default icon Default color
success Operation completed check_circle positive
info Neutral notice info primary
warn Attention / caution warning warning
error Failure or error error negative
confirm Yes/no question before acting back_hand primary

Exported constant: DIALOG_MESSAGE_VARIANTS — list of valid variants.

Icon and buttons by theme

The dialog resolves colors based on $q.dark.isActive (light / dark).

Icon — iconColor

In boot (per preset) or per call:

iconColor: { light: "negative", dark: "red-4" }
// or flat (same color in both themes):
iconColor: "positive"

Buttons — buttonStyle

Global in boot (applies to all presets) or partial per preset / call:

buttonStyle: {
  light: {
    acceptColor: "primary",
    acceptVariant: "unelevated",
    cancelColor: "primary",
    cancelVariant: "outline",
  },
  dark: {
    acceptColor: "primary",
    acceptVariant: "unelevated",
    cancelColor: "white",
    cancelVariant: "outline",
  },
}

Per-theme fields in buttonStyle: acceptColor, acceptVariant, cancelColor, cancelVariant.

Built-in variants: Accept → unelevated, Cancel → outline.

Alerts vs confirmation

Aspect Alerts (successerror) Confirm (confirm)
Buttons One (Accept) Two (Cancel + Confirm)
Promise void on accept boolean (true / false)
UX order (LTR) Cancel left, Confirm right
hide() Closes without callback Resolves false
Default labels presets.<variant>.acceptLabel (e.g. "OK") presets.confirm.acceptLabel / cancelLabel

Only one dialog can be visible at a time. A new call closes the previous session (pending confirm resolves false).

Exported TypeScript types

From the main entrypoint:

import {
  useDialogMessage,
  resolveDialogMessageMessages,
  resolveExtensionLocale,
  type DialogMessageApi,
  type DialogMessageOptions,
  type DialogMessageConfirmOptions,
  type DialogMessageDefaults,
  type DialogMessagePresetConfig,
  type DialogMessagePresetsDefaults,
  type DialogMessageFontDefaults,
  type DialogMessageI18nMessages,
  type PartialDialogMessageI18nMessages,
  type DialogMessageButtonStyleConfig,
  type DialogMessageButtonThemeStyle,
  type DialogMessageButtonVariant,
  type DialogMessageThemeColor,
  type DialogMessageThemeColorValue,
  type DialogMessageThemeMode,
  type DialogMessageVariant,
  type ExtensionLocale,
  type ResolvedDialogMessageDefaults,
  configureDialogMessageDefaults,
  BUILTIN_DIALOG_MESSAGE_DEFAULTS,
  DIALOG_MESSAGE_VARIANTS,
} from "@benjaminor-dev/quasar-app-extension-dialog-message";
Type Use
DialogMessageApi Return type of useDialogMessage()
ExtensionLocale "en" | "es" | "pt" — boot locale
DialogMessageI18nMessages Shape of boot messages (labels + nested presets)
PartialDialogMessageI18nMessages Partial boot messages override
DialogMessageOptions Argument of success, info, warn, error
DialogMessageConfirmOptions Argument of confirm()
DialogMessageDefaults Options for configureDialogMessageDefaults
DialogMessagePresetConfig Fields of each entry in presets
DialogMessagePresetsDefaults Partial presets map
DialogMessageFontDefaults { family?, sizeTitle?, sizeText? }
DialogMessageButtonStyleConfig { light?, dark? } with button styles
DialogMessageButtonThemeStyle Button colors/variants in one theme
DialogMessageButtonVariant "flat" | "outline" | "unelevated" | "push"
DialogMessageThemeColor { light?, dark? } for per-theme colors
DialogMessageThemeColorValue string or DialogMessageThemeColor (iconColor)
DialogMessageThemeMode "light" | "dark"
DialogMessageVariant "success" | "info" | "warn" | "error" | "confirm"
ResolvedDialogMessageDefaults Merged defaults (reference / advanced)

Also exported: configureDialogMessage (alias), resolveDialogMessageMessages, resolveExtensionLocale, BUILTIN_DIALOG_MESSAGE_DEFAULTS, and DIALOG_MESSAGE_API_KEY (boot provide key for advanced integrations).

Public entrypoints

What you import in your code:

Entrypoint Purpose
@benjaminor-dev/quasar-app-extension-dialog-message useDialogMessage, configureDialogMessageDefaults, i18n helpers (resolveDialogMessageMessages, resolveExtensionLocale), types, and DIALOG_MESSAGE_VARIANTS

Boot (boot/dialog) and styles (main.css) are registered by the extension in quasar.config on install — no manual import needed for a normal install.

Troubleshooting

I see titles or buttons in English and want Spanish (or Portuguese)

Without configuring Quasar, built-in presets are in English. Pick one option:

// quasar.config.ts — recommended
framework: {
  lang: "es",
},
// src/boot/bor/bor-dialog-message-defaults.ts — pin Dialog Message locale only
configureDialogMessageDefaults({ locale: "es" });

Boots or styles do not appear in quasar.config

Under normal conditions, install registers the defaults boot in boot: [] and the runner injects boot/dialog + CSS at compile time. If the defaults boot is missing:

npx quasar ext invoke @benjaminor-dev/dialog-message

Error: Pinia not initialized

useDialogMessage() outside setup

Call it inside setup, another composable, or <script setup>. The boot must have run (app mounted).

The dialog does not show a title

confirm() always resolves false

The dialog stays behind another overlay

Adjust zIndex in boot (default 7000) according to your app’s layer hierarchy.

I changed presets in boot and nothing updates

Restart the dev server. Confirm you are editing src/boot/bor/bor-dialog-message-defaults.ts in the host, not only the extension template.


MIT © Benjamín Olvera R.