Утиліти для класів
Створення атрибутів 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() побудовано на основі clsx за допомогою merge(), тож використовуйте безпосередньо 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).