Toda tela que mostra dados existe em mais de um estado. O desenho “feliz”, com dados carregados, é só um deles. Na operação logística, os outros estados são os que a pessoa mais vê: a conexão do pátio oscila, o filtro não retorna nada, o servidor demora.
Regra de ouro: nenhuma tela está pronta enquanto os cinco estados abaixo não estiverem desenhados e implementados.
| Estado |
Pergunta que responde |
Componente |
| Carregando |
“O sistema está trabalhando?” |
Loader, Progress |
| Vazio |
“Por que não há nada aqui e o que faço?” |
EmptyState |
| Erro |
“O que falhou e como resolvo?” |
Alert ou EmptyState com ação de tentar de novo |
| Sucesso |
“Deu certo?” |
Toast, botão Success, tela de conclusão |
| Com dados |
O estado principal |
O componente da tela |
Regra: o usuário nunca fica olhando uma tela parada sem saber se o sistema travou.
| Escopo |
Quando |
Como |
| Global |
Página inteira carregando |
Loader centralizado |
| Da área |
Painel, tabela ou card carregando |
Loader sobre a área afetada (o resto da tela continua utilizável) |
| Inline |
Uma ação específica, como salvar |
Botão em estado de carregamento |
| Skeleton |
Antecipar a estrutura de tabelas e painéis |
Ainda sem componente (veja Para desenvolvedores) |
- Deve dizer o que está sendo carregado, sempre que possível: Gerando relatório…, Pesquisando motoristas…, Salvando…
- Deve usar caixa de sentença, sem pronomes nem artigos. “Por favor, aguarde enquanto carregamos…” vira Carregando…
- Reticências: use quando a espera for longa (espera ativa). Em spinners pequenos dentro de botões, são opcionais.
- Deve desabilitar a ação que está em andamento para evitar duplo clique (duas cargas despachadas por engano é um problema real).
- Recomendado usar barra de progresso, em vez de spinner, quando o sistema sabe quanto falta (importação de arquivo, geração de relatório longo).
- [Proposta] Referência de tempos de resposta (Nielsen): até ~1 s não precisa de indicador; entre 1 e 10 s use spinner; acima de 10 s mostre progresso e permita continuar em outra tela.
O EmptyState transforma uma tela vazia em um próximo passo. Existem dois vazios diferentes, e a mensagem muda:
| Tipo |
Situação |
Título |
Descrição |
Ação |
| Primeiro uso |
Nunca houve dado |
Nenhum Documento |
O veículo ainda não possui anexos cadastrados. |
Subir Arquivo |
| Sem resultado |
Há dado, mas o filtro escondeu tudo |
Motorista Não Encontrado |
Nenhum motorista com o CPF informado. |
Limpar Filtros |
| Tudo em ordem |
Ausência é boa notícia |
Nenhum Alerta Pendente |
Não há alertas para ler no momento. |
Ir para o Dashboard |
| Estrutura, de cima para baixo: |
|
|
|
|
- Ícone ou ilustração ligado ao contexto (uma caixa para “sem mercadoria”).
- Título: o que está acontecendo, em Caixa de Título.
- Descrição: por que e como resolver, em caixa de sentença.
- Ação: um caminho para criar o dado ou desfazer o filtro, em Caixa de Título.
- Deve ter título e descrição. Só ilustração não explica nada.
- Não deve usar mensagens genéricas (“Ops, nada por aqui”).
- Recomendado que o vazio de “sem resultado” traga a ação de limpar filtros, não a de criar.
Erros acontecem em três escalas, e cada uma tem seu lugar:
| Escala |
Exemplo |
Onde aparece |
| Campo |
CPF inválido |
No próprio campo, abaixo dele |
| Ação |
Não foi possível salvar a carga |
Alert no contexto (ou Toast, se não exigir correção) |
| Tela |
Não foi possível carregar as viagens |
Estado de erro ocupando a área, com ação de tentar de novo |
| Fórmula da mensagem: o que aconteceu + como resolver, sem culpa. |
|
|
| Evite |
Prefira |
|
| — |
— |
|
| Você digitou o CPF errado. |
CPF inválido. Insira apenas números. |
|
| Ocorreu um erro. |
Falha na conexão. Tente novamente. |
|
| Ops, algo deu errado! |
Não foi possível salvar a carga. Verifique o peso informado. |
|
- Deve preservar o que o usuário já digitou. Perder um formulário longo por um erro de rede é a pior experiência possível.
- Deve manter o erro visível até ser resolvido (veja Feedback ao usuário).
- Recomendado que erros de campo apareçam ao sair do campo, não a cada tecla digitada.
- [Proposta] Em erro de tela, oferecer sempre Tentar novamente.
Proporcional ao impacto:
| Impacto |
Como confirmar |
| Ação pequena (salvar, editar) |
Toast: Alterações salvas. |
| Conclusão de fluxo (despachar, registrar entrega) |
Botão Success no fechamento e estado de conclusão claro |
| Ação em massa |
Resumo do que foi feito: 12 cargas despachadas. 2 com falha. |
Definidos na página do Input e válidos para os campos do sistema:
| Estado |
Como se apresenta |
Observação |
| Padrão |
Borda neutra, fundo padrão |
Placeholder só exemplifica o formato, sem reticências |
| Foco |
Borda realçada na cor primária, com cursor |
O rótulo ganha destaque |
| Obrigatório |
Realce em amarelo, asterisco no rótulo e aria-required |
Amarelo comunica prioridade sem a conotação punitiva do vermelho |
| Preenchido |
Borda de maior peso visual |
Confirma que o dado foi assimilado |
| Desabilitado |
Opacidade reduzida e cursor de bloqueio |
Rótulo continua legível; evite ajuda longa |
| Somente leitura |
Fundo e texto esmaecidos, valor visível |
Dado que existe, mas não pode ser alterado nesta etapa |
| Erro |
Borda e mensagem em vermelho |
Mensagem específica, veja Erro acima |
- Deve manter o rótulo visível em todos os estados. Placeholder nunca substitui rótulo.
- [Proposta] Quando um campo ou botão está desabilitado, explique por quê (tooltip ou texto de apoio). Sem isso, a pessoa não sabe o que fazer para habilitar.
| Estado |
Frame no Figma |
| Loading |
Loading |
| EmptyState |
EmptyState |
| Input (estados de campo) |
Input |
| Ao entregar uma tela, entregue os cinco estados no Figma. Uma tela só com o estado “com dados” está incompleta para desenvolvimento. |
|
| Necessidade |
mds-styles (HTML/CSS) |
mds-angular |
Situação |
| Spinner |
.mds-loader |
<mds-loader> |
Disponível |
| Carregando sobre uma área |
.mds-loader-box (--absolute, --full, --lighter) |
<mds-loader-box> |
Disponível |
| Botão carregando |
.mds-btn |
mdsButton com [loading] |
Disponível |
| Barra e círculo de progresso |
.mds-progress--bar, .mds-progress--circle |
<mds-progress-circle> |
Disponível |
| Estado vazio |
.mds-empty-state |
<mds-empty-state> |
Disponível |
| Erro em campo |
.mds-input--danger |
<mds-input> |
Disponível |
| Skeleton |
não existe |
não existe |
Lacuna |
Lacuna conhecida: Skeleton. A página do Loading prevê skeleton para antecipar tabelas e painéis, mas não há componente dedicado no mds-styles nem no mds-angular. Até existir, use .mds-loader-box sobre a área.