Dialog Message para Quasar

🇺🇸 English | 🇪🇸 Versión en español

npm version license Vue Quasar TypeScript Node

Extensão Quasar para diálogos modais de mensagem (alertas e confirmação) em apps Vue 3 + Quasar, com API imperativa baseada em composable.

Índice

Em 30 segundos

Fluxo base recomendado:

  1. Instalar a extensão na sua app Quasar (quasar ext add).
  2. Garantir que o boot de Pinia do host executa antes do boot desta extensão.
  3. Importar useDialogMessage() onde mostrar feedback ao utilizador.
  4. Chamar await message.success() (preset i18n) ou await message.success({ text: '...' }); para confirm: const ok = await message.confirm({ text: '...' }).

A extensão regista boots e CSS no projeto host automaticamente após quasar ext add.

O que é e o que inclui

Diálogo modal global controlado por useDialogMessage() — não é um componente embutível.

Requisitos e compatibilidade

Item Valor
Node >= 20.0.0
Quasar ^2.6.0
Vue ^3.4.18
Pinia ^2.0.11 | ^3.0.0
Formato do pacote ES modules
CLI recomendado @quasar/app-vite ^2.x ou ^3.x

O boot de Pinia do host deve executar antes do boot desta extensão.

Instalação na app Quasar

quasar ext add @benjaminor-dev/dialog-message

Remover:

quasar ext remove @benjaminor-dev/dialog-message

Após quasar ext add, a extensão regista boots e CSS na sua app automaticamente. Não precisa de passos adicionais numa instalação normal a partir do npm.

O que a extensão adiciona ao host

Recursos instalados ou registados pela extensão:

Recurso Caminho npm
Boot do diálogo ~@benjaminor-dev/quasar-app-extension-dialog-message/boot/dialog
Estilos ~@benjaminor-dev/quasar-app-extension-dialog-message/main.css
Defaults boot (host) src/boot/bor/bor-dialog-message-defaults.ts — criado na instalação; Skip/Overwrite se já existir

Install (quasar ext add / invoke): cria src/boot/bor/bor-dialog-message-defaults.ts (ou .js) e regista-o em quasar.configboot: [] automaticamente. Não precisa de editar manualmente numa instalação normal. O boot de pacote (boot/dialog) e main.css são injetados em cada dev/build (não aparecem como entradas curtas em quasar.config).

Remove (quasar ext remove): remove o defaults boot e a respetiva entrada em quasar.config.

Ordem mínima de boots:

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

Em quasar.config só verá bor/bor-dialog-message-defaults; o boot boot/dialog é adicionado pelo runner ao compilar.

O boot monta o diálogo no documento e liga a store Pinia do host. Não precisa de importar DialogMessage em App.vue.

Defaults globais (boot)

Evite repetir títulos, ícones, labels e medidas em cada chamada. Prioridade: opções por chamada → boot do host → i18n (locale / $q.lang / en).

Após quasar ext add, reveja src/boot/bor/bor-dialog-message-defaults.ts — modelo com instruções de idioma no comentário do ficheiro.

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

configureDialogMessageDefaults({
  // locale: "es", // descomente para fixar um idioma específico no 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",
    },
  },
});

Idioma (i18n)

Built-in en, es e pt para títulos, textos e labels de presets (success, info, warn, error, confirm). Por defeito segue $q.lang; sem idioma Quasar, cai em en.

Resolução de locale: boot locale → prefixo de $q.lang.isoName (es*es, pt*pt) → en.

Resolução de textos: opções por chamada → boot presets.<variant> → boot messages → catálogo built-in → en. Ícones e cores default vêm de visuais built-in; override visual no boot presets.

Opção Quando usar
framework.lang em quasar.config.ts Recomendado — alinha Dialog Message com Quasar
locale: 'es' no boot Fixar um idioma específico (en | es | pt); ignora mudanças de $q.lang
messages / presets no boot Override parcial (um preset ou um label)

Exemplo espanhol em toda a app:

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

Override de um preset (visual + texto):

configureDialogMessageDefaults({
  presets: {
    confirm: { title: "Eliminar registo?", acceptLabel: "Eliminar" },
  },
});

Override i18n sem alterar ícones:

configureDialogMessageDefaults({
  messages: {
    acceptLabel: "Entendido",
    presets: { warn: { title: "Atenção", text: "Revise os dados" } },
  },
});

configureDialogMessage é alias de configureDialogMessageDefaults.

