Przejdź do treści

Warianty

variants() to port PHP CVA (Class Variance Authority). Zamienia deklaratywną konfigurację — klasę bazową, nazwane osie wariantów i wartości domyślne — w funkcję, która mapuje propsy na ciąg klas. Użyj go, gdy komponent ma łączące się wymiary stylu, takie jak rozmiar i przeznaczenie.

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() zwraca callable; wywołaj ją z tablicą propsów (lub bez argumentów), aby uzyskać rozwiązany ciąg.

Konfiguracja

Klucz Typ Przeznaczenie
base string Klasy stosowane do każdego wyniku.
variants array Nazwane osie, z których każda mapuje nazwy wartości na ciągi klas.
compoundVariants array Ciągi klas stosowane tylko wtedy, gdy łączy się kilka wartości wariantów.
defaultVariants array Wartość dla każdej osi używana, gdy pominięto prop.

Wszystkie klucze są opcjonalne. Bez variants wynikiem jest base oraz dowolne własne klasy:

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

Wartość wariantu może być mapowana na null, aby niczego nie dodawać — przydatne jako jawna opcja „wyłączona” w danej osi.

Wywoływanie wyniku

Przekaż pojedynczą tablicę propsów, jak w CVA. Klucze odpowiadają nazwom osi wariantów; pominięte osie przyjmują wartość 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'

Klucz class (i jego alias className) jest dodawany na końcu wyniku. Samo dodanie nie rozwiązuje konfliktów — zobacz poniższy wzorzec komponentu.

compoundVariants

Każdy element w compoundVariants to tablica warunków wariantów oraz class (lub className) z dodatkowymi klasami. Klasy są stosowane tylko wtedy, gdy wszystkie warunki pasują do rozwiązanych propsów, łącznie z wartościami domyślnymi. Wartość warunku może być pojedynczym ciągiem lub tablicą ciągów, aby dopasować dowolną z kilku wartości.

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'

Wzorzec komponentu

variants() tylko dodaje class; aby umożliwić wywołującym rzeczywiste nadpisanie domyślnych wariantów, opakuj wynik w cn(), aby konflikty były rozstrzygane na korzyść wywołującego.

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

Pamięć podręczna static $styles tworzy konfigurację wariantów raz i ponownie wykorzystuje ją podczas kolejnych wywołań.

compose()

compose() łączy kilka komponentów wariantowych w jeden. Złożona funkcja przekazuje każdy prop do każdego komponentu, zbiera ich wyniki i dodaje dowolne 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'

Dzięki temu wielokrotnego użytku osie (odstępy, wysokość, układ) pozostają w osobnych definicjach i można je łączyć dla każdego komponentu.

Importy

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

Obie funkcje znajdują się w głównej przestrzeni nazw TailwindPHP i są dołączone do pakietu — to port PHP CVA autorstwa Joe Bella.