Утилиты для классов
Создание атрибутов class в шаблонах предполагает объединение строк, переключение классов в зависимости от условий и предотвращение конфликтов между более поздними и ранними утилитами (p-2 и p-4 не должны оставаться одновременно). В JavaScript эта работа разделена между clsx и tailwind-merge. TailwindPHP включает PHP-порты обеих библиотек, поэтому поведение будет таким же, но без цепочки инструментов Node.js и дополнительных пакетов Composer.
Три функции охватывают все случаи: cn() создает и устраняет конфликты, merge() только устраняет конфликты, а join() только объединяет строки.
cn()
Рекомендуемая утилита. Сначала она создает классы с условной логикой, как clsx, а затем разрешает конфликты Tailwind с помощью tailwind-merge — поэтому при конфликте побеждает последняя утилита.
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, '' |
Игнорируются. |
cn('flex', ['items-center' => true], ['p-4', ['gap-2']], null);
// => 'flex items-center p-4 gap-2'
Шаблон компонента
cn() позволяет переопределять компонент: объедините собственные классы компонента с переданными вызывающим кодом, и конфликты разрешатся в пользу вызывающего кода.
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().
merge()
Только разрешение конфликтов — без условного создания. Передавайте строки классов; более поздние классы переопределяют ранние, если они задают одно и то же свойство. Используйте эту функцию, если входные данные уже представлены обычными строками.
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()
Простое объединение без разрешения конфликтов. Ложные значения отбрасываются, но конфликтующие утилиты сохраняются все. Используйте эту функцию, если уверены, что конфликтов нет, и хотите выбрать самый экономичный вариант.
use function TailwindPHP\join;
join('foo', 'bar', null, 'baz');
// => 'foo bar baz'
Какую функцию выбрать?
| Функция | Создает классы (условия, массивы) | Разрешает конфликты | Когда использовать |
|---|---|---|---|
cn() |
да | да | По умолчанию — для создания строк классов, в которых возможны конфликты. |
merge() |
нет | да | Входные данные — обычные строки; нужно только устранить конфликты. |
join() |
да | нет | Вы уверены, что конфликтов нет, и хотите свести обработку к минимуму. |
Импорты
use function TailwindPHP\cn;
use function TailwindPHP\merge;
use function TailwindPHP\join;
Все три функции находятся в основном пространстве имен TailwindPHP и входят в состав пакета. Это PHP-порты clsx (автор Luke Edwards) и tailwind-merge (автор Dany Castillo).