Opção boot Default built-in Descrição
locale (segue $q.lang) Fixa en | es | pt para textos de presets
messages (por locale) Override parcial i18n (presets.success.title, …)
acceptLabel "OK" (i18n) Fallback global do botão Aceitar
cancelLabel "No" (i18n) Fallback global do botão Cancelar em confirm
width "420px" Largura máxima da card
persistent true Bloqueia fecho com backdrop / Esc
zIndex 7000 Camada do diálogo face ao resto da UI
gap "1rem" Espaço ícone ↔ título ↔ texto
actionsGap "2rem" Espaço bloco de texto ↔ botões
font.sizeTitle "1.4rem" CSS font-size do título
font.sizeText "1.2rem" CSS font-size do corpo
font.family "Arial, sans-serif" CSS font-family do título e texto
buttonStyle Ver modelo boot Cores e variantes de botões por tema (light / dark)
presets.<variant> (i18n + ícones) Override de title, text, icon, iconColor, labels

Cada preset inclui title, text e labels por idioma. Override no boot só se precisar de personalizar ícones ou textos de domínio.

Variantes de preset: success, info, warn, error, confirm.

Prioridade por campo: chamadapreset (boot)i18nglobal (boot). Dentro de botões, buttonStyle.<tema> ganha sobre acceptColor / cancelColor planos do mesmo nível.

Uso rápido

<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(); // preset i18n (title + text)
    // await message.success({ text: "O registo foi guardado" });
  } catch (error) {
    await message.error({ text: "Não foi possível guardar" });
  }
}

