
# Klassverktyg

När du bygger `class`-attribut i mallar behöver du sammanfoga strängar, växla klasser baserat på villkor och hindra senare utilities från att krocka med tidigare (`p-2` och `p-4` ska inte båda finnas kvar). I JavaScript delas arbetet upp mellan [clsx](https://github.com/lukeed/clsx) och [tailwind-merge](https://github.com/dcastil/tailwind-merge). TailwindPHP innehåller PHP-portar av båda, så du får samma beteende utan verktygskedjan Node.js och utan extra paket Composer.

Tre funktioner täcker hela spannet: `cn()` skapar och löser konflikter, `merge()` löser bara konflikter och `join()` sammanfogar bara.

## cn()

Det rekommenderade verktyget. Först bygger det villkorsstyrt enligt clsx-stil och löser sedan konflikter mellan Tailwind med tailwind-merge — den sista motstridiga utility-klassen vinner.

```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'
```

### Godkända argument

`cn()` accepterar valfritt antal argument. Vart och ett plattas ut och filtreras enligt clsx-semantik:

| Argument | Beteende |
|----------|----------|
| `string` | Läggs till som det är. |
| `int` / `float` | Konverteras till en sträng och läggs till. |
| Sekventiell array | Varje element behandlas rekursivt. |
| `key => bool`-array | Varje nyckel läggs till om dess värde är sant. |
| `null`, `false`, `0`, `''` | Ignoreras. |

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

### Komponentmönster

`cn()` gör en komponent möjlig att åsidosätta: slå ihop komponentens egna klasser med dem som anroparen skickar in, så löses konflikter till anroparens fördel.

```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>
```

För deklarativa komponentstilar med flera axlar kan du kombinera `cn()` med [variants()](https://tailwindphp.inline0.dev/sv/docs/class-utilities/variants).

## merge()

Löser endast konflikter — ingen villkorsstyrd konstruktion. Skicka klasssträngar; senare klasser åsidosätter tidigare när de riktar sig mot samma egenskap. Använd detta när indata redan består av vanliga strängar.

```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()` är `merge()` byggt ovanpå clsx, så använd `merge()` direkt bara när du inte behöver villkorlig arraysyntax.

## join()

Enkel sammanfogning utan konfliktlösning. Falska värden tas bort, men alla motstridiga utilities behålls. Använd detta när du vet att det inte finns några konflikter och vill ha det snabbaste alternativet.

```php
use function TailwindPHP\join;

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

## Vilken ska jag använda?

| Funktion | Bygger (villkor, arrayer) | Löser konflikter | Använd när |
|----------|:---:|:---:|----------|
| `cn()`    | ja | ja | Standardval — när du bygger klasssträngar där konflikter kan uppstå. |
| `merge()` | nej  | ja | Indata består av vanliga strängar; du behöver bara lösa konflikter. |
| `join()`  | ja | nej  | Du vet att det inte finns några konflikter och vill göra så lite som möjligt. |

## Importer

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

Alla tre finns i huvudnamnrymden `TailwindPHP` och följer med paketet. De är PHP-portar av clsx (av Luke Edwards) och tailwind-merge (av Dany Castillo).
