npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@benjaminor-dev/quasar-app-extension-dialog-loader

v0.1.10

Published

Dialog loader for Quasar — global loading dialog via useDialogLoader()

Downloads

1,890

Readme

Dialog Loader para Quasar

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

npm version license Vue Quasar TypeScript Node

Extensão Quasar para diálogo modal de carregamento global 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 do Pinia do host roda antes do boot desta extensão.
  3. Importar useDialogLoader() onde executar pedidos async.
  4. Envolver a tarefa com await loader.run({ task: () => api.save() }) — ou { label, task } para override pontual.

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 useDialogLoader() — não é um componente embebível.

  • run({ task }) ou run(task) — caso principal; usa o label do boot se não passar label.
  • run({ label, task }) — override pontual do texto sem alterar o boot.
  • show() / hide() — controlo manual com contador interno de operações pendentes.
  • Três variantes de apresentação: glass, primary, minimal.
  • Spinners configuráveis (subset curado do Quasar; default ios).
  • Anti-piscar: delays de abertura/fecho e tempo mínimo visível.
  • Defaults globais no boot do host (gap, font, variant, spinner…); label por chamada opcional.
  • i18n built-in en, es, pt — segue $q.lang do Quasar; overrides no boot (locale, messages).
  • Controlos em task: pause, resume, cancel e signal (AbortSignal).

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 do Pinia do host deve executar-se antes do boot desta extensão.

Instalação na app Quasar

quasar ext add @benjaminor-dev/dialog-loader

Remover:

quasar ext remove @benjaminor-dev/dialog-loader

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 via npm.

O que a extensão adiciona ao host

Recursos instalados ou registados pela extensão:

| Recurso | Rota npm | | --- | --- | | Boot do diálogo | ~@benjaminor-dev/quasar-app-extension-dialog-loader/boot/dialog | | Estilos | ~@benjaminor-dev/quasar-app-extension-dialog-loader/main.css | | Defaults boot (host) | src/boot/bor/bor-dialog-loader-defaults.ts — criado no install; Skip/Overwrite se já existir |

Install (quasar ext add / invoke): cria src/boot/bor/bor-dialog-loader-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 Loader — boot/dialog
3. bor/bor-dialog-loader-defaults (host)

Em quasar.config só verá bor/bor-dialog-loader-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 importar DialogLoader em App.vue.

Defaults globais (boot)

Evite repetir variant, spinner, gap, font, delays e zIndex em cada chamada. Prioridade do label: run({ label }) / show() → boot label → i18n (locale / $q.lang / en).