async function onDelete(item: { id: string }) {
  const confirmed = await message.confirm({
    title: "Eliminar registo",
    text: "O registo selecionado será eliminado. Deseja continuar?",
  });
  if (!confirmed) return;

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

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

Alerta com override pontual de título e ícone:

await message.info({
  title: "Aviso importante",
  text: "Reveja os dados antes de continuar",
  icon: "campaign",
  iconColor: "warning",
});

Confirm com override de botões só em dark:

const ok = await message.confirm({
  text: "Deseja continuar?",
  buttonStyle: {
    dark: { cancelColor: "grey-4" },
  },
});
if (!ok) return;

Side-effect ao aceitar (ex.: logout):

await message.warn({
  text: "A sua sessão expira em 5 minutos",
  onAccept: async () => {
    await auth.refreshSession();
  },
});

TypeScript no seu IDE

Não memorize a API: deixe o autocompletar guiá-lo.

Se algo não aparecer no autocompletar, costuma ser uma prop inexistente ou um import incorreto — reveja o entrypoint principal antes de procurar no README.

API pública

Ponto de entrada: useDialogMessage().

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

const message = useDialogMessage();

Métodos

Método Retorno Descrição
success(options?) Promise<void> Alerta de sucesso (preset success; options opcional)
info(options?) Promise<void> Alerta informativo
warn(options?) Promise<void> Alerta de aviso
error(options?) Promise<void> Alerta de erro
confirm(options?) Promise<boolean> Confirmação com dois botões; true = confirmar
hide() void Fecha sem onAccept; em confirm resolve false

Estado reativo (só leitura)

Ref Descrição
visible Se o diálogo está visível

Opções por chamada (DialogMessageOptions)

Campo Descrição
title? Título; omitir → preset do boot; "" oculta o título
text? Corpo da mensagem
icon? Ícone Material Icons (Quasar)
iconColor? Cor do ícone: string ou { light?, dark? }
acceptLabel? Label do botão principal
acceptColor? Cor Quasar do botão principal (plana; ambos os temas)
acceptVariant? Variante Quasar: flat | outline | unelevated | push
buttonStyle? Override parcial { light?, dark? } de cores/variantes de botões
onAccept? Callback ao premir Aceitar / Confirmar

DialogMessageConfirmOptions estende o anterior com:

Campo Descrição
cancelLabel? Label do botão Cancelar
cancelColor? Cor Quasar do botão Cancelar (plana)
cancelVariant? Variante Quasar do botão Cancelar
onCancel? Callback ao premir Cancelar

Presets visuais

Configure cada preset em presets do boot (ou use os built-in).

Preset Uso típico Ícone default Cor default
success Operação concluída check_circle positive
info Aviso neutro info primary
warn Atenção / precaução warning warning
error Falha ou erro error negative
confirm Pergunta sim/não antes de agir back_hand primary

Constante exportada: DIALOG_MESSAGE_VARIANTS — lista de variantes válidas.

Ícone e botões por tema

O diálogo resolve cores conforme $q.dark.isActive (light / dark).

Ícone — iconColor

No boot (por preset) ou por chamada:

iconColor: { light: "negative", dark: "red-4" }
// ou plano (mesma cor em ambos os temas):
iconColor: "positive"

Botões — buttonStyle

Global no boot (aplica a todos os presets) ou parcial por preset / chamada:

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

Campos por tema em buttonStyle: acceptColor, acceptVariant, cancelColor, cancelVariant.

Built-in de variantes: Aceitar → unelevated, Cancelar → outline.

Alertas vs confirmação

Aspeto Alertas (successerror) Confirm (confirm)
Botões Um (Aceitar) Dois (Cancelar + Confirmar)
Promise void ao aceitar boolean (true / false)
Ordem UX (LTR) Cancelar à esquerda, Confirmar à direita
hide() Fecha sem callback Resolve false
Labels default presets.<variant>.acceptLabel (ex. "OK") presets.confirm.acceptLabel / cancelLabel

Só pode haver um diálogo visível de cada vez. Uma nova chamada fecha a sessão anterior (confirm pendente resolve false).

Tipos TypeScript exportados

A partir do entrypoint principal:

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";
Tipo Uso
DialogMessageApi Retorno de useDialogMessage()
ExtensionLocale "en" | "es" | "pt" — boot locale
DialogMessageI18nMessages Forma de boot messages (labels + presets aninhados)
PartialDialogMessageI18nMessages Override parcial de boot messages
DialogMessageOptions Argumento de success, info, warn, error
DialogMessageConfirmOptions Argumento de confirm()
DialogMessageDefaults Opções de configureDialogMessageDefaults
DialogMessagePresetConfig Campos de cada entrada em presets
DialogMessagePresetsDefaults Mapa parcial presets
DialogMessageFontDefaults { family?, sizeTitle?, sizeText? }
DialogMessageButtonStyleConfig { light?, dark? } com estilos de botões
DialogMessageButtonThemeStyle Cores/variantes de botões num tema
DialogMessageButtonVariant "flat" | "outline" | "unelevated" | "push"
DialogMessageThemeColor { light?, dark? } para cores por tema
DialogMessageThemeColorValue string ou DialogMessageThemeColor (iconColor)
DialogMessageThemeMode "light" | "dark"
DialogMessageVariant "success" | "info" | "warn" | "error" | "confirm"
ResolvedDialogMessageDefaults Defaults fundidos (referência / avançado)

Também se exportam configureDialogMessage (alias), resolveDialogMessageMessages, resolveExtensionLocale, BUILTIN_DIALOG_MESSAGE_DEFAULTS e DIALOG_MESSAGE_API_KEY (chave provide do boot para integrações avançadas).

Entrypoints públicos

O que importa no seu código:

Entrypoint Propósito
@benjaminor-dev/quasar-app-extension-dialog-message useDialogMessage, configureDialogMessageDefaults, helpers i18n (resolveDialogMessageMessages, resolveExtensionLocale), tipos e DIALOG_MESSAGE_VARIANTS

Boot (boot/dialog) e estilos (main.css) são registados pela extensão em quasar.config na instalação — não precisa de os importar manualmente numa instalação normal.

Troubleshooting

Vejo títulos ou botões em inglês e quero espanhol (ou português)

Sem configurar Quasar, os presets built-in estão em inglês. Escolha uma opção:

// quasar.config.ts — recomendado
framework: {
  lang: "es",
},
// src/boot/bor/bor-dialog-message-defaults.ts — fixar só o locale do Dialog Message
configureDialogMessageDefaults({ locale: "es" });

Boots ou estilos não aparecem em quasar.config

Em condições normais o install regista o defaults boot em boot: [] e o runner injeta boot/dialog + CSS ao compilar. Se faltar o defaults boot:

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

Erro: Pinia não inicializada

useDialogMessage() fora de setup

Chame-o dentro de setup, outro composable ou <script setup>. O boot deve ter sido executado (app montada).

O diálogo não mostra título

confirm() resolve sempre false

O diálogo fica atrás de outro overlay

Ajuste zIndex no boot (default 7000) conforme a hierarquia de camadas da sua app.

Mudei presets no boot e não se reflete

Reinicie o dev server. Confirme que edita src/boot/bor/bor-dialog-message-defaults.ts do host, não só o modelo da extensão.


MIT © Benjamín Olvera R.