Propósito
Iniciar una acción
Los botones disparan acciones: agregar al carrito, aplicar un cupón, confirmar una compra.
Mostrar jerarquía
Ocho jerarquías ayudan a identificar la acción principal y las secundarias en cada pantalla.
Cubrir los estados
Hover, active, foco, disabled y loading mantienen el comportamiento predecible.
Anatomía
Hacé clic en un número para ver las propiedades y los tokens de esa parte.
Configuración
Variante
La prop variant define colores, radio y peso de fuente, y comunica la jerarquía de la acción en la pantalla.
Acción principal de una sección. Una por bloque. Tamaño habitual: lg.
Tamaño
La prop size define alto, padding, gap, tipografía e ícono. Permite ajustar el peso visual de la acción a la densidad del layout.
Small: 36px de alto, tipografía 14px / 20px.
Forma
La prop shape es default (8 px) para acciones de compra y formularios, y pill solo en marketing.
Compra, formularios y Stepper.
Íconos
Un ícono (lucide) a la izquierda o a la derecha del texto refuerza el significado de la acción y hereda su color.
Cuando el ícono aporta claridad, por ejemplo un carrito antes de «Agregar».
Estado
Hover y foco los resuelve CSS. disabled y loading son props; active se muestra forzado.
Para acciones disponibles de inmediato. Probá hover, foco con Tab y click.
Ancho completo
La prop fullWidth estira el botón al ancho de su contenedor, para layouts apilados o angostos.
Para acciones en línea: se ajusta al contenido.
Props
| Prop | Tipo | Descripción |
|---|---|---|
| variant | "primary" | "add-to-cart" | "secondary" | "outline" | "neutral" | "inverse" | "outline-inverse" | "link" | Jerarquía. Por defecto primary. |
| size | "sm" | "md" | "lg" | "xl" | Tamaño. Si falta, el de cada jerarquía. |
| shape | "default" | "pill" | pill solo en marketing. |
| fullWidth | boolean | Ocupa todo el ancho del contenedor. |
| loading | boolean | Muestra spinner, mantiene el ancho y bloquea el click. |
| loadingText | string | Texto mientras carga. |
Tokens
| Variante | Token | Valor |
|---|---|---|
| Link | none | |
| Link | underline | |
| Forma | 8px | |
| Forma | 9999px | |
| Todas | 2px | |
| Todas | 2px | |
| Tamaño Small | 36px | |
| Tamaño Small | 8px | |
| Tamaño Small | 12px | |
| Tamaño Small | 6px | |
| Tamaño Small | 14px | |
| Tamaño Small | 20px | |
| Tamaño Small | 16px | |
| Tamaño Medium | 40px | |
| Tamaño Medium | 10px | |
| Tamaño Medium | 16px | |
| Tamaño Medium | 8px | |
| Tamaño Medium | 14px | |
| Tamaño Medium | 20px | |
| Tamaño Medium | 16px | |
| Tamaño Large | 44px | |
| Tamaño Large | 12px | |
| Tamaño Large | 20px | |
| Tamaño Large | 8px | |
| Tamaño Large | 14px | |
| Tamaño Large | 20px | |
| Tamaño Large | 20px | |
| Tamaño Extra large | 48px | |
| Tamaño Extra large | 12px | |
| Tamaño Extra large | 24px | |
| Tamaño Extra large | 8px | |
| Tamaño Extra large | 16px | |
| Tamaño Extra large | 24px | |
| Tamaño Extra large | 20px | |
| Primary | 600 | |
| Primary | 44px | |
| Primary | 32px | |
| Primary | 12px | |
| Add to cart | 500 | |
| Add to cart | 40px | |
| Secondary | 500 | |
| Secondary | 40px | |
| Secondary | 16px | |
| Outline | 500 | |
| Outline | 44px | |
| Outline | 16px | |
| Outline | 12px | |
| Neutral | 500 | |
| Neutral | 24px | |
| Inverse | 500 | |
| Inverse | 40px | |
| Inverse | 32px | |
| Outline inverse | rgba(255, 255, 255, 0.1) | |
| Outline inverse | rgba(255, 255, 255, 0.15) | |
| Outline inverse | rgba(255, 255, 255, 0.5) | |
| Outline inverse | 500 | |
| Outline inverse | 44px | |
| Outline inverse | 16px | |
| Link | 0px | |
| Link | 500 | |
| Todas | 0.5 | |
| Ghost | rgba(255, 255, 255, 0) | |
| Ghost | 500 | |
| Ghost | 0px | |
| Todas | #e30613 | |
| Primary | #e30613 | |
| Primary | #c20510 | |
| Primary | #9a040d | |
| Primary | #ffffff | |
| Primary | 8px | |
| Add to cart | #e30613 | |
| Add to cart | #c20510 | |
| Add to cart | #9a040d | |
| Add to cart | #ffffff | |
| Add to cart | 8px | |
| Secondary | #1a1a1a | |
| Secondary | #6b6b6b | |
| Secondary | #404040 | |
| Secondary | #ffffff | |
| Secondary | 8px | |
| Outline | #ffffff | |
| Outline | #fff1f2 | |
| Outline | #ffe1e3 | |
| Outline | #e30613 | |
| Outline | #e30613 | |
| Outline | 8px | |
| Neutral | #fafafa | |
| Neutral | #f5f5f5 | |
| Neutral | #e4e4e4 | |
| Neutral | 8px | |
| Inverse | #ffffff | |
| Inverse | #f5f5f5 | |
| Inverse | #e4e4e4 | |
| Inverse | #1a1a1a | |
| Inverse | 9999px | |
| Outline inverse | #ffffff | |
| Outline inverse | 9999px | |
| Todas | #f5f5f5 | |
| Todas | #d4d4d4 | |
| Todas | #d4d4d4 | |
| Todas | #d4d4d4 | |
| Ghost | #1a1a1a | |
| Ghost | #1a1a1a | |
| Ghost | #6b6b6b | |
| Ghost | #525252 | |
| Outline | #c20510 | |
| Outline | #9a040d | |
| Neutral | #1a1a1a | |
| Neutral | #e4e4e4 | |
| Link | #e30613 | |
| Link | #c20510 | |
| Link | #9a040d | |
| Ghost | #d4d4d4 |
Tokens por variante
Se leen en vivo del paquete de tokens. Pasá el mouse por un color para ver el token.
| Variante | Fondo | Hover | Active | Texto | Borde |
|---|---|---|---|---|---|
| Primary | #e30613 | #c20510 | #9a040d | #ffffff | — |
| Add to cart | #e30613 | #c20510 | #9a040d | #ffffff | — |
| Secondary | #1a1a1a | #6b6b6b | #404040 | #ffffff | — |
| Outline | #ffffff | #fff1f2 | #ffe1e3 | #e30613 | #e30613 |
| Neutral | #fafafa | #f5f5f5 | #e4e4e4 | #1a1a1a | #e4e4e4 |
| Inverse | #ffffff | #f5f5f5 | #e4e4e4 | #1a1a1a | — |
| Outline inverse | — | rgba(255, 255, 255, 0.1) | rgba(255, 255, 255, 0.15) | #ffffff | rgba(255, 255, 255, 0.5) |
| Link | — | — | — | #e30613 | — |
Tokens por tamaño
| Tamaño | Alto | Padding (y / x) | Gap | Tipografía | Ícono |
|---|---|---|---|---|---|
| Small | 36px | 8px / 12px | 6px | 14px / 20px | 16px |
| Medium | 40px | 10px / 16px | 8px | 14px / 20px | 16px |
| Large | 44px | 12px / 20px | 8px | 14px / 20px | 20px |
| Extra large | 48px | 12px / 24px | 8px | 16px / 24px | 20px |
Estados
Estados forzados con clases solo para mostrarlos fijos. Los botones reales responden a hover, foco con Tab y click.
| Variante | default | hover | active | focus | disabled |
|---|---|---|---|---|---|
| Primary | |||||
| Add to cart | |||||
| Secondary | |||||
| Outline | |||||
| Neutral | |||||
| Inverse | |||||
| Outline inverse | |||||
| Link |
Uso
import { Button, buttonClasses } from "@/components/ui/button"
<Button variant="add-to-cart">Button CTA</Button>
<Button size="lg" shape="pill">Button CTA</Button>
<Button loading loadingText="Procesando…">Button CTA</Button>
// Link con estilo de botón
<Link href="/productos" className={buttonClasses({ variant: "primary", shape: "pill" })}>Ver productos</Link>