Belajar Tailwind CSS - Component Libraries & Headless UI Patterns
Episode 19 of 23

Belajar Tailwind CSS - Component Libraries & Headless UI Patterns

Episode ini membahas cara membangun komponen accessible memakai Headless UI, Radix, dan Tailwind UI, serta menyusun dokumentasi dan pengembangan komponen dengan Storybook yang terintegrasi dengan Tailwind.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Komponen interaktif seperti dialog, menu, dan tabs menyimpan banyak jebakan aksesibilitas: fokus trap, keyboard navigation, dan ARIA. Menulisnya dari nol berulang kali itu boros dan rawan bug. Episode 19 membahas pendekatan headless UI: komponen logika tanpa gaya, yang lalu di-styling dengan Tailwind.

Pola ini memisahkan dua hal: perilaku yang disediakan library headless, dan tampilan yang sepenuhnya di tangan kalian lewat utility class. Hasilnya komponen accessible dengan gaya yang sepenuhnya custom — dan Tailwind UI serta Storybook menyempurnakan alur kerjanya.

Headless UI dan Radix

Headless UI

Headless UI dari Tailwind Labs menyediakan komponen tanpa gaya: menu, listbox, dialog, disclosure, dan lainnya. Memasangnya:

Install Headless UI
npm install @headlessui/react

Lalu styling dilakukan murni dengan utility Tailwind:

JSMenu dengan Headless UI
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
 
export function Dropdown() {
  return (
    <Menu>
      <MenuButton className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600">
        Opsi
      </MenuButton>
      <MenuItems className="absolute mt-1 w-40 rounded border border-gray-200 bg-white p-1 shadow-lg">
        <MenuItem>
          <button className="block w-full rounded px-3 py-1 text-left hover:bg-gray-100">
            Edit
          </button>
        </MenuItem>
        <MenuItem>
          <button className="block w-full rounded px-3 py-1 text-left hover:bg-gray-100">
            Hapus
          </button>
        </MenuItem>
      </MenuItems>
    </Menu>
  );
}

MenuButton dan MenuItem menangani keyboard navigation, fokus, dan ARIA secara otomatis — kalian hanya bertanggung jawab atas tampilan lewat class seperti hover:bg-gray-100.

Radix

Radix UI adalah koleksi primitives tak bergaya yang lebih granular. Pola pemakaiannya sama: bungkus dengan class Tailwind. Pilihan antara Headless UI dan Radix biasanya soal selera dan kebutuhan — keduanya menghasilkan komponen accessible tanpa gaya bawaan.

Tailwind UI

Tailwind UI adalah kumpulan komponen premium berbayar dari Tailwind Labs. Komponennya ditulis penuh dengan utility class — tanpa dependency lain. Kalian menyalin markup-nya lalu menyesuaikan:

HTMLKomponen Tailwind UI
<div class="flex items-center gap-4 rounded-lg bg-white p-6 shadow">
  <img src="avatar.png" alt="Avatar" class="h-12 w-12 rounded-full" />
  <div>
    <p class="text-sm font-medium text-gray-900">Nama Pengguna</p>
    <p class="text-sm text-gray-500">Deskripsi singkat profil.</p>
  </div>
</div>

Keunggulan Tailwind UI: konsisten, sudah responsive, dan langsung di-customize. Kelemahan: berbayar dan tidak mencakup komponen dengan logika kompleks — untuk itu tetap butuh Headless UI atau Radix.

Storybook untuk Dokumentasi Komponen

Storybook adalah tempat mengembangkan dan mendokumentasikan komponen secara terisolasi. Inisialisasi:

Inisialisasi Storybook
npx storybook@latest init

Agar Tailwind berfungsi di Storybook, import CSS global lewat decorator:

JS.storybook/preview.ts
import "../src/styles.css";
import type { Preview } from "@storybook/react";
 
const preview: Preview = {
  decorators: [
    (Story) => (
      <div className="p-4">
        <Story />
      </div>
    ),
  ],
};
 
export default preview;

Setelah itu setiap komponen punya stories sendiri:

JSButton.stories.tsx
import { Button } from "./Button";
 
export const Primary = {
  args: { variant: "primary", children: "Simpan" },
};
 
export const Ghost = {
  args: { variant: "ghost", children: "Batal" },
};

Stories ini bukan sekadar dokumentasi — episode 20 akan memakainya sebagai dasar visual regression testing.

Tip

Kombinasi terbaik untuk library komponen: Headless UI atau Radix untuk logika, utility Tailwind untuk tampilan, Storybook untuk pengembangan, dan CVA dari episode 15 untuk API variants. Empat elemen ini menjadi fondasi komponen yang accessible, konsisten, dan terdokumentasi.

Penutup

Episode 19 membangun fondasi library komponen: komponen accessible dengan Headless UI dan Radix, gaya siap pakai dari Tailwind UI, serta dokumentasi dan pengembangan terisolasi dengan Storybook.

Inti yang harus dibawa pulang:

  • Headless UI menyediakan logika dan aksesibilitas tanpa gaya.
  • Radix memberi primitives granular dengan pola pemakaian sama.
  • Tailwind UI menyediakan markup premium siap custom.
  • Storybook mengembangkan komponen secara terisolasi.
  • Import CSS global lewat decorator di preview.
  • Stories menjadi fondasi visual regression testing.

Di episode 20 selanjutnya kita akan membahas testing, observability & monitoring — visual regression testing dengan Playwright dan Chromatic, pemantauan performa memakai Lighthouse dan Web Vitals, serta mencegah regresi CSS di CI.

Belajar Tailwind CSS - Component Libraries & Headless UI Patterns | Belajar Tailwind CSS