Lewati ke konten

Varian

variants() adalah port PHP dari CVA (Class Variance Authority). Fitur ini mengubah konfigurasi deklaratif — base, sumbu varian bernama, dan nilai default — menjadi fungsi yang memetakan props ke string kelas. Gunakan saat komponen memiliki dimensi gaya seperti ukuran dan tujuan yang perlu digabungkan.

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() mengembalikan callable; panggil dengan array props (atau tanpa argumen) untuk mendapatkan string yang telah diselesaikan.

Konfigurasi

Kunci Tipe Tujuan
base string Kelas yang diterapkan ke setiap keluaran.
variants array Sumbu bernama, masing-masing memetakan nama nilai ke string kelas.
compoundVariants array String kelas yang diterapkan hanya saat beberapa nilai varian digabungkan.
defaultVariants array Nilai untuk tiap sumbu yang digunakan jika prop tidak diberikan.

Semua kunci bersifat opsional. Tanpa variants, hasilnya mengembalikan base beserta kelas kustom apa pun:

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

Nilai varian dapat dipetakan ke null agar tidak menyumbangkan apa pun — berguna sebagai opsi eksplisit "unset" pada suatu sumbu.

Memanggil hasilnya

Berikan satu array props, seperti pada CVA. Kunci harus cocok dengan nama sumbu varian; sumbu yang tidak diberikan menggunakan 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'

Kunci class (dan aliasnya className) ditambahkan di akhir keluaran. Penambahan saja tidak menyelesaikan konflik — lihat pola komponen di bawah.

compoundVariants

Setiap entri dalam compoundVariants berupa array kondisi varian beserta class (atau className) kelas tambahan. Kelas tersebut diterapkan hanya jika setiap kondisi cocok dengan props yang telah diselesaikan, termasuk nilai default. Nilai kondisi dapat berupa satu string atau array string untuk mencocokkan beberapa nilai.

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'

Pola komponen

variants() hanya menambahkan class; agar pemanggil benar-benar dapat meng-override nilai default varian, bungkus keluarannya dengan cn() agar konflik diselesaikan dengan mengutamakan pemanggil.

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

Cache static $styles menyusun konfigurasi varian sekali dan menggunakannya kembali pada pemanggilan berikutnya.

compose()

compose() menggabungkan beberapa komponen varian menjadi satu. Fungsi gabungan meneruskan setiap prop ke semua komponen, mengumpulkan keluarannya, lalu menambahkan class/className apa pun.

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'

Cara ini menjaga sumbu yang dapat digunakan kembali (jarak, elevasi, tata letak) dalam definisi terpisah, lalu menggabungkannya untuk tiap komponen.

Impor

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

Keduanya tersedia di namespace TailwindPHP utama dan disertakan dalam paket — port PHP CVA oleh Joe Bell.