Componente de botón con variantes para Tailwind CSS
Este componente de botón, creado con la capa @layer components
de Tailwind CSS, incluye estilos base, variantes de color (primary
, secondary
, danger
, dark
, etc.), tamaños (sm
, lg
) y soporte para pseudoelementos (::before
, ::after
) y pseudo-clases (:hover
, :focus
, :active
).
El diseño asegura consistencia visual con tamaños mínimos uniformes y permite personalizar fácilmente estados como botones deshabilitados o con estilos de contorno (outline
). Es una solución flexible, modular y lista para integrarse en cualquier proyecto con Tailwind CSS.
css code
.btn {
@apply
inline-flex
items-center
justify-center
font-semibold
py-2 px-4
rounded-lg
shadow
transition
focus:outline-none
focus:ring-2
focus:ring-offset-2
min-w-fit;
/* Estilo neutral claro (light) por defecto */
background-color: var(--color-neutral-light, #f5f5f5);
color: var(--color-neutral-dark, #333333);
border: 1px solid var(--color-neutral-border, #e0e0e0);
}
.btn {
/* Variantes normales */
&-primary {
background-color: var(--color-primary, #3b82f6);
color: var(--color-primary-contrast, #ffffff);
border-color: var(--color-primary, #3b82f6);
@apply hover:bg-opacity-90 focus:ring-[var(--color-primary)] focus:ring-opacity-50;
}
&-secondary {
background-color: var(--color-secondary, #6b7280);
color: var(--color-secondary-contrast, #ffffff);
border-color: var(--color-secondary, #6b7280);
@apply hover:bg-opacity-90 focus:ring-[var(--color-secondary)] focus:ring-opacity-50;
}
&-info {
background-color: var(--color-info, #0ea5e9);
color: var(--color-info-contrast, #ffffff);
border-color: var(--color-info, #0ea5e9);
@apply hover:bg-opacity-90 focus:ring-[var(--color-info)] focus:ring-opacity-50;
}
&-success {
background-color: var(--color-success, #22c55e);
color: var(--color-success-contrast, #ffffff);
border-color: var(--color-success, #22c55e);
@apply hover:bg-opacity-90 focus:ring-[var(--color-success)] focus:ring-opacity-50;
}
&-warning {
background-color: var(--color-warning, #f59e0b);
color: var(--color-warning-contrast, #000000);
border-color: var(--color-warning, #f59e0b);
@apply hover:bg-opacity-90 focus:ring-[var(--color-warning)] focus:ring-opacity-50;
}
&-danger {
background-color: var(--color-danger, #ef4444);
color: var(--color-danger-contrast, #ffffff);
border-color: var(--color-danger, #ef4444);
@apply hover:bg-opacity-90 focus:ring-[var(--color-danger)] focus:ring-opacity-50;
}
&-dark {
background-color: var(--color-dark, #111827);
color: var(--color-dark-contrast, #ffffff);
border-color: var(--color-dark, #111827);
@apply hover:bg-opacity-90 focus:ring-[var(--color-dark)] focus:ring-opacity-50;
}
/* Variantes outline */
&-outline {
background-color: transparent;
@apply hover:bg-opacity-10;
&-primary {
border-color: var(--color-primary);
color: var(--color-primary);
@apply hover:bg-opacity-10 focus:ring-[var(--color-primary)];
}
&-secondary {
border-color: var(--color-secondary);
color: var(--color-secondary);
@apply hover:bg-opacity-10 focus:ring-[var(--color-secondary)];
}
&-info {
border-color: var(--color-info);
color: var(--color-info);
@apply hover:bg-opacity-10 focus:ring-[var(--color-info)];
}
&-success {
border-color: var(--color-success);
color: var(--color-success);
@apply hover:bg-opacity-10 focus:ring-[var(--color-success)];
}
&-warning {
border-color: var(--color-warning);
color: var(--color-warning);
@apply hover:bg-opacity-10 focus:ring-[var(--color-warning)];
}
&-danger {
border-color: var(--color-danger);
color: var(--color-danger);
@apply hover:bg-opacity-10 focus:ring-[var(--color-danger)];
}
&-dark {
border-color: var(--color-dark);
color: var(--color-dark);
@apply hover:bg-opacity-10 focus:ring-[var(--color-dark)];
}
}
/* Tamaños */
&-sm {
@apply text-sm py-1 px-3;
}
&-lg {
@apply text-lg py-3 px-6;
}
&-xl {
@apply text-xl py-4 px-8;
}
/* Extra ancho */
&-wide {
@apply px-12;
}
/* Ancho completo */
&-block {
@apply w-full;
}
/* Deshabilitado */
&-disabled {
background-color: var(--color-disabled-bg, #d1d5db);
color: var(--color-disabled-text, #9ca3af);
cursor: not-allowed;
@apply opacity-50;
}
}