본문으로 건너뛰기

변형

variants()는 PHP CVA(Class Variance Authority) 포트입니다. 기본 클래스, 이름이 지정된 변형 축, 기본값으로 구성된 선언형 설정을 호출 가능한 함수로 변환하며, 이 함수는 props를 클래스 문자열로 매핑합니다. 크기나 의도처럼 여러 스타일 속성을 조합하는 컴포넌트에 사용하세요.

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를 반환하며, props 배열(또는 인수 없음)을 전달하면 해석된 문자열을 얻습니다.

구성

키 유형 용도
base string 모든 출력에 적용되는 클래스.
variants array 이름이 지정된 축으로, 각 축은 값 이름을 클래스 문자열에 매핑합니다.
compoundVariants array 여러 변형 값이 조합될 때만 적용되는 클래스 문자열.
defaultVariants array prop을 생략했을 때 사용하는 축별 값.

모든 키는 선택 사항입니다. variants가 없으면 결과에 base와 사용자 지정 클래스가 포함됩니다:

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

변형 값에 null를 지정하면 아무것도 추가하지 않습니다. 축에서 명시적으로 "설정 해제" 옵션을 만들 때 유용합니다.

결과 호출

CVA 방식으로 props 배열 하나를 전달하세요. 키는 변형 축 이름과 일치하며, 생략한 축에는 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)로 구성됩니다. 모든 조건이 해석된 props와 일치할 때만 클래스가 적용되며, 기본값도 포함해 확인합니다. 조건 값은 단일 문자열이거나 여러 값 중 하나와 일치하도록 하는 문자열 배열일 수 있습니다.

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()는 여러 변형 컴포넌트를 하나로 병합합니다. 조합된 호출 가능 함수는 각 prop을 모든 컴포넌트에 전달하고, 각 출력을 모은 다음 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 네임스페이스에 있으며 패키지에 포함됩니다. Joe Bell이 만든 CVA의 PHP 포트입니다.