
# Varianten

`variants()` is een PHP-port van [CVA (Class Variance Authority)](https://github.com/joe-bell/cva). 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()](https://tailwindphp.inline0.dev/nl/docs/class-utilities) 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.
