Перейти до вмісту

Варіанти

variants() — порт PHP CVA (Class Variance Authority). Він перетворює декларативну конфігурацію — базові класи, названі осі варіантів і типові значення — на функцію, яка зіставляє властивості з рядком класів. Використовуйте його, коли параметри стилю компонента, як-от розмір і призначення, поєднуються.

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() повертає callable; викличте її з масивом властивостей або без аргументів, щоб отримати розв’язаний рядок.

Конфігурація

Ключ Тип Призначення
base string Класи, що застосовуються до кожного результату.
variants array Іменовані осі, кожна зіставляє назви значень із рядками класів.
compoundVariants array Рядки класів, які застосовуються лише в разі поєднання кількох значень варіантів.
defaultVariants array Значення для кожної осі, якщо відповідну властивість не передано.

Усі ключі необов’язкові. Якщо variants відсутній, результат містить base і користувацькі класи:

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

Значенню варіанта можна призначити null, щоб не додавати нічого — це зручно як явний варіант «не задано» для певної осі.

Виклик отриманої функції

Передайте один масив властивостей, як у CVA. Ключі мають відповідати назвам осей варіантів; для пропущених осей використовуються типові значення 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'

Ключ class (і його псевдонім className) додається в кінець результату. Саме додавання не розв’язує конфліктів — див. нижче шаблон компонента.

compoundVariants

Кожен елемент compoundVariants — це масив умов варіантів і class (або className) додаткових класів. Класи застосовуються, лише якщо всі умови відповідають розв’язаним властивостям, включно з типовими значеннями. Значення умови може бути окремим рядком або масивом рядків для зіставлення з кількома можливими значеннями.

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'

Шаблон компонента

variants() лише додає class; щоб викликачі могли справді перевизначати типові варіанти, обгорніть результат у cn(), щоб конфлікти розв’язувалися на користь викликача.

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

Кеш static $styles створює конфігурацію варіантів один раз і повторно використовує її під час наступних викликів.

compose()

compose() об’єднує кілька компонентів варіантів в один. Отримана функція передає кожну властивість усім компонентам, збирає їхні результати та додає всі 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'

Завдяки цьому багаторазово використовувані осі (інтервали, підняття, компонування) можна визначати окремо й поєднувати для кожного компонента.

Імпорт

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

Обидві функції містяться в основному просторі імен TailwindPHP та входять до пакета — це порт PHP CVA від Joe Bell.