
# Varianten

`variants()` ist eine PHP-Portierung von [CVA (Class Variance Authority)](https://github.com/joe-bell/cva). Sie wandelt eine deklarative Konfiguration – eine Basis, benannte Variantenachsen und Standardwerte – in eine aufrufbare Funktion um, die Props einer Klassenzeichenfolge zuordnet. Verwende sie, wenn eine Komponente kombinierbare Stilmerkmale wie Größe und Ausrichtung hat.

```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()` gibt eine `callable` zurück. Rufe sie mit einem Props-Array oder ohne Argumente auf, um die aufgelöste Zeichenfolge zu erhalten.

## Konfiguration

| Schlüssel | Typ | Zweck |
|-----|------|---------|
| `base` | `string` | Klassen, die auf jede Ausgabe angewendet werden. |
| `variants` | `array` | Benannte Achsen, die jeweils Wertnamen Klassenzeichenfolgen zuordnen. |
| `compoundVariants` | `array` | Klassenzeichenfolgen, die nur bei bestimmten Kombinationen von Variantenwerten angewendet werden. |
| `defaultVariants` | `array` | Wert je Achse, der verwendet wird, wenn eine Prop fehlt. |

Alle Schlüssel sind optional. Ohne `variants` gibt das Ergebnis `base` sowie alle benutzerdefinierten Klassen zurück:

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

Ein Variantenwert kann auf `null` abgebildet werden, um nichts beizutragen – nützlich als explizite Option „nicht gesetzt“ für eine Achse.

## Ergebnis aufrufen

Übergib wie bei CVA ein einzelnes Props-Array. Die Schlüssel entsprechen den Namen deiner Variantenachsen; für ausgelassene Achsen werden `defaultVariants` verwendet.

```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'
```

Der Schlüssel `class` (und sein Alias `className`) wird ans Ende der Ausgabe angefügt. Das Anhängen allein löst keine Konflikte auf – siehe dazu das Komponenten-Muster weiter unten.

## compoundVariants

Jeder Eintrag in `compoundVariants` ist ein Array aus Variantenbedingungen und `class` (oder `className`) mit zusätzlichen Klassen. Die Klassen werden nur angewendet, wenn alle Bedingungen mit den aufgelösten Props übereinstimmen, einschließlich der Standardwerte. Ein Bedingungswert kann eine einzelne Zeichenfolge oder ein Array von Zeichenfolgen sein, um mehrere mögliche Werte abzudecken.

```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'
```

## Komponenten-Muster

`variants()` hängt nur `class` an. Damit Aufrufer Varianten-Standardwerte wirklich überschreiben können, umschließe die Ausgabe mit [cn()](https://tailwindphp.inline0.dev/de/docs/class-utilities), sodass Konflikte zugunsten des Aufrufers aufgelöst werden.

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

Der `static $styles`-Cache erstellt die Variantenkonfiguration einmal und verwendet sie bei weiteren Aufrufen wieder.

## compose()

`compose()` führt mehrere Variantenkomponenten zusammen. Die zusammengesetzte aufrufbare Funktion leitet jede Prop an alle Komponenten weiter, sammelt ihre Ausgaben und hängt beliebige `class`/`className` an.

```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'
```

So bleiben wiederverwendbare Achsen (Abstände, Erhebung, Layout) in separaten Definitionen und werden je Komponente kombiniert.

## Importe

```php
use function TailwindPHP\variants;
use function TailwindPHP\compose;
```

Beide befinden sich im Haupt-Namespace `TailwindPHP` und sind im Paket enthalten – es handelt sich um eine PHP-Portierung von CVA von Joe Bell.
