Loading
Overlay de tela cheia que bloqueia a interação durante uma operação assíncrona global, acionado pelas funções showLoading() e hideLoading() do mk-loading.
O mk-loading cobre a viewport inteira com um backdrop, exibe um spinner em anel centralizado e bloqueia toda a interação de ponteiro e teclado enquanto uma operação assíncrona global está em andamento. É acionado pelas funções imperativas showLoading() e hideLoading() — a instância é montada automaticamente na primeira chamada, sem nenhuma tag declarada na árvore.
Chamadas concorrentes compartilham o mesmo overlay por contagem de referência: ele desaparece apenas quando a última operação pendente termina.
Quando usar
Use o mk-loading quando a operação afeta a página inteira e a interação concorrente causaria problema — o usuário perde o controle da interface enquanto o overlay está aberto.
- Uma submissão dispara várias requisições e a tela ficaria inconsistente durante o processo.
- A navegação é bloqueante e o usuário não deve disparar ações no meio da transição.
- Um processamento pesado no cliente deixaria a interface em estado intermediário.
- O carregamento é escopado a uma seção, card ou lista — use o Skeleton.
- O progresso é conhecido e pode ser medido — use a Progress Bar.
- Apenas uma ação está em andamento — use o Button com
loading.
Anatomia
| # | Parte | Obrigatório? | Função |
|---|---|---|---|
| 1 | Backdrop | Sim | Camada de fundo semi-transparente com desfoque que cobre a viewport e bloqueia o ponteiro. |
| 2 | Track | Sim | Anel de fundo estático do spinner. Permanece neutro independentemente da cor escolhida. |
| 3 | Indicator | Sim | Arco em rotação contínua sobre o track. Sua cor é definida pela prop color. |
Padrão
size="xl" e color="brand". Acione o gatilho para ver o overlay cobrir a tela por dois segundos.
import { showLoading } from '@db1/makuco-ui-core';
async function handleSubmit() {
const dismiss = showLoading();
try {
await salvarFormulario();
} finally {
dismiss();
}
}import { showLoading } from '@db1/makuco-ui-core';
async salvar(): Promise<void> {
const dismiss = showLoading();
try {
await this.api.salvar();
} finally {
dismiss();
}
}Operações concorrentes
Cada showLoading() incrementa o contador de referência e cada hideLoading() decrementa. No exemplo abaixo, duas operações começam juntas e terminam em 1s e 3s — o overlay permanece visível até a mais lenta concluir.
import { showLoading, hideLoading } from '@db1/makuco-ui-core';
// As duas chamadas compartilham o mesmo overlay.
const dismissA = showLoading();
const dismissB = showLoading();
await Promise.all([
buscarUsuario().finally(dismissA),
buscarPedidos().finally(dismissB),
]);
// O overlay sai somente aqui, quando o contador chega a zero.import { showLoading } from '@db1/makuco-ui-core';
const dismissA = showLoading();
const dismissB = showLoading();
await Promise.all([
firstValueFrom(this.api.usuario()).finally(dismissA),
firstValueFrom(this.api.pedidos()).finally(dismissB),
]);Tamanhos
O diâmetro do anel usa a mesma escala semântica do Icon: xs (12px), sm (16px), md (24px), lg (40px) e xl (48px).
import { showLoading } from '@db1/makuco-ui-core';
const dismiss = showLoading({ size: 'md' });import { showLoading } from '@db1/makuco-ui-core';
const dismiss = showLoading({ size: 'md' });Cor
color="brand" é o padrão. color="neutral" pinta o arco de branco, para uso sobre superfícies brand ou coloridas. O track permanece neutro nos dois casos.
import { showLoading } from '@db1/makuco-ui-core';
const dismiss = showLoading({ color: 'neutral' });import { showLoading } from '@db1/makuco-ui-core';
const dismiss = showLoading({ color: 'neutral' });API do handler
| Função | Assinatura | Descrição |
|---|---|---|
showLoading | (options?: LoadingOptions) => () => void | Incrementa o contador de referência e exibe o overlay, montando a instância única na primeira chamada. Retorna uma função de dispensa idempotente, equivalente a um hideLoading(). |
hideLoading | () => void | Decrementa o contador de referência. Oculta o overlay quando o contador chega a zero. |
Opções
A aparência do spinner é definida na chamada. Como a tag não é declarada na árvore, showLoading() é o único lugar onde size e color podem ser informados.
| Opção | Tipo | Padrão | Descrição |
|---|---|---|---|
size | "xs" | "sm" | "md" | "lg" | "xl" | "xl" | Diâmetro do anel do spinner. |
color | "brand" | "neutral" | "brand" | Cor do arco animado. O track permanece neutro em ambos os valores. |
Cada exibição parte dos valores padrão, então a aparência de uma chamada anterior não vaza para a próxima. Entre chamadas concorrentes prevalece a última que especificou um valor — uma chamada sem opções não altera o que já está na tela.
Props — mk-loading
Todas as props são escritas pelo handler. size e color chegam pelas opções de showLoading(); open é gerenciado pela contagem de referência.
| Prop | Tipo | Padrão | Descrição |
|---|---|---|---|
open | boolean | false | Controla a visibilidade do overlay. Gerenciado pelo handler — declarar a tag manualmente para controlar open não é uma superfície suportada. |
size | "xs" | "sm" | "md" | "lg" | "xl" | "xl" | Diâmetro do anel do spinner, na mesma escala semântica do Icon. |
color | "brand" | "neutral" | "brand" | Cor do arco indicator. O track permanece neutro em ambos os valores. |
Acessibilidade
- O host recebe
role="status"earia-live="polite": a abertura é anunciada sem interromper o leitor de tela. A live region permanece na árvore com o overlay fechado, para que a abertura seja percebida como mudança de conteúdo. aria-labeltraz o rótulo traduzido (Carregando/Cargando/Loading), resolvido pelolangdo documento. O mesmo texto é renderizado como conteúdo visualmente oculto.- Backdrop e spinner são decorativos e recebem
aria-hidden="true". - Ao abrir, os irmãos de
document.bodyrecebeminert: o conteúdo por trás fica não-focável e não-interativo, sem foco preso. Elementos que já estavaminertpor outro motivo são preservados ao fechar. - O scroll do
bodyé travado ao abrir e o valor anterior é restaurado ao fechar — um Dialog que já travava o scroll continua travado depois que o overlay sai. - Não há elemento focável dentro do overlay, então o foco não precisa ser movido ativamente.
- A animação de entrada do backdrop respeita
prefers-reduced-motion. A rotação do spinner permanece: é a única indicação de que algo está em andamento.
| Tecla | Comportamento |
|---|---|
Tab / Shift+Tab | Não alcança o conteúdo por trás do overlay — os irmãos de document.body estão inert. |
Esc | Nenhuma ação. O overlay fecha apenas por hideLoading(). |