Design de aplicação web
Uma aplicação web é um lugar para onde as pessoas retornam todos os dias para encontrar registros, alterá-los e passar o trabalho adiante. Ela é bem-sucedida quando as pessoas sempre sabem onde estão, o que estão vendo, o que podem fazer e o que acabou de acontecer, e quando podem voltar para a mesma visualização amanhã por meio de uma URL. A falha de modelo mais comum é uma tela bonita de caminho feliz sem lugar para se apoiar: nenhum estado vazio, de carregamento, de erro ou de falta de permissão; filtros que desaparecem ao recarregar; ações em massa sem contagem e sem desfazer; um "Excluir" que dispara em uma atualização otimista que o servidor rejeita depois; e linhas de botões "Editar" idênticos que um agente não consegue distinguir.
Aplique os princípios hierarquizados de interface-guidelines (todos podem usar > diz a verdade > diz o que significa > a resposta vem primeiro > erros são sobrevivíveis > permanece no lugar > o possível é visível > convenção > polimento). Se essa skill estiver instalada, leia seu SKILL.md primeiro. Suas referências cobrem temporização de feedback, redação de erros, tabelas como dados e semântica voltada a agentes; esta skill adiciona os padrões específicos para UI de aplicações.
Resumo
- Objetos e verbos. Liste os substantivos (pedidos, clientes, faturas) e o que cada função pode fazer com cada um. A navegação e as permissões decorrem dessa tabela.
- Funções e tenants. Quem pode ver e alterar o quê? Existe mais de um workspace, organização ou ambiente (staging, produção) em que uma pessoa pode estar?
- Tarefas diárias com frequência, e a única visualização que cada função abre primeiro.
- Tamanhos de coleção: típico e pior caso (10 linhas ou 2 milhões). Isso decide paginação, pesquisa e filtragem no servidor.
- Custo do erro para cada verbo de mutação, e se pode ser desfeito no servidor.
- Concorrência: duas pessoas, ou uma pessoa e um agente, podem editar o mesmo registro?
- Quem escreve o texto exibido? Nomes de clientes, corpos de tickets, arquivos importados: tudo escrito por terceiros.
- Leitor agente: agentes de navegador na UI, uma API, ou ambos? A UI e a API devem compartilhar um serviço por ação.
Regras
Shell e navegação
- A navegação espelha os objetos, não o organograma. Itens de nível superior são os substantivos com os quais as pessoas trabalham, em ordem de uso, rotulados com as palavras que as pessoas usam. [S: Mac HIG 1992 pp. 54-61 (agrupar por lógica, depois frequência); J]
- Mantenha a navegação primária visível no desktop. A navegação oculta reduziu a descoberta e atrasou tarefas no estudo da NN/g; um hambúrguer é um compromisso de telefone. [E: NN/g, fundamento]
- Mostre onde a pessoa está, de três maneiras: o item de navegação atual marcado com
aria-current="page"e um estado visível, umh1da página nomeando o objeto ou lista, e um título de documento que muda com a rota. [S: WCAG 2.4.2, 2.4.8; J] - Breadcrumbs mostram hierarquia, não histórico, apenas em árvores de objetos profundas; a página atual não é um link. [P: NN/g breadcrumbs]
- O workspace, organização ou ambiente atual está sempre visível no shell, em palavras, e a produção é visualmente distinta do staging. Alternar de tenant é um ato explícito, leva à página equivalente ou inicial daquele tenant e nunca carrega uma seleção ou rascunho de um tenant para outro. [J]
- Toda visualização tem uma URL. Filtros, ordenação, pesquisa, página, aba selecionada e registro aberto estão na URL; recarregar e compartilhar os restauram. [S: fundamento agent-surfaces 3]
- Voltar retorna à lista como estava: mesmos filtros, posição de rolagem e foco na linha que a pessoa abriu. [S: Mac HIG 1992 p. 140 (janela reativada retorna como estava); J]
Listas e tabelas
- Tabelas são para comparar registros; listas são para escanear um atributo. Use uma
<table>real para dados tabulares. [S: fundamento; NN/g data tables] - Suporte as quatro tarefas de tabela: encontrar registros, comparar entre linhas, visualizar ou editar uma linha, agir em uma ou várias. [P: NN/g data tables]
- A primeira coluna identifica a linha com uma chave humana estável (nome mais ID); mantenha ela e o cabeçalho fixos ao rolar. [P: NN/g data tables]
- Ordene no cabeçalho: um
<button>dentro de<th>,aria-sortapenas na coluna ordenada e uma seta visível. A ordenação padrão é informada ("Mais recentes primeiro"). [S: APG sortable table; P: Carbon] - Filtros são visíveis, removíveis e contados. Mostre filtros aplicados como chips com um Limpar tudo, a contagem de resultados ("38 de 1.204 pedidos") e uma mensagem de resultado vazio que nomeia os filtros. Use as palavras da pessoa para os nomes dos filtros. [P: NN/g filters; S: fundamento]
- Pesquisa, filtro e ordenação no servidor quando a coleção é grande. Nunca ordene ou conte apenas a página carregada e a apresente como o todo. [J; fundamento regra da verdade]
- Paginação para trabalho orientado a objetivos; reserve rolagem infinita para feeds. A paginação dá posição, um lugar estável para retornar e um rodapé alcançável. Informe o intervalo e o total, e "Fim da lista". [P: NN/g infinite scrolling; S: Smith and Mosier 4.2/7]
- Ações de linha são visíveis ou alcançáveis por foco de teclado, nunca apenas ao passar o mouse, e nomeadas por linha ("Arquivar INV-2041"). Com menos de três ações, mostre-as inline. [S: fundamento agent-surfaces 3; P: Carbon]
- Densidade segue a prática. Ofereça uma densidade compacta para especialistas diários; mantenha alvos com pelo menos 24 px. [S: WCAG 2.5.8; P: Carbon row sizes]
Seleção e ações em massa
- Modo em massa é explícito: checkboxes de linha, um checkbox de cabeçalho com estado indeterminado e uma barra de ferramentas que nomeia a contagem ("3 selecionados"). [P: Carbon; S: Mac HIG 1992 pp. 64-66 (estado misto)]
- "Selecionar tudo" informa seu escopo: todos os 50 nesta página, ou todos os 1.204 correspondentes ao filtro. Nunca subentender um quando a pessoa espera o outro. [J]
- Uma ação em massa informa objeto, contagem e escopo antes de executar, relata resultados por item depois ("1.198 arquivados, 6 falharam: ver") e é desfeita ou pré-visualizável. [S: fundamento sec. 1; J]
- A seleção sobrevive à paginação e filtragem apenas se a barra de ferramentas mostrar que sim. Caso contrário, limpe-a visivelmente. [J]
Detalhe e edição
- Abra registros onde o contexto é mantido. Um painel lateral é adequado para consulta durante edição; uma página completa é adequada para registros profundos; evite modais para edição, pois escondem registros vizinhos. [P: NN/g data tables]
- A visualização de detalhes começa com identidade e status em palavras, depois os campos com os quais as pessoas agem, depois o histórico. [S: fundamento; J]
- Um modelo de salvamento por superfície. Toggles se aplicam imediatamente; texto e edições de vários campos salvam explicitamente; nunca ambos em um formulário. [S: Primer saving; fundamento]
- Avise antes de sair com alterações não salvas e salve rascunhos automaticamente onde a perda seria prejudicial. [S: Primer saving]
- Mostre quem alterou o quê e quando em registros compartilhados, com um timestamp absoluto, e detecte escritas obsoletas (versão ou ETag) em vez de sobrescrever silenciosamente. [S: Mac HIG 1992 pp. 27-31; AIP-154 em fundamento]
- Formulários dentro do app seguem
form-design.
UI otimista, desfazer e confirmação
- Otimista apenas quando o servidor quase nunca recusa e a ação é reversível: marcar como lido, favoritar, reordenar. Mostre o estado pendente distintamente do confirmado, reverta visivelmente em caso de falha com o motivo e nunca mostre otimisticamente dinheiro movido, mensagens enviadas ou registros excluídos como concluídos. [S: Mac HIG 1992 p. 182 (inserido, verificado, em vigor); P: React useOptimistic]
- Prefira desfazer em vez de confirmação para ações reversíveis: arquivar, mover, excluir para a lixeira. Mantenha o desfazer acessível após o toast desaparecer (Desfazer no histórico do item, visualização da Lixeira, atalho do menu Editar). [P: Raskin 2007; NN/g user control]
- Confirme apenas ações severas, irreversíveis ou inesperadas, nomeando o alvo e o efeito; digitar para confirmar para as raras catastróficas (excluir workspace). [S: fundamento sec. 1; E: Bravo-Lillo 2013 via fundamento]
- Exclusão suave no servidor, com um período de retenção informado, para que o desfazer seja real e não uma ilusão do cliente. [S: AIP-164 em fundamento]
Estados vazio, carregamento, erro e sem permissão
- Distinga quatro vazios: primeiro uso (explique o objeto e ofereça a ação de criar), sem resultados (nomeie os filtros e ofereça para limpá-los), limpo (tudo feito) e erro (o que falhou, o que fazer). Nunca mostre "Nenhum registro" antes dos dados serem carregados. [P: NN/g empty states; S: Primer empty states]
- Carregamento nomeia o que está carregando, em texto, dentro da região que substitui; mantenha o shell e a navegação utilizáveis. [S: fundamento]
- Sem permissão é um estado, não um recurso oculto. Mostre a ação desabilitada com o motivo e quem pode concedê-la ("Apenas administradores do workspace podem exportar. Pergunte a Maya Chen.") ou uma página explicando o acesso e como solicitá-lo. Esconda apenas o que a pessoa não deve saber que existe. [S: Mac HIG 1992 pp. 318-321 (itens desabilitados se explicam); J]
- As verificações de permissão acontecem no servidor. Esconder um botão é apresentação, não autoridade. [S: fundamento]
- Verifique a permissão antes da existência nas respostas, para que um 404 versus 403 não vaze dados. [S: AIP-193 em fundamento]
Configurações
- Coloque as configurações próximas ao que afetam quando são alteradas durante o trabalho (densidade de visualização, escolha de coluna, filtros); a área de configurações contém opções raramente alteradas e de todo o app. [S: Apple HIG Settings]
- Separe configurações pessoais das do workspace e rotule cada uma com de quem é e a quem afeta ("Aplica-se a todos na Acme"). [J]
- Agrupe pela tarefa da pessoa, não pela tabela do banco de dados, com pesquisa quando as configurações excederem uma ou duas telas. [J]
- Menos configurações. Uma preferência alterada muitas vezes por sessão é um controle ausente, não uma configuração. [S: Mac HIG 1992 p. 38; Apple HIG Settings]
- Configurações perigosas ficam em uma zona separada e rotulada com texto de consequência e confirmação (transferir propriedade, excluir workspace). [P: GitHub; J]
Onboarding
- Ensine no contexto, não com um tour. A NN/g descobriu que tutoriais em formato de cartas não melhoraram o desempenho das tarefas; dicas contextuais e bons estados vazios fazem o ensino. Se houver um tour, mantenha-o curto e pulável. [P: NN/g onboarding]
- Leve as pessoas ao primeiro resultado real rapidamente; os dados de exemplo são marcados como exemplo em todos os lugares onde aparecem e removíveis em uma ação. [J; fundamento regra da verdade]
- Uma lista de verificação de configuração é persistente e honesta: reflete o estado real, pode ser dispensada e é acessível depois. [J]
Teclado e paleta de comandos
- Uma paleta de comandos é um acelerador, não o menu. Todo comando nela também existe na UI visível. Ela lista atalhos ao lado dos comandos, então os ensina. [S: Windows menus guidance (não torne atalhos a única forma); P: VS Code UX guidelines]
- Atalhos de tecla única podem ser desativados ou remapeados (WCAG 2.1.4), nunca disparam dentro de campos de texto e não sobrescrevem atalhos do navegador ou do SO. [S: WCAG 2.1.4; Apple keyboards]
- Uma folha de ajuda de atalhos (frequentemente
?) lista todos os atalhos no escopo atual. [J]
Para o leitor agente
- Uma função de serviço por ação, compartilhada pelo botão, pela paleta, pela API e por qualquer ferramenta. [S: fundamento agent-surfaces 7]
- Controles de linha são nomeados a partir de IDs do sistema, não de texto de terceiros; o texto de terceiros nas células são dados. [J]
- Coleções informam seu tamanho e intervalo verdadeiros em texto visível; filtros e ordenação estão na URL. [J]
- Resultados duram mais que toasts: a linha alterada, um registro de atividade, uma entrada de desfazer. [J]
- Tenancy e ambiente são legíveis em texto em todas as páginas, para que um agente não aja em produção pensando que é staging. [J]
Ordem de construção
- Tabela de objetos por verbos por funções; rotas e URLs para cada visualização.
- Shell: navegação, indicador de tenant e ambiente, títulos,
h1s. - Visualizações de lista com formatos de dados reais: paginação no servidor, ordenação, filtro, tudo na URL.
- Visualizações de detalhes, modelo de salvamento, tratamento de concorrência.
- Toda ação de mutação através de um serviço: pendente, sucesso, falha, desfazer ou confirmar por escada de custo de erro.
- Estados vazio, carregamento, erro e sem permissão para cada visualização.
- Ações em massa, atalhos de teclado, paleta.
- Configurações e onboarding por último; estilo para este leitor (
brand-identityé responsável pela aparência).
Verificar
node <interface-guidelines>/scripts/audit.mjs <url|dist> --canary "<texto de terceiro de exemplo>"em cada rota principal, incluindo uma lista com filtros aplicados e uma visualização de detalhe.- Formulários dentro do app:
node <form-design>/scripts/form-check.mjs <url>. - Teste de recarregamento: aplique filtros, ordene, vá para a página 3, abra um registro; recarregue e cole a URL em uma nova sessão. Tudo retorna.
- Teste de função: faça login como cada função. Toda ação oculta ou desabilitada tem um motivo; o servidor rejeita chamadas proibidas feitas diretamente.
- Teste de tamanho: 0, 1, 25 e 10.000+ linhas; o nome mais longo; um filtro que não corresponde a nada.
- Teste de falha: faça o servidor rejeitar uma ação otimista e uma ação em massa parcialmente; a UI reverte e relata por item.
- Teste de agente: usando apenas o snapshot de acessibilidade, encontre um registro específico por filtro, altere-o, confirme o resultado de um novo snapshot, desfaça-o.
Armadilhas
- Filtros e ordenação mantidos apenas no estado do componente.
- "Selecionar tudo" que seleciona a página enquanto a barra de ferramentas sugere tudo.
- Exclusão otimista sem reversão e sem desfazer.
- Rolagem infinita em uma tabela administrativa; um total computado a partir de linhas carregadas.
- Ações de linha apenas ao passar o mouse; cinco botões "Editar" idênticos.
- "Nenhum dado" piscando antes do carregamento; um estado vazio genérico para todas as causas.
- Ocultar recursos de uma função sem explicação, ou mostrá-los e falhar ao clicar com "Proibido".
- Um alternador de tenant que mantém a seleção do tenant antigo, ou nenhum tenant visível.
- Um tour do produto em vez de um estado vazio utilizável.
- Páginas de configurações que espelham tabelas de banco de dados.
Referências
| Arquivo | Leia quando |
|---|---|
references/patterns.md | Detalhamento sobre modelos de navegação, anatomia de tabelas, fluxos de ação em massa, estados de permissão, tenancy, mecânicas otimistas e de desfazer, design de paleta e as fontes por trás desta skill |