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
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-busye mantém dimensão estável. - Foco visível é obrigatório.
Regras
- Uma ação primária por superfície.
- Ações lado a lado mantêm mesma altura.
- Destructive precisa deixar consequência explícita.
- Cor não substitui texto.
- Loading só aparece quando há espera real.
Last updated on