COMPONENTES · 03 · CARREGAMENTOCarregamento e esqueleto
Esperar é parte da experiência de um sistema que lê planilha de orçamento com dezenas de milhares de linhas. O DS trata a espera como instrumento: ela informa o que está sendo carregado, quanto falta quando isso é conhecido, e que forma o resultado vai ter.
Por que o esqueleto imita o layout final, e não um retângulo genérico
Um retângulo cinza genérico só diz "aguarde". Um esqueleto com a forma real da tela diz onde cada coisa vai aparecer, e isso muda três coisas mensuráveis. Primeira: o olho começa a apontar para o lugar certo antes do dado chegar, então a leitura efetiva começa mais cedo. Segunda: a troca do esqueleto pelo conteúdo acontece sem salto de layout, porque as caixas já têm a altura definitiva; salto de layout é o que faz a pessoa perder a linha que estava lendo e clicar no botão errado. Terceira: a espera parece mais curta, porque o cérebro já reconhece a estrutura como familiar em vez de encarar uma tela vazia.
Daí as regras concretas desta página. O cabeçalho da tabela é texto real, não barra cinza, porque o nome das colunas é conhecido antes da consulta. O eixo do gráfico e os rótulos de mês são desenhados de verdade, pelo mesmo motivo. As linhas de parágrafo têm larguras diferentes, imitando a quebra natural do texto, e a última é curta. A coluna numérica tem bloco estreito e alinhado à direita, do tamanho de R$ 9.860.000, porque é isso que vai chegar ali. Esqueleto que não parece com o resultado é só ruído com aparência de progresso.
3.1 · SPINNER EM TRÊS TAMANHOS// 16px dentro de botão e de célula · 24px em cartão e painel · 40px em área de conteúdo vazia. Acima de 40px o spinner deixa de reportar estado e passa a decorar, e aí a barra de progresso é o componente certo.
// o spinner nunca aparece sozinho. Todo role="status" carrega um texto que diz o que está acontecendo, porque "girando" não é informação.
3.2 · BARRA DE PROGRESSO// determinada mostra percentual, indeterminada nunca mostra. Percentual inventado é pior que nenhum.
14.812 de 23.740 linhas · faltam 00:41
O servidor não estima o total, então a barra não finge que estima. Movimento reduzido: trilha hachurada estática.
3.3 · PROGRESSO CIRCULAR// o percentual no centro é Spline Sans Mono tabular. Tabular aqui não é preciosismo: sem largura de dígito fixa, o número tremeria de 9 para 10 a cada quadro.
// o laranja do anel do meio não é escolha estética. Contingência consumida acima de 80% é desvio, e desvio é o único assunto que ganha laranja neste sistema. Se os três anéis fossem laranja, nenhum deles chamaria atenção.
3.4 · ESQUELETO DE TEXTO E DE CARTÃO// a última linha é curta porque parágrafo de verdade termina no meio da linha. Cinco barras iguais denunciam esqueleto preguiçoso.
// código de fase curto em cima, título em duas linhas, corpo em três, seta no canto. É a planta do cartão, não um bloco.
// o esqueleto inteiro é aria-hidden="true". Quem usa leitor de tela recebe o aviso pela região viva ao lado, com o texto do que está carregando; ouvir "imagem, imagem, imagem" não ajudou ninguém.
Carregando 6 soluções do ciclo.
3.5 · ESQUELETO DE TABELA// cabeçalho é texto real. A largura de cada célula é a largura do dado que vem: descrição larga, numérico estreito e alinhado à direita.
| EAP | Descrição do serviço | Orçado | Medido | Desvio |
|---|---|---|---|---|
Carregando 5 de 312 linhas da EAP.
3.6 · ESQUELETO DE GRÁFICO// eixo, escala e rótulo de mês não dependem da consulta, então são desenhados antes. Só as colunas esperam. O quadro não muda de tamanho quando o dado chega.
Carregando medição mensal de 8 meses.
// não diz que é um gráfico, não diz quantos meses, e quando o dado chega o quadro muda de altura e empurra o resto da página para baixo.
3.7 · SHIMMER// a varredura é quase imperceptível de propósito. Ela existe para dizer "vivo, não travado", não para atrair o olho para o vazio.
// o brilho sai e entra um contorno de 1px. A caixa continua legível como "espaço reservado", sem nada em laço.
3.8 · CARREGANDO DENTRO DO BOTÃO// largura travada no rótulo mais longo. O botão não encolhe ao virar "Aprovando", então nada ao lado dele se move.
Pronto para aprovar.
// enquanto aria-busy="true", o botão fica disabled para impedir duplo envio, e a região viva anuncia início e fim. Sem a região viva, quem não vê o spinner não sabe que apertou.
3.9 · CARREGAMENTO DE PÁGINA INTEIRA// usado só na entrada da aplicação e na troca de obra, onde a tela toda muda. Navegação interna usa esqueleto, nunca cortina.
3.10 · FALLBACK DE MOVIMENTO REDUZIDO, PEÇA POR PEÇA| Peça | Padrão | Movimento reduzido | O que continua informando |
|---|---|---|---|
| Spinner 16, 24 e 40px | arco girando em 900ms | anel completo estático a 45% de opacidade | o texto ao lado, em região status |
| Barra determinada | largura anima em 420ms | largura salta direto para o valor | percentual em mono e contagem de linhas |
| Barra indeterminada | faixa de 38% desliza em laço | trilha cheia com hachura estática | aria-valuetext e o rótulo |
| Progresso circular | arco cresce em 800ms | arco já desenhado no valor final | percentual em mono no centro |
| Esqueleto de texto, cartão, tabela e gráfico | varredura de 5% a cada 1.6s | varredura removida, contorno de 1px | a forma do layout e a região viva |
| Botão carregando | spinner de 16px no lugar da seta | anel estático, rótulo troca para "Aprovando" | rótulo, aria-busy e região viva |
| Página inteira | régua se desenha em 800ms, count-up de 1.4s | régua já cheia, percentual salta | nome da obra, etapa e percentual |
FIM · 03 · CARREGAMENTO