Skip to Content
ComponentsAtomsButton

Button

Atom

Button comunica ação. O texto precisa deixar claro o que acontece depois do clique.

Use Button para submissão, confirmação, navegação ou ação contextual. Em telas operacionais, hierarquia e tamanho precisam evitar ambiguidade: uma ação primária por superfície e ações lado a lado com altura consistente.

Exemplos copiáveis

React

import * as React from "react" type ButtonVariant = "primary" | "secondary" | "ghost" | "destructive" type ButtonSize = "sm" | "md" | "lg" | "icon" type PulsoButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & { variant?: ButtonVariant size?: ButtonSize isLoading?: boolean } const variantClass: Record<ButtonVariant, string> = { primary: "bg-[var(--primary)] text-[var(--primary-foreground)] hover:bg-[var(--primary-hover)]", secondary: "border border-[var(--border-strong)] bg-[var(--card)] text-[var(--fg)] hover:bg-[var(--muted)]", ghost: "bg-transparent text-[var(--fg-muted)] hover:bg-[var(--muted)] hover:text-[var(--fg)]", destructive: "bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:opacity-90", } const sizeClass: Record<ButtonSize, string> = { sm: "h-8 px-3 text-xs", md: "h-9 px-4 text-sm", lg: "h-10 px-5 text-sm", icon: "h-9 w-9 p-0", } export function PulsoButton({ variant = "primary", size = "md", isLoading = false, disabled, className, children, ...props }: PulsoButtonProps) { return ( <button type="button" disabled={disabled || isLoading} aria-busy={isLoading || undefined} className={[ "inline-flex items-center justify-center gap-2 rounded-[var(--radius-md)] font-medium", "transition-colors duration-[var(--motion-duration-fast)] ease-[var(--motion-easing)]", "focus-visible:outline focus-visible:outline-[var(--ring-width)] focus-visible:outline-offset-2 focus-visible:outline-[var(--ring)]", "disabled:cursor-not-allowed disabled:opacity-60", variantClass[variant], sizeClass[size], className, ].filter(Boolean).join(" ")} {...props} > {isLoading ? "Carregando…" : children} </button> ) }
<PulsoButton onClick={acknowledgeAlert}>Reconhecer alerta</PulsoButton> <PulsoButton variant="secondary">Ver evidências</PulsoButton> <PulsoButton variant="destructive">Encerrar caso</PulsoButton>

Quando usar

  • Confirmar ou submeter uma decisão.
  • Abrir uma próxima superfície clara.
  • Executar ação contextual em card, toolbar ou formulário.
  • Tornar uma ação operacional rastreável.

Quando não usar

  • Para estado persistente; use Toggle/Switch/Badge conforme o caso.
  • Para navegação textual secundária; use Link.
  • Para escolhas entre opções; use Radio/Select/Toggle Group.
  • Para ação destrutiva sem confirmação quando a consequência é alta.

Acessibilidade

  • Use verbo específico no label.
  • Botão icon-only precisa de aria-label.
  • Loading usa aria-busy e mantém dimensão estável.
  • Foco visível é obrigatório.

Regras

  1. Uma ação primária por superfície.
  2. Ações lado a lado mantêm mesma altura.
  3. Destructive precisa deixar consequência explícita.
  4. Cor não substitui texto.
  5. Loading só aparece quando há espera real.
Last updated on