Spinner

Feedbackserver safe

Indicador de carregamento em SVG animado, sem estado e sem Radix, em tres tamanhos e com a variante da marca: o touro da TRDR escalando a ladeira.

Carregando

Instalação

Recebe correções por update de versão. O caminho recomendado.

npm i @trdr/ui

import { Spinner } from "@trdr/ui/spinner"

Uso

import { Spinner } from "@trdr/ui/spinner"

export function Exemplo() {
  return <Spinner />
}

Variantes

GrupoValoresPadrão
variant
defaultbull
default
size
smdefaultlg
default

Props

SpinnerPropsestende React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof spinnerVariants>
PropTipoDescrição
label?stringTexto lido pelo leitor de tela enquanto o spinner esta visivel.

Quando usar

Use o spinner para indicar que uma acao esta em andamento e nao ha um progresso mensuravel para mostrar: carregar um botao apos o clique, buscar dados que respondem em poucos segundos, atualizar uma lista. Ele comunica "algo esta acontecendo", nao "quanto falta".

Quando nao usar

Nao use spinner para operacoes longas ou quando o percentual de conclusao e conhecido: nesse caso use o Progress determinado, que da ao usuario uma nocao real de tempo restante. Nao empilhe varios spinners na mesma tela: se multiplas areas carregam ao mesmo tempo, prefira um unico indicador global ou skeletons no lugar de cada bloco.

Anatomia

  • Raiz (data-slot="spinner"): um <span> com role="status", sem estado e sem Radix. Carrega a cor de destaque da marca (text-content-brand) por padrao, herdada pelo icone via currentColor.
  • Icone (data-slot="spinner-icon"): o <svg> que gira, marcado com aria-hidden="true" porque a informacao relevante para o leitor de tela vive no texto oculto, nao no desenho.
  • Texto acessivel (data-slot="spinner-label"): um texto sr-only (escondido visualmente, presente na arvore de acessibilidade), com o valor padrao "Carregando" e customizavel pela prop label.

Tamanhos

  • sm (size-4): uso dentro de texto corrido ou ao lado de um rotulo pequeno.
  • default (size-6): o tamanho geral, alinhado ao icone padrao do Button.
  • lg (size-12): espera de tela cheia ou de painel inteiro.

Na variante bull cada chave rende o dobro (size-8, size-12 e size-20), porque abaixo de uns 32px o simbolo vira mancha e a caminhada nao le. E a mesma prop, com desenho maior.

Variantes

  • default: o circulo que gira. E o indicador de trabalho, e serve em qualquer lugar.
  • bull: o simbolo da TRDR escalando a propria ladeira, com as pernas alternando.

A variante bull custa atencao: ela e uma peca de marca em movimento, entao o lugar dela e a espera que o usuario ja sabe que vai demorar um pouco, como abrir a mesa ou carregar um painel inteiro. Dentro de um botao ou de uma linha de tabela use o default, senao o desenho compete com a acao que o usuario acabou de tomar.

Como o touro anda

Vale saber, porque muda o que da para customizar: o symbol.svg de @trdr/brand nao tem pernas como formas proprias, so blocos preenchidos e a diagonal. A animacao nao redesenhou nada. Os tres grupos do SVG (.trdr-bull-body, .trdr-bull-front, .trdr-bull-hind) desenham os MESMOS paths, e cada um mostra so a sua fatia via clip-path; o que gira e a fatia. Em repouso as tres remontam o simbolo oficial pixel a pixel.

Os paths vem gerados de @trdr/brand por scripts/build-bull-paths.mjs, entao trocar o simbolo da marca reemite o spinner. Se o desenho mudar de verdade, o script para e pede revisao: os recortes sao coordenadas casadas com este desenho, nao valores genericos.

Acessibilidade

O role="status" faz o leitor de tela anunciar o texto oculto assim que o spinner aparece na tela, sem precisar de configuracao adicional do consumidor. O <svg> fica fora da arvore de acessibilidade (aria-hidden) porque um desenho girando nao carrega significado por si so. A animacao de rotacao respeita motion-reduce: com a preferencia de menos movimento ativa no sistema, o spinner fica estatico, e o estado de carregamento continua comunicado pelo texto, nao pelo movimento.

Na variante bull a preferencia de menos movimento para as pernas na pose neutra, que e o simbolo oficial, e deixa so um respiro lento no corpo. Ela nao some por completo de proposito: sem nenhum movimento o desenho viraria um logo parado no meio da tela, que nao comunica espera.

Slots e tokens

Todo elemento renderizado carrega um data-slot para estilizar partes internas sem depender de classe da biblioteca. Os tokens listados são extraídos do código fonte.

[data-slot="spinner"][data-slot="spinner-icon"][data-slot="spinner-label"]
1 tokens usados
text-content-brand