Pular para o conteúdo
Faculdade PhorteDesign System

Button

Em andamento

O botão do sistema: executa uma ação no lugar — enviar, confirmar, abrir — ou, com href, vira um link com a mesma aparência. Tem oito variantes, três tamanhos e um estado de carregando que não tira o foco de quem apertou.

Função
Formulário e ação
Também chamado de
botão, CTA, chamada para ação, link de botão
Mora em
app/components/atoms/Button.tsx
Última mudança
2026-09-30

Prévia

A peça ao vivo, vinda da ficha, na largura escolhida. Em larguras fixas, ela roda num quadro do tamanho de uma tela de verdade.

Na largura da página: 0px

Variante Padrão, ao vivo — vem da ficha.Abrir sozinha(abre em outra aba)

Variantes na ficha

Lidas da ficha no build, na ordem do palco. Cada uma abre sozinha, sem o styleguide em volta — é o endereço que o palco carrega.

  1. Padrão
  2. Todas As Variantes
  3. secondary vs. neutral
  4. Todos Os Tamanhos
  5. Com ícones
  6. Carregando
  7. Desabilitado
  8. Largura Total
  9. forwardRef funciona
  10. Como link

Quando usar

Para a ação principal e as secundárias de uma tela ou formulário, e para navegar quando o destino precisa do peso visual de um botão ("Inscrever-se").

Faça

  • Para a ação de apoio ou de escolha ao lado de uma primária ("Escolher esta turma", "Ver grade"), o tonal: verde claro, com o fio verde por dentro (E127). Não é o secondary, que é o verde cheio de confirmar.
  • Escreva verbo e objeto, de uma a três palavras, sem ponto final: "Enviar inscrição".
  • Use href para navegar e o <button> para agir; o componente decide a tag.
  • Use isLoading durante o envio: o foco fica no botão, que anuncia aria-busy e ignora novos cliques.
  • Passe type="submit" explicitamente no botão que envia o formulário — o padrão aqui é type="button".
  • Dê aria-label ao botão que só tem ícone.

Evite

  • Envolver o Button num <a>: são dois elementos interativos aninhados, e o leitor anuncia os dois.
  • Desabilitar para dizer que falta algo: botão desabilitado sai do Tab e não explica o motivo. Se precisar, escreva ao lado o que falta.
  • Mais de um variant="primary" na mesma área — a ação principal deixa de ser principal.
  • Trocar secondary por cinza: secondary é verde desde setembro; o cinza é neutral.

Quando não usar. Para abrir uma lista de ações, use o Dropdown. Para escolher entre opções que ficam marcadas, o FilterGroup (filtro) ou o Radio (formulário). Para um link dentro de um parágrafo, texto com link — ou, no máximo, variant="link".

Nota de uso

variant="secondary" é verde desde a decisão de cor de setembro; o cinza de antes virou variant="neutral". Alvo mínimo de 44×44 px em todos os tamanhos — a única exceção documentada é variant="link", que é texto corrido dentro de um parágrafo. `href` vira link com a mesma aparência: use para navegar, e o <button> para agir — nunca <a><Button /></a>. isLoading não desabilita: o foco fica no botão, que anuncia aria-busy e ignora o clique. Texto: verbo e objeto, de uma a três palavras, sem ponto final — "Enviar inscrição", não "Clique aqui". Evite desabilitar: botão desabilitado não diz o que falta. Se precisar, escreva ao lado o motivo e como destravar.

Anatomia

As partes, na ordem em que o olho — e o teclado — passam.

  1. Ícone à esquerda — `leftIcon`, opcional e decorativo — o texto já descreve a ação.
  2. Rótulo — O `children`: verbo e objeto. Com `isLoading`, fica escondido do leitor e o `loadingLabel` é lido no lugar.
  3. Ícone à direita — `rightIcon`, opcional e decorativo.
  4. Indicador de carregando — Um `Loader2` que gira só com movimento liberado (`motion-safe:animate-spin`).

Estados

Os estados que a peça tem no código, e o que muda em cada um.

Estados da peça e o que muda em cada um
EstadoO que muda
PadrãoCor da variante; primary por padrão.
HoverTom mais escuro da variante (hover:bg-primary-dark, hover:bg-secondary-dark…); o tonal vira o verde cheio; link sublinha.
FocoAnel ring-ring de 2px com afastamento de 2px, igual nas oito variantes; só no teclado (focus-visible).
CarregandoisLoading: ícone girando, aria-busy="true" e aria-disabled="true", opacidade 50% e cursor de espera. Continua focável; o clique e o envio são bloqueados.
Desabilitadodisabled: opacidade 50%, sem ponteiro e fora da ordem de Tab. No modo link (href), disabled vira aria-disabled e o clique é bloqueado.

Comportamento

Como a peça reage em cada situação
SituaçãoO que acontece
Com `href`Renderiza next/link com a aparência de botão. Com target="_blank", o rel="noopener noreferrer" vem sozinho.
Sem `type` dentro de um formulárioNão envia: o padrão é type="button". Um "Cancelar" não dispara o envio por engano.
Clique ou tecla com `isLoading`Nada acontece — medido: Enter e Espaço não disparam o onClick.
Sem texto e sem `aria-label`Em desenvolvimento, o console avisa: "Button: botão sem texto visível precisa de aria-label."
`variant="link"`Perde a altura mínima de 44px e o preenchimento: é texto dentro de um parágrafo. É a única exceção de alvo documentada.

Relacionados