Utilidades de clases
Crear atributos class en plantillas implica unir cadenas, alternar clases según condiciones y evitar que las utilidades posteriores entren en conflicto con las anteriores (p-2 y p-4 no deberían conservarse ambas). En JavaScript, ese trabajo se reparte entre clsx y tailwind-merge. TailwindPHP incluye implementaciones PHP de ambas, para que obtenga el mismo comportamiento sin herramientas de Node.js ni paquetes Composer adicionales.
Tres funciones cubren todo el espectro: cn() construye y resuelve conflictos, merge() solo resuelve conflictos y join() solo concatena.
cn()
La utilidad recomendada. Primero construye las clases con condicionales al estilo de clsx y luego resuelve los conflictos de Tailwind con tailwind-merge, de modo que prevalece la última utilidad en conflicto.
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'
Argumentos aceptados
cn() acepta cualquier número de argumentos. Cada uno se aplana y filtra según la semántica de clsx:
| Argumento | Comportamiento |
|---|---|
string |
Se añade tal cual. |
int / float |
Se convierte en cadena y se añade. |
| Matriz secuencial | Cada elemento se procesa de forma recursiva. |
Matriz key => bool |
Cada clave se añade si su valor es verdadero. |
null, false, 0, '' |
Se ignoran. |
cn('flex', ['items-center' => true], ['p-4', ['gap-2']], null);
// => 'flex items-center p-4 gap-2'
Patrón de componente
cn() es lo que permite sobrescribir un componente: combine sus propias clases con las que pase quien lo llama; los conflictos se resuelven a favor de quien lo llama.
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>
Para estilos de componentes declarativos y con varios ejes, combine cn() con variants().
merge()
Solo resuelve conflictos; no construye clases condicionales. Pase cadenas de clases: las posteriores prevalecen sobre las anteriores cuando afectan a la misma propiedad. Úselo cuando la entrada ya sean cadenas simples.
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() está compuesto por merge() sobre clsx, así que use merge() directamente solo cuando no necesite la sintaxis de matrices condicionales.
join()
Concatena de forma sencilla, sin resolver conflictos. Descarta los valores falsos, pero conserva todas las utilidades en conflicto. Úselo cuando sepa que no hay conflictos y quiera la opción más ligera.
use function TailwindPHP\join;
join('foo', 'bar', null, 'baz');
// => 'foo bar baz'
¿Cuál debería usar?
| Función | Construye (condicionales, matrices) | Resuelve conflictos | Úsela cuando |
|---|---|---|---|
cn() |
sí | sí | Sea la opción predeterminada: al crear cadenas de clases que podrían entrar en conflicto. |
merge() |
no | sí | La entrada sean cadenas simples y solo necesite resolver conflictos. |
join() |
sí | no | Sepa que no hay conflictos y quiera minimizar el trabajo. |
Importaciones
use function TailwindPHP\cn;
use function TailwindPHP\merge;
use function TailwindPHP\join;
Las tres están en el espacio de nombres principal TailwindPHP y se incluyen con el paquete. Son implementaciones PHP de clsx (de Luke Edwards) y tailwind-merge (de Dany Castillo).