Ga naar de inhoud

Varianten

variants() is een PHP-port van CVA (Class Variance Authority). Het zet een declaratieve configuratie — een basis, benoemde variantassen en standaardwaarden — om in een aanroepbare functie die props omzet in een classstring. Gebruik het wanneer een component stijlkenmerken heeft, zoals grootte en intentie, die gecombineerd worden.

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() geeft een callable terug; roep deze aan met een props-array (of zonder argumenten) om de opgeloste string te krijgen.

Configuratie

Sleutel Type Doel
base string Classes die op elke uitvoer worden toegepast.
variants array Benoemde assen, elk met een koppeling van waardennamen aan classstrings.
compoundVariants array Classstrings die alleen worden toegepast wanneer meerdere variantwaarden worden gecombineerd.
defaultVariants array Waarde per as die wordt gebruikt wanneer een prop ontbreekt.

Alle sleutels zijn optioneel. Zonder variants geeft het resultaat base terug, plus eventuele aangepaste classes:

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

Een variantwaarde kan worden ingesteld op null om niets bij te dragen — handig als expliciete optie voor 'niet ingesteld' op een as.

Het resultaat aanroepen

Geef één props-array door, zoals bij CVA. Sleutels komen overeen met de namen van je variantassen; ontbrekende assen vallen terug op 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'

De sleutel class (en het alias className ervan) wordt achteraan de uitvoer toegevoegd. Toevoegen alleen lost geen conflicten op — zie het componentpatroon hieronder.

compoundVariants

Elke invoer in compoundVariants is een array met variantvoorwaarden, plus een class (of className) met extra classes. De classes worden alleen toegepast als elke voorwaarde overeenkomt met de opgeloste props (inclusief standaardwaarden). Een voorwaarde kan één string of een array met strings zijn die overeenkomen met een van meerdere waarden.

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'

Componentpatroon

variants() voegt alleen class toe; om aanroepers de standaardwaarden van varianten echt te laten overschrijven, plaats je de uitvoer in cn() zodat conflicten in het voordeel van de aanroeper worden opgelost.

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']);

De static $styles-cache bouwt de variantconfiguratie één keer op en hergebruikt die bij volgende aanroepen.

compose()

compose() voegt meerdere variantcomponenten samen tot één geheel. De samengestelde aanroepbare functie geeft elke prop door aan elke component, verzamelt hun uitvoer en voegt eventuele class/className toe.

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'

Zo blijven herbruikbare assen (afstand, verhoging, indeling) in afzonderlijke definities staan en kunnen ze per component worden gecombineerd.

Imports

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

Beide bevinden zich in de hoofdnamespace TailwindPHP en zijn gebundeld met het pakket — een PHP-port van CVA door Joe Bell.