
# Утилиты для классов

Создание атрибутов `class` в шаблонах предполагает объединение строк, переключение классов в зависимости от условий и предотвращение конфликтов между более поздними и ранними утилитами (`p-2` и `p-4` не должны оставаться одновременно). В JavaScript эта работа разделена между [clsx](https://github.com/lukeed/clsx) и [tailwind-merge](https://github.com/dcastil/tailwind-merge). TailwindPHP включает PHP-порты обеих библиотек, поэтому поведение будет таким же, но без цепочки инструментов Node.js и дополнительных пакетов Composer.

Три функции охватывают все случаи: `cn()` создает и устраняет конфликты, `merge()` только устраняет конфликты, а `join()` только объединяет строки.

## cn()

Рекомендуемая утилита. Сначала она создает классы с условной логикой, как clsx, а затем разрешает конфликты Tailwind с помощью tailwind-merge — поэтому при конфликте побеждает последняя утилита.

```php
use function TailwindPHP\cn;

// Conflicts are resolved — px-4 overrides px-2
cn('px-2 py-1', 'px-4');
// => 'py-1 px-4'

// Conditional classes via a key => bool array
cn('btn', ['btn-primary' => true, 'btn-disabled' => false]);
// => 'btn btn-primary'
```

### Допустимые аргументы

`cn()` принимает любое количество аргументов. Каждый аргумент разворачивается и фильтруется по правилам clsx:

| Аргумент | Поведение |
|----------|----------|
| `string` | Добавляется без изменений. |
| `int` / `float` | Преобразуется в строку и добавляется. |
| Вложенный массив | Каждый элемент обрабатывается рекурсивно. |
| Массив `key => bool` | Каждый ключ добавляется, если его значение истинно. |
| `null`, `false`, `0`, `''` | Игнорируются. |

```php
cn('flex', ['items-center' => true], ['p-4', ['gap-2']], null);
// => 'flex items-center p-4 gap-2'
```

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

`cn()` позволяет переопределять компонент: объедините собственные классы компонента с переданными вызывающим кодом, и конфликты разрешатся в пользу вызывающего кода.

```php
use function TailwindPHP\cn;

function Card(array $props = []): string {
    $class = cn(
        'rounded-lg border bg-card text-card-foreground shadow-sm',
        $props['class'] ?? null
    );
    return "<div class=\"{$class}\">" . ($props['children'] ?? '') . "</div>";
}

Card(['class' => 'p-6', 'children' => 'Content']);
// <div class="rounded-lg border bg-card text-card-foreground shadow-sm p-6">Content</div>
```

Для декларативных стилей компонентов с несколькими измерениями используйте `cn()` вместе с [variants()](https://tailwindphp.inline0.dev/ru/docs/class-utilities/variants).

## merge()

Только разрешение конфликтов — без условного создания. Передавайте строки классов; более поздние классы переопределяют ранние, если они задают одно и то же свойство. Используйте эту функцию, если входные данные уже представлены обычными строками.

```php
use function TailwindPHP\merge;

merge('px-2 py-1 bg-red-500', 'px-4 bg-blue-500');
// => 'py-1 px-4 bg-blue-500'

// Conflict resolution is variant-aware
merge('hover:bg-red-500', 'hover:bg-blue-500');
// => 'hover:bg-blue-500'
```

`cn()` — это `merge()`, построенная поверх clsx, поэтому используйте напрямую только `merge()`, если вам не нужен синтаксис условных массивов.

## join()

Простое объединение без разрешения конфликтов. Ложные значения отбрасываются, но конфликтующие утилиты сохраняются все. Используйте эту функцию, если уверены, что конфликтов нет, и хотите выбрать самый экономичный вариант.

```php
use function TailwindPHP\join;

join('foo', 'bar', null, 'baz');
// => 'foo bar baz'
```

## Какую функцию выбрать?

| Функция | Создает классы (условия, массивы) | Разрешает конфликты | Когда использовать |
|----------|:---:|:---:|----------|
| `cn()`    | да | да | По умолчанию — для создания строк классов, в которых возможны конфликты. |
| `merge()` | нет  | да | Входные данные — обычные строки; нужно только устранить конфликты. |
| `join()`  | да | нет  | Вы уверены, что конфликтов нет, и хотите свести обработку к минимуму. |

## Импорты

```php
use function TailwindPHP\cn;
use function TailwindPHP\merge;
use function TailwindPHP\join;
```

Все три функции находятся в основном пространстве имен `TailwindPHP` и входят в состав пакета. Это PHP-порты clsx (автор Luke Edwards) и tailwind-merge (автор Dany Castillo).
