Button Component
Componente de botão versátil com múltiplas variações, estados e tamanhos. Construído com acessibilidade e responsividade em mente.
Baseado no shadcn/ui
Este componente utiliza a base do Button do shadcn/ui com extensões customizadas para casos de uso específicos e melhor experiência do usuário.
Variações Básicas
Variantes do Button
Diferentes estilos visuais para diferentes contextos
Tamanhos
Diferentes tamanhos para diferentes contextos de uso
Com Ícones
Botões com Ícones
Combinando ícones com texto para melhor UX
Estados Interativos
Estados e Loading
Botões com estados de loading e interações
Implementação
components/ui/button.tsxtsx
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }
Props API
Prop | Tipo | Default | Descrição |
---|---|---|---|
variant | string | "default" | Estilo visual do botão |
size | string | "default" | Tamanho do botão |
asChild | boolean | false | Renderiza como elemento filho |
disabled | boolean | false | Desabilita o botão |
Dica
Use a prop
asChild
quando quiser aplicar os estilos do Button a outro componente, como um Link do Next.js: <Button asChild><Link href="/page">Link</Link></Button>
Boas Práticas
✅ Faça
- • Use ícones para melhorar a compreensão da ação
- • Implemente estados de loading para ações assíncronas
- • Use variantes apropriadas para o contexto (destructive para deletar)
- • Mantenha textos concisos e descritivos
❌ Evite
- • Usar muitas variantes diferentes na mesma interface
- • Botões muito pequenos em dispositivos touch
- • Textos genéricos como "Clique aqui" ou "Botão"
- • Esquecer de implementar estados de loading