Dialog Message para Quasar
🇺🇸 English | 🇪🇸 Versión en español
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
- O que é e o que inclui
- Requisitos e compatibilidade
- Instalação na app Quasar
- O que a extensão adiciona ao host
- Defaults globais (boot)
- Idioma (i18n)
- Uso rápido
- TypeScript no seu IDE
- API pública
- Presets visuais
- Ícone e botões por tema
- Alertas vs confirmação
- Tipos TypeScript exportados
- Entrypoints públicos
- Troubleshooting
Em 30 segundos
Fluxo base recomendado:
- Instalar a extensão na sua app Quasar (
quasar ext add). - Garantir que o boot de Pinia do host executa antes do boot desta extensão.
- Importar
useDialogMessage()onde mostrar feedback ao utilizador. - Chamar
await message.success()(preset i18n) ouawait 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.
- Presets de alerta —
success,info,warn,error(um botão Aceitar). - Confirmação —
confirm()com dois botões (Cancelar / Confirmar) ePromise<boolean>. - Defaults por preset no boot do host (
title,icon,iconColor, labels). - i18n built-in
en,es,pt— presets e botões seguem$q.lang; overrides no boot (locale,messages,presets). - Tema light / dark —
iconColor: { light, dark }ebuttonStyleglobal ou por preset. - Override por chamada —
title,text,icon, cores, variantes de botão e labels. onAccept/onCancel— side-effects opcionais ao premir botões.hide()— fecho imperativo sem executar callbacks.persistent— impede fechar com backdrop ou Esc (configurável no boot).
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.config → boot: [] 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: chamada → preset (boot) → i18n → global (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.
useDialogMessage()devolveDialogMessageApi— métodos e refs aparecem ao escrevermessage..- Em
configureDialogMessageDefaults({ ... }), Ctrl+Space / Cmd+Space listapresets,buttonStyle,gap,font,zIndex, etc. - Dentro de
presets.success,presets.confirm, etc., o IDE sugeretitle,text,icon,iconColor,acceptLabel,cancelLabel,buttonStyle. - Em
font, o IDE sugerefamily,sizeTitle,sizeText. iconColoraceita string plana ou{ light, dark };buttonStyleagrupa cores e variantes de botões por tema.success/info/warn/erroraceitamDialogMessageOptionsopcional;confirmaceitaDialogMessageConfirmOptionsopcional (adicionacancelLabel,cancelColor,cancelVariant,onCancel).confirm()resolvePromise<boolean>; os presets de alerta resolvemPromise<void>ao premir Aceitar.- Passe o cursor sobre um método: o tooltip mostra parâmetros e JSDoc.
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 (success … error) |
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
- Verifique um boot de Pinia no host (
app.use(pinia)ou equivalente). - Em
quasar.config, o boot de Pinia deve ir antes do bootdialogdesta extensão.
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
- Verifique se passou
title: ""(oculta o título de propósito). - Se omitir
title, usa-sepresets.<variant>.titledo boot.
confirm() resolve sempre false
- Confirme que não chama
hide()nem abre outro diálogo antes de premir um botão. - Uma segunda chamada com o primeiro aberto fecha o anterior com
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.