Saltar al contenido

Variantes

variants() es una implementación PHP de CVA (Class Variance Authority). Convierte una configuración declarativa —una clase base, ejes de variantes con nombre y valores predeterminados— en una función invocable que asigna las propiedades a una cadena de clases. Úsela cuando un componente tenga dimensiones de estilo combinables, como el tamaño y la intención.

PHP
use function TailwindPHP\variants;

$button = variants([
    'base' => 'btn font-semibold border rounded',
    'variants' => [
        'intent' => [
            'primary'   => 'bg-blue-500 text-white',
            'secondary' => 'bg-gray-200 text-gray-800',
        ],
        'size' => [
            'sm' => 'text-sm px-2 py-1',
            'md' => 'text-base px-4 py-2',
        ],
    ],
    'defaultVariants' => [
        'intent' => 'primary',
        'size'   => 'md',
    ],
]);

$button();
// => 'btn font-semibold border rounded bg-blue-500 text-white text-base px-4 py-2'

variants() devuelve una callable; llámela con una matriz de propiedades (o sin argumentos) para obtener la cadena resuelta.

Configuración

Clave Tipo Finalidad
base string Clases que se aplican a todos los resultados.
variants array Ejes con nombre, cada uno asigna nombres de valores a cadenas de clases.
compoundVariants array Cadenas de clases que se aplican solo cuando se combinan varios valores de variantes.
defaultVariants array Valor de cada eje que se usa cuando se omite una propiedad.

Todas las claves son opcionales. Sin variants, el resultado devuelve base más las clases personalizadas:

PHP
$x = variants(['base' => 'box']);
$x();                          // => 'box'
$x(['class' => 'p-4']);        // => 'box p-4'

Un valor de variante puede asignarse a null para no aportar nada; es útil como opción explícita «sin valor» en un eje.

Llamar al resultado

Pase una única matriz de propiedades, como en CVA. Las claves deben coincidir con los nombres de los ejes de variantes; los ejes omitidos usan defaultVariants.

PHP
$button(['intent' => 'secondary']);
// => 'btn font-semibold border rounded bg-gray-200 text-gray-800 text-base px-4 py-2'

$button(['size' => 'sm', 'class' => 'mt-4']);
// => 'btn font-semibold border rounded bg-blue-500 text-white text-sm px-2 py-1 mt-4'

La clave class (y su alias className) se añade al final del resultado. Añadirla por sí sola no resuelve conflictos; consulte el patrón de componente más abajo.

compoundVariants

Cada entrada de compoundVariants es una matriz de condiciones de variantes más una class (o className) de clases adicionales. Las clases se aplican solo cuando todas las condiciones coinciden con las propiedades resueltas (incluidos los valores predeterminados). El valor de una condición puede ser una sola cadena o una matriz de cadenas para coincidir con varios valores posibles.

PHP
$button = variants([
    'base' => 'btn',
    'variants' => [
        'intent' => [
            'primary' => 'bg-blue-500',
            'warning' => 'bg-yellow-500',
            'danger'  => 'bg-red-500',
        ],
        'size' => ['sm' => 'text-sm', 'md' => 'text-base'],
    ],
    'compoundVariants' => [
        // Applies only when intent=primary AND size=md
        ['intent' => 'primary', 'size' => 'md', 'class' => 'uppercase'],
        // Applies when intent is warning OR danger
        ['intent' => ['warning', 'danger'], 'class' => '!border-red-500'],
    ],
    'defaultVariants' => ['intent' => 'primary', 'size' => 'md'],
]);

$button();
// => 'btn bg-blue-500 text-base uppercase'

$button(['intent' => 'danger']);
// => 'btn bg-red-500 text-base !border-red-500'

Patrón de componente

variants() solo añade class; para que quienes llaman al componente puedan sobrescribir realmente los valores predeterminados de las variantes, envuelva el resultado en cn() para que los conflictos se resuelvan a su favor.

PHP
use function TailwindPHP\variants;
use function TailwindPHP\cn;

function Button(array $props = []): string {
    static $styles = null;
    $styles ??= variants([
        'base' => 'inline-flex items-center justify-center rounded-md font-medium',
        'variants' => [
            'variant' => [
                'default' => 'bg-primary text-primary-foreground hover:bg-primary/90',
                'outline' => 'border border-input bg-background hover:bg-accent',
                'ghost'   => 'hover:bg-accent hover:text-accent-foreground',
            ],
            'size' => [
                'default' => 'h-10 px-4 py-2',
                'sm'      => 'h-9 px-3',
                'lg'      => 'h-11 px-8',
            ],
        ],
        'defaultVariants' => ['variant' => 'default', 'size' => 'default'],
    ]);

    // cn() merges variant output with custom classes, resolving conflicts
    $class = cn($styles($props), $props['class'] ?? null);
    $text  = $props['children'] ?? 'Button';
    return "<button class=\"{$class}\">{$text}</button>";
}

// The custom px-8 wins over the variant's px-3 via cn()
Button(['variant' => 'outline', 'size' => 'sm', 'class' => 'mt-4 px-8']);

La caché static $styles crea la configuración de variantes una vez y la reutiliza en las llamadas posteriores.

compose()

compose() combina varios componentes de variantes en uno. La función compuesta pasa cada propiedad a todos los componentes, recoge sus resultados y añade cualquier class/className.

PHP
use function TailwindPHP\variants;
use function TailwindPHP\compose;

$box   = variants(['variants' => ['shadow' => ['sm' => 'shadow-sm', 'md' => 'shadow-md']]]);
$stack = variants(['variants' => ['gap' => ['1' => 'gap-1', '2' => 'gap-2']]]);
$card  = compose($box, $stack);

$card(['shadow' => 'md', 'gap' => '2']);
// => 'shadow-md gap-2'

Así, los ejes reutilizables (espaciado, elevación, diseño) se mantienen en definiciones separadas y se combinan para cada componente.

Importaciones

PHP
use function TailwindPHP\variants;
use function TailwindPHP\compose;

Ambas están en el espacio de nombres principal TailwindPHP y se incluyen con el paquete: una implementación PHP de CVA, de Joe Bell.