Introduction

Hai! Selamat datang di My Komponent Library. Ini adalah pustaka komponen UI yang dirancang untuk memudahkan kamu membangun antarmuka pengguna yang menarik dan responsif. Komponen di dalam pustaka ini dibuat dengan prinsip desain modern dan mengikuti praktik terbaik dalam pengembangan frontend.

Menurut React.dev, komponen adalah blok UI yang dapat digunakan kembali dan ditulis sebagai fungsi atau kelas. Komponen dapat menerima input melalui props dan mengembalikan elemen React yang menjelaskan tampilan antarmuka.

"Komponen React adalah fungsi JavaScript yang dapat Anda tambahkan markup di dalamnya. Namanya selalu dimulai dengan huruf kapital dan mengembalikan markup JSX."

Saat ini tersedia banyak pustaka UI populer seperti Chakra UI, Mantine, Ant Design, dan lainnya. Mereka menyediakan berbagai komponen siap pakai sehingga kamu bisa langsung menggunakannya sesuai kebutuhan.
Tapi, jika kamu membuat komponen sendiri, ada banyak keuntungan tambahan yang bisa didapatkan, lho!

Perbandingan: Buat Komponen Sendiri vs Pakai Library

AspekBuat SendiriPakai Library
๐ŸŽจ Kontrol Desain100% kamu yang aturTergantung fitur & tema bawaan
โš™๏ธ PerformaRingan (jika dirancang baik)Bisa berat karena banyak fitur bawaan
๐Ÿ”„ FleksibilitasSangat fleksibelKadang terbatas pada API mereka
๐Ÿงฑ Konsistensi UIHarus kamu jaga sendiriSudah built-in dan konsisten
๐Ÿ•’ Waktu PengembanganLebih lamaLebih cepat karena komponen siap pakai
๐Ÿงช TestingHarus kamu uji sendiriSudah stabil dan battle-tested
๐ŸŽฏ Learning CurveTidak perlu belajar API baruHarus mempelajari struktur & props library

Tapi jangan salah, membuat komponen sendiri juga memberikan banyak manfaat, lho! Seperti yang akan kita lihat berikut ini:

Manfaat Membuat Komponen Sendiri (Untuk Developer)

NoManfaatPenjelasan Singkat
1๐Ÿง  Memahami UI Lebih DalamBelajar membangun UI dari nol, termasuk struktur, perilaku, dan aksesibilitas.
2๐Ÿ› ๏ธ Meningkatkan Skill FrontendMelatih pola pikir 'thinking in components' yang penting untuk technical test.
3๐Ÿ’ผ Portfolio Kuat dan UnikMenjadi nilai tambah saat melamar kerja dan bisa dipakai ulang di proyek lain.
4๐Ÿงฉ Fleksibilitas Tanpa BatasTidak terikat oleh batasan library atau desain yang sudah jadi.
5๐Ÿงช Belajar TestingKomponen kecil cocok untuk latihan unit testing maupun integration testing.
6๐Ÿง  Mandiri dan AdaptifMeningkatkan pemahaman dasar sehingga tidak bergantung pada framework.

Sekarang, mari kita mulai dari awal untuk membangun komponen kita sendiri. Aku juga akan membagikan beberapa contoh penggunaannya agar kamu bisa langsung mencoba dan memahami konsepnya dengan mudah.

1. Tailwind CSS

Sebelum membuat komponen UI yang bisa dipakai ulang, kita mulai dulu dari Tailwind CSS. Tailwind adalah utility-first CSS framework yang memungkinkan kita membangun desain antarmuka langsung di dalam elemen HTML atau JSX dengan class-class seperti px-4, text-center, bg-blue-500, dan sebagainya.

Tailwind membuat kita bisa mendesain UI dengan cepat tanpa harus menulis CSS secara manual. Tapi, ketika komponen makin kompleks, kita akan sering menulis class secara dinamis. Nah, di sinilah clsx dan tailwind-merge sangat berguna โ€” dan akan dibahas di poin berikutnya. silahkan install tailwind terlebih dulu dengan mengunjungi website nya Tailwind Css

2. clsx dan tailwind-merge

Mengapa kita membutuhkan clsx dan tailwind-merge? Karena saat membangun komponen UI yang fleksibel, sering kali kita perlu mengatur class Tailwind secara dinamis berdasarkan kondisi tertentu.
clsx membantu kita menggabungkan class secara kondisional dengan cara yang rapi dan efisien. Sementara itu, tailwind-merge berguna untuk menyatukan class Tailwind yang mungkin saling bertentangan (seperti p-2 dan p-4), sehingga hanya class terakhir yang relevan yang akan digunakan.

Code:

DummyComponent.jsx
1npm install clsx tailwind-merge

Jika sudah, Sekarang kita buka VScode nya

Buat fungsi ini. tujuan nya adalah Menyederhanakan dan menstandarkan cara menggabungkan className di seluruh komponen React, supaya lebih bersih, fleksibel, dan bebas bug konflik class Tailwind.

lib/utils.ts
utils.ts
1export function Twc(...inputs: ClassValue[]) { 2 return twMerge(clsx(inputs)); 3}
Button.jsx
1import { Twc } from "@/lib/utils"; 2import React, { forwardRef } from "react"; 3 4const baseStyles = "inline-flex items-center justify-center font-medium rounded transition-colors disabled:opacity-50 disabled:pointer-events-none"; 5 6const variantClasses = { 7 filed: "bg-[#0079f8] text-white hover:bg-blue-600 ", 8 default: "bg-white text-gray-900 rounded-md border border-gray-300 hover:border-gray-50", 9 outline: "border bg-transparent border-gray-600 border-2 text-gray-900 rounded-md", 10}; 11 12const sizeClasses = { 13 sm: "px-3 py-1 text-sm", 14 md: "px-4 py-2 text-base", 15 lg: "px-5 py-3 text-lg", 16}; 17 18export type ButtonProps = React.ComponentPropsWithRef<"button"> & { 19 as?: React.ElementType; 20 variant?: keyof typeof variantClasses; 21 size?: keyof typeof sizeClasses; 22 className?: string; 23 children?: React.ReactNode; 24}; 25 26 export const Button: React.FC<ButtonProps> = forwardRef( 27 ( 28 { 29 as: Component = "button", 30 variant = "default", 31 size = "md", 32 className, 33 children, 34 ...props 35 }, 36 ref 37 ) => { 38 return ( 39 <Component 40 ref={ref} 41 className={Twc( 42 baseStyles, 43 variantClasses[variant], 44 sizeClasses[size], 45 className 46 )} 47 {...props} 48 > 49 {children} 50 </Component> 51 ); 52 } 53 ); 54 55 Button.displayName = "Button"; 56
Button.jsx
1const CobaButton = () => { 2 return <Button variant="default"> Default </Button>; 3 };