
# Utilitas Kelas

Menyusun atribut `class` dalam templat berarti menggabungkan string, mengaktifkan atau menonaktifkan kelas berdasarkan kondisi, dan mencegah utilitas yang ditambahkan belakangan bertabrakan dengan utilitas sebelumnya (`p-2` dan `p-4` seharusnya tidak muncul bersamaan). Di JavaScript, pekerjaan ini terbagi antara [clsx](https://github.com/lukeed/clsx) dan [tailwind-merge](https://github.com/dcastil/tailwind-merge). TailwindPHP menyediakan port PHP keduanya, sehingga Anda mendapatkan perilaku yang sama tanpa toolchain Node.js dan tanpa paket Composer tambahan.

Tiga fungsi mencakup semua kebutuhan: `cn()` menyusun dan mengatasi konflik, `merge()` hanya mengatasi konflik, dan `join()` hanya menggabungkan.

## cn()

Utilitas yang direkomendasikan. Fungsi ini terlebih dahulu menyusun kondisi seperti clsx, lalu menyelesaikan konflik Tailwind dengan tailwind-merge — utilitas yang konflik dan ditulis terakhir akan digunakan.

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

### Argumen yang diterima

`cn()` menerima argumen dalam jumlah berapa pun. Setiap argumen diratakan dan difilter dengan semantik clsx:

| Argumen | Perilaku |
|----------|----------|
| `string` | Ditambahkan apa adanya. |
| `int` / `float` | Diubah menjadi string lalu ditambahkan. |
| Array berurutan | Setiap elemen diproses secara rekursif. |
| Array `key => bool` | Setiap kunci ditambahkan jika nilainya truthy. |
| `null`, `false`, `0`, `''` | Diabaikan. |

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

### Pola komponen

`cn()` membuat komponen dapat di-override: gabungkan kelas bawaan komponen dengan kelas yang diberikan pemanggil, lalu konflik diselesaikan dengan mengutamakan pemanggil.

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

Untuk gaya komponen deklaratif dengan banyak sumbu, pasangkan `cn()` dengan [variants()](https://tailwindphp.inline0.dev/id/docs/class-utilities/variants).

## merge()

Hanya menyelesaikan konflik — tidak menyusun kondisi. Berikan string kelas; kelas yang ditulis belakangan akan menggantikan kelas sebelumnya jika menargetkan properti yang sama. Gunakan fungsi ini jika masukan Anda sudah berupa string biasa.

```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()` adalah `merge()` yang disusun di atas clsx, jadi gunakan langsung `merge()` hanya jika Anda tidak memerlukan sintaks array kondisional.

## join()

Penggabungan sederhana tanpa penyelesaian konflik. Nilai falsy dihapus, tetapi semua utilitas yang konflik tetap dipertahankan. Gunakan jika Anda yakin tidak ada konflik dan menginginkan opsi yang paling ringan.

```php
use function TailwindPHP\join;

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

## Mana yang sebaiknya saya gunakan?

| Fungsi | Menyusun (kondisi, array) | Menyelesaikan konflik | Gunakan saat |
|----------|:---:|:---:|----------|
| `cn()`    | ya | ya | Pilihan standar — menyusun string kelas yang mungkin berkonflik. |
| `merge()` | tidak | ya | Masukan berupa string biasa; Anda hanya perlu mengatasi konflik. |
| `join()`  | ya | tidak | Anda yakin tidak ada konflik dan menginginkan pemrosesan minimal. |

## Impor

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

Ketiganya tersedia di namespace `TailwindPHP` utama dan disertakan dalam paket. Semuanya merupakan port PHP clsx (oleh Luke Edwards) dan tailwind-merge (oleh Dany Castillo).