Após quasar ext add, reveja src/boot/bor/bor-dialog-loader-defaults.ts — plantilla com todas as opções boot (// recomendado: …) e instruções de idioma no comentário do ficheiro.

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

configureDialogLoaderDefaults({
  // locale: "pt", // descomente para fixar um idioma específico no Dialog Loader
  variant: "glass",
  spinner: "ios",
  openDelayMs: 120,
  hideDelayMs: 450,
  minVisibleMs: 600,
  backdropBlur: "blur(10px)",
  zIndex: 6000,
  gap: "2rem",
  font: {
    family: "Arial, sans-serif",
    size: "1.35rem",
  },
  spinnerColor: {
    light: "primary",
    dark: "white",
  },
  spinnerTrackColor: {
    light: "grey-4",
    dark: "grey-7",
  },
});

Idioma (i18n)

Built-in en, es e pt. Por defeito o label segue o idioma do Quasar ($q.lang.isoName); se o Quasar não definir idioma, cai em en ("Loading...").

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

Resolução do label: run({ label }) / show(label) → boot label → boot messages.loadingLabel → catálogo built-in → en.

Chaves i18n built-in: loadingLabel (texto padrão do loader), operationCancelled (DialogLoaderRunCancelledError quando cancel() aborta a tarefa).

| Opção | Quando usar | | --- | --- | | framework.lang em quasar.config.ts | Recomendado — alinha Dialog Loader com o resto do Quasar | | locale: 'pt' no boot | Fixar um idioma específico (en | es | pt); ignora mudanças de $q.lang | | messages: { loadingLabel: '…' } | Só alterar um texto sem tocar no locale | | label: '…' no boot | Label fixo sempre (ignora i18n) |

Exemplo Quasar config (português em toda a app):

// quasar.config.ts
framework: {
  lang: "pt-BR",
},

configureDialogLoader é alias de configureDialogLoaderDefaults.

| Opção boot | Default built-in | Descrição | | --- | --- | --- | | locale | (segue $q.lang) | Fixa en | es | pt para textos da extensão | | messages | (por locale) | Override parcial (loadingLabel, operationCancelled) | | label | "Loading..." (i18n) | Texto fixo quando não passa label em show() / run() | | variant | "glass" | Apresentação do diálogo | | spinner | "ios" | Indicador de carregamento (ver spinners) | | openDelayMs | 120 | Atraso antes de mostrar (evita flashes em pedidos muito rápidos) | | hideDelayMs | 450 | Atraso extra ao fechar (alinha com animação de saída) | | minVisibleMs | 600 | Tempo mínimo visível ainda que a operação termine antes | | backdropBlur | "blur(10px)" | Valor CSS backdrop-filter do overlay | | zIndex | 6000 | Abaixo do Quasar Notify (~9500) para toasts continuarem visíveis | | gap | "2rem" | Espaço label↔spinner | | font.family | "Arial, sans-serif" | CSS font-family do label | | font.size | "1.35rem" | CSS font-size do label | | spinnerColor | (por variant) | Cor Quasar do spinner — plano ou { light, dark } | | spinnerTrackColor | (por variant) | Cor Quasar do track em spinners circulares — plano ou { light, dark } |

Se omitir spinnerColor / spinnerTrackColor, o fallback depende de variant: em primary o spinner é branco; em glass e minimal usa primary e grey-4. Configure { light, dark } no boot para adaptar o spinner ao tema do host ($q.dark).

Uso rápido

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

const loader = useDialogLoader();

async function onSave() {
  try {
    await loader.run({ task: () => api.save(formData) });
    // notify.success('Guardado');
  } catch (error) {
    // notify.error('Erro ao guardar');
  }
}
</script>

<template>
  <q-btn label="Guardar" @click="onSave" />
</template>

Sem label explícito — usa i18n conforme $q.lang (p. ex. "Carregando..." com lang: 'pt-BR'):

await loader.run(() => fetchUsers());
// equivalente:
await loader.run({ task: () => fetchUsers() });

Override pontual do texto:

await loader.run({ label: "A guardar...", task: () => api.save(formData) });

Controlos opcionais dentro de task:

await loader.run({
  task: async ({ pause, resume, cancel, signal }) => {
    await api.prepare();
    pause(); // oculta overlay; a tarefa continua
    await api.finishInBackground();
    resume(); // volta a mostrar o loader
    await fetch("/api/finalize", { signal }); // cancel() aborta este fetch
  },
});

| Controlo | O que faz | | --- | --- | | pause() | Oculta o loader; não cancela a tarefa | | resume() | Reabre o loader após um pause() | | cancel() | Aborta signal, fecha o loader e rejeita run() com DialogLoaderRunCancelledError | | signal | Passe a fetch / axios para cancelação cooperativa |

pause(), resume() e cancel() são idempotentes e só afetam essa operação de run().

import { DialogLoaderRunCancelledError } from "@benjaminor-dev/quasar-app-extension-dialog-loader";

try {
  await loader.run({ task: ({ signal }) => fetch(url, { signal }) });
} catch (error) {
  if (error instanceof DialogLoaderRunCancelledError) return;
  throw error;
}

Controlo manual (menos habitual):

loader.show("A processar...");
try {
  await longTask();
} finally {
  loader.hide();
}

TypeScript no seu IDE

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

  • useDialogLoader() devolve DialogLoaderApi — métodos e refs aparecem ao escrever loader..
  • Em configureDialogLoaderDefaults({ ... }), Ctrl+Space (Windows/Linux) ou Cmd+Space (macOS) lista variant, spinner, spinnerColor, spinnerTrackColor, gap, font, openDelayMs, etc.
  • variant aceita "glass" \| "primary" \| "minimal"; spinner aceita os valores de DIALOG_LOADER_SPINNER_TYPES (p. ex. "ios", "dots", "circular").
  • run() — overloads: run(task) ou run({ task, label? }); em task, desestruture { pause, resume, cancel, signal } com tipos inferidos.
  • No boot, locale aceita "en" \| "es" \| "pt"; messages aceita DialogLoaderMessages parcial (loadingLabel, operationCancelled).
  • Passe o cursor sobre um método: o tooltip mostra parâmetros e JSDoc.

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

API pública

Ponto de entrada: useDialogLoader().

import { useDialogLoader } from "@benjaminor-dev/quasar-app-extension-dialog-loader";

const loader = useDialogLoader();

Métodos

| Método | Descrição | | --- | --- | | run(task) | Executa a tarefa com loader; label do boot. Fecha em finally. | | run({ task }) | Igual ao acima (forma objeto). | | run({ label, task }) | Igual com label pontual para essa operação. | | show(label?) | Incrementa o contador interno e agenda abertura do diálogo. | | hide() | Decrementa o contador; fecha a UI só quando não restam operações pendentes. |

Estado reativo (somente leitura)

| Ref | Descrição | | --- | --- | | visible | Se o diálogo está visível. | | label | Texto mostrado no diálogo. |

Quando usar run vs show / hide

| Abordagem | Quando | | --- | --- | | run() | Pedidos async — preferir run({ task }) ou run(task); label só se precisar override. Recomendado. | | show() / hide() | Fluxos manuais ou várias fases com o mesmo label. |

Variantes visuais

Configure variant no boot do host (ou built-in).

| Valor | Apresentação | | --- | --- | | glass | Glassmorphism — card semitransparente com blur (default) | | primary | Card sólida com cor --q-primary; texto e spinner brancos | | minimal | Pill horizontal compacto, menos intrusivo |

Indicadores de carregamento (spinner)

Configure spinner no boot. Subset curado de spinners Quasar:

| Valor | Estilo | | --- | --- | | ios | Barras radiais estilo iOS (default) | | circular | Anel com track (QCircularProgress) | | dots | Três pontos animados | | oval | Óvalo a rodar | | tail | Cauda rotativa | | puff | Círculo pulsante | | rings | Anéis concêntricos | | bars | Barras verticais | | hourglass | Ampulheta | | infinity | Símbolo ∞ |

Constante exportada: DIALOG_LOADER_SPINNER_TYPES — útil para validar valores em runtime.

Anti-piscar e operações concorrentes

A store mantém um pendingCount: cada show() / início de run() incrementa; cada hide() / fim de run() decrementa. A UI só fecha quando o contador chega a zero.

Delays configuráveis no boot:

  • openDelayMs — não mostra o diálogo se todas as operações terminarem antes.
  • minVisibleMs — evita flash de fecho imediato após abrir.
  • hideDelayMs — alinha o fecho com a animação fade do overlay.

Várias chamadas concorrentes a run() ou show() partilham o mesmo diálogo até todas terminarem.

Tipos TypeScript exportados

Desde o entrypoint principal:

import {
  useDialogLoader,
  DialogLoaderRunCancelledError,
  resolveDialogLoaderMessages,
  resolveExtensionLocale,
  type DialogLoaderApi,
  type DialogLoaderRunControls,
  type DialogLoaderRunOptions,
  type DialogLoaderRunTask,
  type DialogLoaderDefaults,
  type DialogLoaderFontDefaults,
  type DialogLoaderMessages,
  type DialogLoaderThemeColor,
  type DialogLoaderThemeColorValue,
  type DialogLoaderThemeMode,
  type DialogLoaderVariant,
  type DialogLoaderSpinnerType,
  type ExtensionLocale,
  type ResolvedDialogLoaderDefaults,
} from "@benjaminor-dev/quasar-app-extension-dialog-loader";

| Tipo | Uso | | --- | --- | | DialogLoaderApi | Retorno de useDialogLoader() | | ExtensionLocale | "en" \| "es" \| "pt" — boot locale | | DialogLoaderMessages | Forma de boot messages (loadingLabel, operationCancelled) | | DialogLoaderRunOptions | Argumento objeto de run({ label?, task }) | | DialogLoaderRunControls | { pause, resume, cancel, signal } recebido em task | | DialogLoaderRunTask | Tipo do callback task | | DialogLoaderRunPause | Oculta o loader sem cancelar | | DialogLoaderRunResume | Reabre o loader após pause() | | DialogLoaderRunCancel | Cancela a operação | | DialogLoaderRunCancelledError | Erro ao cancelar com cancel() | | DialogLoaderDefaults | Opções admitidas em configureDialogLoaderDefaults | | DialogLoaderFontDefaults | { family?, size? } dentro de DialogLoaderDefaults.font | | DialogLoaderThemeColorValue | Cor plana ou { light?, dark? } para spinner | | DialogLoaderThemeColor | { light?, dark? } — parte de DialogLoaderThemeColorValue | | DialogLoaderThemeMode | "light" \| "dark" — resolvido com $q.dark.isActive | | DialogLoaderVariant | "glass" \| "primary" \| "minimal" | | DialogLoaderSpinnerType | União de spinners suportados | | ResolvedDialogLoaderDefaults | Defaults já mergeados (interno / referência) |

Também se exportam BUILTIN_DIALOG_LOADER_DEFAULTS, DIALOG_LOADER_SPINNER_TYPES, resolveDialogLoaderMessages, resolveExtensionLocale, configureDialogLoader (alias) e DIALOG_LOADER_API_KEY (chave de 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-loader | useDialogLoader, configureDialogLoaderDefaults, helpers i18n (resolveDialogLoaderMessages, resolveExtensionLocale), tipos e DIALOG_LOADER_SPINNER_TYPES |

Boot (boot/dialog) e estilos (main.css) são registados pela extensão em quasar.config ao instalar — não precisa importá-los manualmente.

Troubleshooting

Vejo "Loading..." e quero português (ou espanhol)

O default sem configurar Quasar é inglês. Escolha uma linha:

// quasar.config.ts — recomendado (toda a app Quasar)
framework: {
  lang: "pt-BR",
},
// src/boot/bor/bor-dialog-loader-defaults.ts — fixar só o locale do Dialog Loader
configureDialogLoaderDefaults({ locale: "pt" });

Override de um só texto:

configureDialogLoaderDefaults({ messages: { loadingLabel: "Carregando..." } });

O label não muda se o idioma for alterado durante um run()

Se o usuário mudar o idioma da app enquanto o loader está visível, o texto na tela permanece o de quando run() / show() começou. Ao fechar o loader, o label em repouso segue o novo locale. Para fixar um idioma em toda a extensão, use locale no boot.

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-loader

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 boot dialog desta extensão.

useDialogLoader() fora de setup

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

O loader pisca em pedidos rápidos

Ajuste no boot: suba openDelayMs, minVisibleMs ou ambos.

O loader não fecha após show()

Cada show() requer um hide() correspondente (ou use run(), que equilibra automaticamente).

O diálogo fica atrás de outro overlay

Revise zIndex no boot (default 6000).

Mudei spinner no boot e não se reflete

Reinicie o dev server. Confirme que edita src/boot/bor/bor-dialog-loader-defaults.ts do host.


MIT © Benjamín Olvera R.