Status Button
StableRecipe do Button oficial que mostra o andamento de uma ação assíncrona onde a pessoa já está olhando: spinner enquanto roda, check quando termina e de volta ao rótulo, sem mudar de largura, com cada passo anunciado por uma região live. Preserva variantes, tamanhos e comportamento do primitive; enquanto ocupado continua focável — é aria-disabled, não disabled — e ignora novos cliques. Funciona sem controle, por um `onClick` assíncrono, ou controlado por `status`, como num formulário com `useActionState`.
Instalação
npx up-web-ds add status-buttonGera check para a biblioteca de ícones do projeto (components.json → iconLibrary).
Preview
Basic
Interaction
States
Success Label
Variants
Sizes
Failure
Form Action
Disabled
All states
Basic
Interaction
States
Success Label
Variants
Sizes
Failure
Form Action
Disabled
Usage
Props
Estende Omit< ButtonProps, 'onClick' | 'onError' | 'children' >. Aceita também os atributos padrão de um elemento React (282 não listados).
prop obrigatória.
Metadata
Notas de acessibilidade
Verificado em tests/e2e/status-button.spec.ts no Chromium desktop e mobile, em light e dark, com Axe sem violações WCAG 2.2 AA. Teclado verificado em navegador: o botão entra na sequência de Tab com foco visível, Enter dispara a ação, e durante a ação o foco permanece nele — ele fica aria-disabled em vez de disabled, então o foco não é devolvido à página no meio de um envio — e um segundo acionamento é ignorado, inclusive o submit de formulário. Leitor de tela verificado pela árvore de acessibilidade do navegador: o nome é o rótulo quando ocioso, "Carregando" enquanto roda e o successLabel (ou "Concluído") no sucesso. O primeiro spec mostrou que o Chrome não tira nome de dentro de um role="status", e o botão ficava sem nome enquanto carregava; agora os estados desenhados são aria-hidden, o nome vem de um span sr-only e o anúncio de uma região aria-live="polite" sempre montada, vazia quando ociosa, para que voltar ao rótulo não seja anunciado. aria-busy saiu, porque num ancestral da região ele pode segurar o anúncio que deveria sair. Os textos anunciados são props para produtos em outro idioma. A largura não muda em nenhum quadro do ciclo. Falha: com `onError` o erro é entregue à página e o botão volta a idle; sem ele o erro é relançado, para nunca ser engolido. Formulário com useActionState verificado em navegador. Touch verificado em 320px com emulação de toque: os alvos de estados, variantes, tamanhos e formulário atendem ao piso de 24x24 e o toque percorre o ciclo inteiro. Reduced motion verificado em navegador com prefers-reduced-motion: reduce — a troca vira um cross-fade sem deslocamento nem blur, o pulo do check some (useReducedMotion) e o giro do spinner, que é ambiente, para (motion-safe:animate-spin), restando o arco e o anúncio; o ciclo se completa igual. O upstream escalonava dez barras com um keyframe que nenhum projeto tem; o giro nativo do Tailwind dispensou uma capability para um spinner só.
Classificação
- Layer
- Recipe
- Domínio
- Domain-free (compartilhado)
- Categoria
- action
- Status
- Stable
Origem e distribuição
- Fonte
- Derived from ncdai / status-button
- Licença
- MIT
- Distribuição
- Interna
Acessibilidade
- Teclado: revisado
- Leitor de tela: revisado
- Touch: revisado
- Reduced motion: revisado
Dependências
- Pacotes
- motion
- Ícones
- check
- Construído sobre
- Button
- Usado por
- Nenhum ainda