Spinner
Atom
Spinner indica espera indeterminada. Ele diz que algo está acontecendo, mas não estima progresso.
Use Spinner em submissões, carregamento de seção ou operações assíncronas sem percentual conhecido. Para conteúdo com estrutura previsível, prefira Skeleton. Para avanço conhecido, use Progress.
Exemplos copiáveis
React
React
import * as React from "react"
type SpinnerSize = "sm" | "md" | "lg"
type PulsoSpinnerProps = {
size?: SpinnerSize
label?: string
}
const sizeClass: Record<SpinnerSize, string> = {
sm: "size-4 border-2",
md: "size-6 border-2",
lg: "size-8 border-[3px]",
}
export function PulsoSpinner({ size = "md", label = "Carregando" }: PulsoSpinnerProps) {
return (
<span role="status" aria-label={label} className="inline-flex items-center gap-2 text-[var(--fg-muted)]">
<span
aria-hidden="true"
className={[
"inline-block animate-spin rounded-full border-current border-r-transparent",
sizeClass[size],
].join(" ")}
/>
<span className="sr-only">{label}</span>
</span>
)
}<PulsoSpinner label="Carregando evidências" />Quando usar
- Submissão de formulário sem tempo estimado.
- Carregamento de seção sem estrutura conhecida.
- Operação curta enquanto resultado é confirmado.
Quando não usar
- Para progresso mensurável; use
Progress. - Para layout conhecido carregando; use
Skeleton. - Para estado persistente de sistema; use
Live IndicatorouAlert. - Para bloquear ação crítica sem texto explicativo.
Acessibilidade
- Use
role="status"e label específico. - Não dependa só do movimento para comunicar estado.
- Evite múltiplos spinners concorrendo na mesma superfície.
- Respeite redução de movimento.
Regras
- Spinner precisa de contexto textual ou label acessível.
- Não use spinner infinito sem fallback de erro.
- Em botão, preserve o tamanho do botão ao carregar.
- Não use spinner para mascarar latência longa; explique o que está acontecendo.
- O inverse deve manter contraste em light e dark, sem inverter para chip branco no dark.
Last updated on