Hoppa till innehåll

Varianter

variants() är en PHP-port av CVA (Class Variance Authority). Den omvandlar en deklarativ konfiguration — en bas, namngivna variantaxlar och standardvärden — till en anropsbar funktion som mappar props till en klasssträng. Använd den när en komponent har stilvarianter som storlek och avsikt som ska kombineras.

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() returnerar en callable; anropa den med en props-array (eller utan argument) för att få den lösta strängen.

Konfiguration

Nyckel Typ Syfte
base string Klasser som används i varje utdata.
variants array Namngivna axlar, där varje axel mappar värdenamn till klasssträngar.
compoundVariants array Klasssträngar som används endast när flera variantvärden kombineras.
defaultVariants array Värde per axel som används när en prop utelämnas.

Alla nycklar är valfria. Utan variants returneras base samt eventuella anpassade klasser:

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

Ett variantvärde kan mappas till null för att inte bidra med något — användbart som ett uttryckligt alternativ för att avmarkera en axel.

Anropa resultatet

Skicka in en enda props-array, enligt CVA-stil. Nycklarna motsvarar variantaxlarnas namn; utelämnade axlar använder defaultVariants som reservvärde.

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'

Nyckeln class (och dess alias className) läggs till sist i utdata. Att lägga till klasser löser inte i sig konflikter — se komponentmönstret nedan.

compoundVariants

Varje post i compoundVariants är en array med variantvillkor och ett class (eller className) med extra klasser. Klasserna används endast när alla villkor stämmer med de lösta propsen, inklusive standardvärden. Ett villkorsvärde kan vara en enda sträng eller en array med strängar som matchar ett av flera värden.

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'

Komponentmönster

variants() lägger bara till class; om anropare verkligen ska kunna åsidosätta variantstandardvärden omsluter du utdata med cn() så att konflikter löses till anroparens fördel.

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

Cachen static $styles bygger variantkonfigurationen en gång och återanvänder den vid efterföljande anrop.

compose()

compose() slår ihop flera variantkomponenter till en. Den sammansatta anropsbara funktionen skickar varje prop vidare till alla komponenter, samlar in deras utdata och lägger till eventuella 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'

Detta håller återanvändbara axlar (avstånd, höjd, layout) i separata definitioner och kombinerar dem per komponent.

Importer

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

Båda finns i huvudnamnrymden TailwindPHP och följer med paketet — en PHP-port av CVA av Joe Bell.