Dalam snippet kali ini saya akan menuntun Anda bagaimana sebenarnya membuat komponen yang bernama accordion, biasa digunakan untuk Frequently Asked Question (FAQ), atau bisa jadi yang lain seperti dropdown untuk sidebar.
Dalam snippet kali ini saya akan menuntun Anda bagaimana sebenarnya membuat komponen yang bernama accordion, biasa digunakan untuk Frequently Asked Question (FAQ), atau bisa jadi yang lain seperti dropdown untuk sidebar.
Nah, disini kita tidak akan mulai dari awal, yang artinya saya akan sudah menganggap bahwa Anda sudah mempersiapkan project yang Tailwind CSS nya sendiri sudah ready untuk digunakan.
Jika Anda belum tau bagaimana cara install nya, saya sudah membuat post tentang installasi Tailwind CSS didalam nextjs. Atau Anda bisa lihat installasi dibeberapa framework seperti reactjs, vuejs, atau pun laravel (Install Tailwind CSS 2 Di Beberapa Framework)
Jika sudah, silahkan buka file tailwind.config.js
dan ganti mode nya menjadi Just In Time jit
, atau jika Anda belum menggunakan mode, silahkan tambahkan seperti berikut.
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
mode: 'jit',
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
};
Dalam teknik yang akan kita lakukan ini sama sekali tidak menggunakan yang namanya javascript, jadi ini pure dengan Tailwind CSS, tapi saya berharap Anda menggunakan versi ^2.2
, atau bisa lebih besar dari itulah, karena teknik yang akan kita gunakan ini adalah menggunakan peer
, yang mana itu sendiri datang sejak v2.2
.
Dalam post kali ini, saya menggunakan framework dari reactjs yaitu Nextjs. Tidak ada masalah sama sekali jika Anda menggunakan html, yang penting, jika nanti saya ketik className
itu hanya karena saya pakai jsx
. Jadi jika Anda menggunkan pure html, anda bisa ganti menjadi class
saja.
<!-- HTML -->
<div class="bg-red-500"></div>
<!-- JSX -->
<div className="bg-red-500"></div>
Mari kita mulai dengan membuat wrappernya, seperti berikut.
<div className="relative overflow-hidden">
</div>
Didalam nya, silahkan masukkan satu input dengan type checkbox dan beri class nya dengan peer
seperti berikut.
<input type="checkbox" className="peer absolute top-0 inset-x-0 w-full h-12 opacity-0 z-10 cursor-pointer" />
Jadi sekarang kira - kira komplitnya seperti ini.
<div className="relative overflow-hidden">
<input type="checkbox" className="peer absolute top-0 inset-x-0 w-full h-12 opacity-0 z-10 cursor-pointer" />
</div>
Sekarang, silahkan tambahkan satu div tepat dibawah checkbox tersebut, bayangkan aja sekarang kita lagi buat FAQ, jadi div pertama akan jadi pertanyaan nya, div kedua akan menjadi jawabannya.
<div className="h-12 w-full pl-5 flex items-center">
<h1>
Question 1
</h1>
</div>
Kemudian, tambah kan satu lagi div untuk jawabannya tepat dibawah penutup div nya seperti berikut.
<div className="overflow-hidden bg-white transition-all duration-500 max-h-0 peer-checked:max-h-40">
<div className="p-5 border-t">Answer 1</div>
</div>
Percaya atau tidak, itu semua sudah berhasil, cuma kita perlu sedikit visual icon untuk menandakan bahwa dia terbuka atau tertutup. Silahkan tambah tepat ditengah - tengah div tersebut.
<div className="...">
{/* Question */}
</div>
<div className="absolute top-3 right-3 transition-transform duration-500 rotate-0 peer-checked:-rotate-90">
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
</svg>
</div>
<div className="...">
{/* Answer */}
</div>
Komplitnya kira - kira seperti ini.
<div className="relative overflow-hidden">
<input type="checkbox" className="peer absolute top-0 inset-x-0 w-full h-12 opacity-0 z-10 cursor-pointer" />
<div className="h-12 w-full pl-5 flex items-center">
<h1>
Question 1
</h1>
</div>
<div className="absolute top-3 right-3 transition-transform duration-500 rotate-0 peer-checked:-rotate-90">
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
</svg>
</div>
<div className="overflow-hidden bg-white transition-all duration-500 max-h-0 peer-checked:max-h-40">
<div className="p-5 border-t">Answer 1</div>
</div>
</div>
Jika sudah, harusnya sekarang Anda sudah selesai, tapi jika Anda ingin membuatnya menjadi reusable component
, itu sah - sah saja. Karena disini saya menggunakan next yang membawa react, pastinya itu sangat mudah, tapi bukan berarti Anda menggunakan vue atau laravel itu sulit.
Pertama, silakan cut semua markup tersebut dan extract kedalam satu komponen seperti berikut.
const Item = ({ q, a }) => (
<div className="relative overflow-hidden">
<input type="checkbox" className="peer absolute top-0 inset-x-0 w-full h-12 opacity-0 z-10 cursor-pointer" />
<div className="h-12 w-full pl-5 flex items-center">
<h1>
{q}
</h1>
</div>
<div className="absolute top-3 right-3 transition-transform duration-500 rotate-0 peer-checked:-rotate-90">
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
</svg>
</div>
<div className="overflow-hidden bg-white transition-all duration-500 max-h-0 peer-checked:max-h-40">
<div className="p-5 border-t">{a}</div>
</div>
</div>
);
Jika sudah, sekarang Anda bisa pakai komponen tersebut dengan cara seperti ini.
export default function Home() {
return (
<div className="p-10">
<div className="overflow-hidden divide-y border shadow-sm rounded-2xl">
<Item q="Question 1" a="Answer 1" />
<Item q="Question 2" a="Answer 2" />
<Item q="Question 3" a="Answer 3" />
</div>
</div>
);
}
Kali ini step nya sudah selesai, jadi sekarang Anda tinggal buat satu array, terserah itu mau datang dari database atau tidak. Yang jelas, Anda bisa buat seperti ini sekarang.
export default function Home() {
const faqs = [
{
question: 'Apakah video gratis tersedia ?',
answered: 'Tentu saja. Video yang berbayar bertanda icon rocket. Jika tidak ada tanda, video itu gratis.'
},
{
question: 'Seberapa sering Parsinta upload pelajaran baru ?',
answered: ' Setiap hari akan ada video untuk setiap seri yang masih dalam persiapan, usahakan setiap hari Anda cek konten baru di parsinta. ',
},
{
question: 'Bagaimana cara nonton video gratis mau pun berbayar ?',
answered: ' Dari kedua sisi baik gratis mau pun berbayar, Anda tetap harus login jika ingin menonton video. ',
},
];
return (
<div className="p-10">
<div className="overflow-hidden divide-y border shadow-sm rounded-2xl">
{faqs.map((item, key) => <Item q={item.question} a={item.answered} key={key} />)}
</div>
</div>
);
}
Oia, pertanyaan tersebut saya kopi dari Parsinta FAQ. Semoga bermanfaat, jangan lupa share jika menurut Anda ini bermanfaat ya. Saya irsyad. See on the other one 🙂
Let's start living like no one can help us in any event, so that when we are helped in certain times, it becomes a plus in itself.