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;
    }
  }
Autor
Ángel Julián
Sitio web