00:00:00Berhentilah pakai Radix UI dan beralihlah ke apa? Ke Base UI. Faktanya, kalau kamu penggemar Shadcn,
00:00:06sudah ada pilihan untuk pindah sekarang. Jika kamu belum pernah mendengar tentang Base UI,
00:00:10ini sebenarnya buatan kreator asli Radix, Floating UI, dan Material UI, dan ini adalah perpustakaan headless UI.
00:00:15Jadi, ia membawa fungsionalitas dan aksesibilitas komponen, tapi desainnya tetap dari kamu.
00:00:20Hal ini sangat penting saat ini karena LLM masih kurang mumpuni dalam menangani kasus-kasus khusus
00:00:24dan kebutuhan aksesibilitas. Tapi yang baru saja saya jelaskan itu persis seperti apa yang ditawarkan Radix.
00:00:30Lalu kenapa butuh yang baru? Mari kita lihat dan saya akan tunjukkan perbedaan utamanya.
00:00:35Saya akan mulai dengan cepat menunjukkan dokumentasi Base UI supaya kamu bisa melihat semua
00:00:44komponen yang ada. Di sebelah kiri ini, kamu bisa lihat mereka punya hampir semua komponen yang
00:00:48kamu butuhkan dalam perpustakaan komponen, bahkan yang tingkat lanjut seperti combo box ini,
00:00:52yang tidak ada di Radix. Kamu akan lihat di semuanya ada contoh bagus tentang cara
00:00:57membuat dan menatanya dengan sesuatu seperti CSS Modules. Kamu bahkan bisa mengubahnya ke contoh Tailwind
00:01:01jika mau. Dokumentasinya sangat bagus, tapi kita di sini bukan untuk membandingkan
00:01:06dokumentasi. Mari kita langsung bahas perbedaan utama yang pertama, dan yang mungkin
00:01:10paling sering terdengar, yaitu Base UI dikelola secara aktif sementara Radix seperti dalam kondisi "zombie".
00:01:15Maksud saya, jika kita lihat grafik kontribusi GitHub, kamu akan lihat Base UI
00:01:20terus berkembang, sementara Radix sepertinya hanya sesekali melakukan commit di sana-sini. Namun,
00:01:25ini lebih jelas lagi saat kita melihat PR dan issue yang ditutup dalam sebulan terakhir. Kamu bisa
00:01:29lihat Base UI telah menutup 58 issue dan menggabungkan 154 pull request, sedangkan Radix tidak menutup atau menggabungkan apa pun.
00:01:36Singkatnya, yang terjadi pada Radix adalah WorkOS membeli perusahaan di balik Radix,
00:01:42tapi tidak benar-benar berinvestasi di sana, jadi tim Radix banyak yang keluar. Inilah kondisi kita sekarang.
00:01:47Bahkan salah satu pencipta Radix mengatakan ia hanya akan memakai Radix sebagai pilihan terakhir, dan ya, dia
00:01:53sekarang bekerja di Base UI. Jadi ini soal memastikan aplikasi dan dependensi kamu dikelola secara aktif
00:01:58dan tidak akan membuat pusing di masa depan jika kamu menemukan bug yang tidak akan pernah
00:02:02diperbaiki. Lebih bagusnya lagi, Base UI dibuat cukup mirip dengan Radix jadi migrasi seharusnya
00:02:08tidak terlalu sulit. Tapi itu bukan berarti mereka tidak menyelipkan beberapa peningkatan.
00:02:13Salah satu peningkatan favorit saya adalah cara mereka menangani prop "asChild" yang ada di Radix. Jika kamu belum
00:02:17pernah melihat ini, yang saya punya di sini adalah Radix Select. Jika saya ingin merender komponen kustom
00:02:22di sini sebagai pemicu select saya, jika saya membungkusnya dengan komponen select trigger, kamu bisa lihat
00:02:27bahwa saya mendapatkan komponen pembungkus dan juga tombol bertuliskan "subscribe" (yang sebaiknya kamu klik).
00:02:31Tapi jika saya ingin tombol subscribe tersebut berfungsi sebagai pemicu select,
00:02:36yang perlu saya lakukan di Radix hanyalah menambahkan prop "asChild" ke pemicunya. Itu memberitahu
00:02:41Radix untuk menggabungkan semua prop dan fungsionalitas pemicu select ini dengan komponen yang kita
00:02:46tetapkan sebagai anak (child). Kamu bisa lihat itu terjadi berdasarkan fakta bahwa nama kelas di sini
00:02:50digabungkan dengan tombolnya, bahkan menimpanya dalam kasus ini. Jadi jika saya hapus prop itu dan
00:02:55simpan, kamu lihat sekarang kita punya tombol, tapi secara fungsional ini adalah pemicu select saya.
00:03:00Itu fitur yang praktis, tapi keluhan umum tentang hal itu adalah kurang eksplisitnya cara kerja tersebut.
00:03:04Saya akui terkadang saat membaca kode dengan cepat, saya melewatkan
00:03:09prop ini sehingga saya melewatkan penyebab masalahnya. Jika kita beralih ke cara Base UI menanganinya,
00:03:13kamu tetap mendapatkan fungsionalitas yang sama. Saya punya tombol di sini yang
00:03:18berfungsi sebagai pemicu select, tapi kalau kamu lihat kodenya, alih-alih memakai "asChild", Base UI memakai
00:03:24prop "render". Di prop render tersebut, kamu menentukan komponen yang ingin kamu render
00:03:29sebagai pemicu select. Ini perubahan kecil, tapi menurut saya ini membuatnya jauh lebih
00:03:34eksplisit. Secara harfiah merender komponen ini, jadi kamu tidak perlu mencari apakah ia memakai
00:03:39komponen anak atau mencari prop "asChild". Seperti yang saya katakan, ini
00:03:43hanya perubahan kecil, tapi menurut saya sangat bagus. Dan itu bahkan belum seluruh kekuatan dari
00:03:48prop render. Kita bisa lihat di sini saat membuat Switch, kita bisa memberikan sebuah fungsi ke
00:03:52prop render tersebut. Jadi kita bisa mengakses prop pada state komponen yang sebenarnya sedang kita
00:03:56bangun. Dalam hal ini, switch thumb. Apa yang dimungkinkan adalah kita bisa memilih komponen mana
00:04:01yang ingin kita terapkan passthrough props-nya, dan kita juga bisa melakukan logika render kustom
00:04:05atau logika styling kustom berdasarkan state komponen tersebut. Dalam kasus
00:04:10switch thumb ini, kita bisa pilih apakah kondisinya checked, dirty, disabled, filled, dan banyak lagi. Jadi dalam
00:04:14kasus ini kita hanya mengecek apakah kondisinya sedang dicentang atau tidak, dan jika iya,
00:04:18kita merender ikon yang berbeda. Bahkan ada hook yang memungkinkan kamu membangun prop render itu
00:04:22ke dalam komponen kustom kamu sendiri, tapi itu sudah agak teknis. Namun, semoga
00:04:27kamu bisa melihat bahwa apa pun kustomisasi yang kamu inginkan, seharusnya bisa ditangani dengan Base UI. Sekarang,
00:04:31kembali ke komponen select saya, perbedaan berikutnya adalah Base UI memungkinkan beberapa
00:04:35komponen kamu bersifat data-driven. Kita bisa lihat dalam kasus select di sini. Yang saya punya saat ini
00:04:40adalah kode Radix Select. Kita punya array berisi label dan value, dan untuk
00:04:44memasukkan nilainya ke dalam select di bawah sini, satu-satunya hal yang perlu dilakukan adalah memetakan (map) array apple tersebut
00:04:49dan merender select item di Radix, maka nilai-nilainya akan ditambahkan seperti ini. Jika kita
00:04:54lihat cara kerjanya di Base UI, sangat mirip. Kita masih punya
00:04:59array label dan value, dan di bawah sini kita masih memetakan dan merender
00:05:03select item, tapi kita juga menyertakannya di tempat lain yaitu pada root select ini.
00:05:08Kita menyertakan array itu, dan ini memberikan dampak halus yang berarti komponen tersebut sekarang
00:05:13menyadari data yang akan dirender sebelum proses rendering dimulai. Itu artinya ada sedikit
00:05:17peningkatan performa, terutama dalam hal server side rendering. Satu hal yang saya rasa masih
00:05:22bisa ditingkatkan adalah saat ini saya memasukkan apple sebagai prop items,
00:05:26tapi di bawah sini saya juga memetakan array apple tersebut. Jadi kita memakainya di dua tempat. Menurut saya
00:05:32seharusnya mereka meniru React Aria, perpustakaan headless lainnya. Di sini kamu
00:05:36bisa lihat kita punya array animal, kita memasukkannya sebagai items di sini, lalu untuk
00:05:41anak-anaknya, yang kita lakukan hanyalah menggunakan sebuah fungsi. Fungsi ini akan mengetahui semua item yang
00:05:45telah diteruskan pada elemen induknya. Jadi kita tidak memakai array itu di dua tempat dan elemen
00:05:50induknya berfungsi sebagai penyedia data. Jadi ini sesuatu yang menurut saya masih bisa ditingkatkan.
00:05:55Kembali ke komponen select saya, saya ingin menunjukkan perbedaan lainnya,
00:05:59tapi yang satu ini spesifik untuk komponen select. Prop render dan pendekatan
00:06:03data-driven tadi bisa kamu lihat di hampir semua komponen, tapi yang ini khusus untuk select.
00:06:08Yaitu, kamu bisa membuat multi-select. Ini fitur yang sangat dirindukan di Radix.
00:06:13Kamu bisa lihat di Base UI, yang perlu kamu lakukan hanyalah menambahkan prop ke root select bertuliskan "multiple".
00:06:17Bisa bernilai true atau false, dan seketika select kamu menjadi multi-select. Semudah itu. Dan
00:06:22lebih jauh lagi, Base UI bahkan punya beberapa komponen lain yang tidak ada di Radix seperti combo box
00:06:27dan auto complete. Inilah keuntungan dari pengelolaan yang aktif; mereka bisa menanggapi
00:06:33permintaan pengguna. Sekarang, ada dua lagi perbedaan yang ingin saya tunjukkan antara Radix dan Base UI.
00:06:38Kita akan ganti menggunakan komponen checkbox karena saya agak bosan dengan
00:06:41komponen select itu. Perbedaan pertama yang ingin saya tunjukkan adalah soal styling. Base UI
00:06:45memberikan pilihan styling lain yang menurut saya sangat keren. Bisa kita lihat di sini saat ini
00:06:50saya menggunakan Tailwind. Kamu bisa pakai semua pendekatan tradisional seperti CSS biasa, CSS
00:06:55Modules, dan banyak lagi. Tapi jika kamu pakai sesuatu seperti Tailwind, salah satu cara yang
00:06:59biasanya digunakan untuk menata komponen seperti ini adalah dengan memakai atribut data untuk state-nya. Kita punya
00:07:04data-checked di sini, dan jika dicentang, kita akan pakai background primary. Kamu bisa lihat ada
00:07:08string yang sangat panjang untuk styling ini di Tailwind, yang terkadang bisa menjadi masalah. Jadi,
00:07:13salah satu opsi yang diberikan Base UI untuk membantu hal ini adalah kamu bisa memakai fungsi
00:07:17sebagai class name kamu. Ini memberimu akses ke state komponen tersebut. Dalam hal
00:07:22checkbox ini, saya menerapkan gaya berdasarkan apakah kondisinya checked atau disabled. Saya melakukannya
00:07:26dengan kondisional sederhana di sini, dan menurut saya terkadang ini cara yang lebih enak dilihat selintas
00:07:31saat kamu membaca kode untuk melihat di mana tepatnya gaya checked dan disabled itu
00:07:35berasal, daripada harus memindai satu baris panjang dan mencari atribut data tadi. Saya rasa
00:07:40ini bahkan lebih membantu jika kamu memakai sesuatu seperti Vanilla CSS. Ini juga bekerja sangat
00:07:45baik dengan perpustakaan lain yang sangat saya sukai bernama Tailwind Variants. Kamu bisa lihat di sini saya
00:07:49meneruskan state ke fungsi checkbox saya, dan di bagian Tailwind Variant checkbox, kita punya
00:07:53gaya dasar, tapi kita juga punya varian. Kamu bisa lihat di sini saya cukup bilang jika checked adalah
00:07:58true gunakan gaya ini, jika disabled true gunakan yang itu. Menurut saya terkadang ini jauh lebih
00:08:02jelas daripada memakai atribut data, tapi itu tergantung pendapat dan kenyamanan masing-masing.
00:08:06Sangat bagus Base UI memberi kita semua pilihan ini. Saya juga ingin
00:08:11menambahkan bahwa menggunakan fungsi sebagai class name adalah sesuatu yang pertama kali saya sukai dari React
00:08:14Aria. Jadi bagi saya sepertinya ada React Aria di satu sisi yang punya kurva belajar yang lebih curam,
00:08:19dan Radix yang cukup sederhana, lalu Base UI seolah bertemu di tengah dan mengambil
00:08:23fitur-fitur yang saya suka dari keduanya untuk menciptakan perpustakaan headless yang mutakhir. Itulah
00:08:28semua perbedaan utama yang ingin saya bahas di video ini, tapi masih banyak lagi fitur lain. Base UI punya
00:08:33dukungan bagus untuk React Hook Form dan TanStack Form, punya dukungan animasi untuk memudahkan
00:08:38proses penganimasian komponen, bahkan punya fitur seperti input scrubbing,
00:08:42nested dialogs, dan pemicu menu saat hover. Dan saya yakin jika kamu punya permintaan yang masuk akal, mereka
00:08:47akan menanggapinya di GitHub karena proyek ini dikelola secara aktif. Namun, perlu dikatakan juga
00:08:52bahwa saya mungkin tidak akan langsung bermigrasi dari Radix ke Base UI sekarang karena menurut saya
00:08:57Radix belum sepenuhnya rusak. Kalau saya memulai proyek baru, saya pasti pakai Base UI sekarang, dan jika saya
00:09:02butuh fitur seperti combo box atau autocomplete, saya juga akan mempertimbangkan untuk migrasi. Beritahu
00:09:07pendapatmu tentang Base UI di komentar. Jangan lupa subscribe, dan seperti biasa,
00:09:11sampai jumpa di video berikutnya.