Komponen Chat Terpisah di Mobile, Logika Jawaban Tetap Satu
Chat mobile butuh struktur sendiri ala aplikasi pesan, tetapi logika jawaban tetap satu sumber lewat TurnBody yang diekspor ulang.
Ringkasan
Layar sempit butuh struktur beda, bukan versi dipampatkan, jadi ChatMobileThread dibuat khusus di bawah breakpoint lg dengan pola aplikasi pesan: header sticky, gelembung dua sisi, dan composer di bawah. Desktop tiga kolom tak tersentuh. Logika jawaban tetap satu sumber karena TurnBody dipakai ulang lewat named export; 271 barisnya murni tata letak.
Membaca jawaban panjang dari asisten AI di layar HP biasanya berakhir sama: pertanyaan dan jawaban menyatu jadi satu kolom, pemisahnya cuma warna tipis, dan saya kehilangan jejak bagian mana yang sedang saya baca. Di desktop hal itu tidak terjadi karena ada tiga kolom yang memisahkan peran. Dugaan pertama saya waktu itu sederhana: tinggal kecilkan tiga kolom itu sampai muat di ponsel. Ternyata bukan itu jalan keluarnya.
Struktur lain untuk layar sempit
Layar ponsel memang membutuhkan struktur yang beda, bukan versi dipampatkan. Di commit ini komponen baru bernama ChatMobileThread saya buat khusus untuk layar di bawah breakpoint lg; desktop tiga kolom tidak tersentuh sama sekali. Bentuknya mengikuti pola aplikasi pesan yang dipahami semua orang: header menempel di atas berisi avatar dan status singkat, gelembung percakapan terbagi dua sisi dengan pertanyaan pengguna di kanan, jawaban asisten di kiri lengkap dengan avatar dan nomor urut, lalu baris pertanyaan lanjutan dan kolom ketik di bawah.
Dua detail CSS menopang rasa itu. Header memakai position: sticky yang dokumentasi MDN jelaskan sebagai posisi yang mengikuti alur normal dokumen lalu dihitung ulang terhadap scrollport terdekat, sehingga menempel saat digulir [8]. Efek kaca pilarnya datang dari backdrop-filter: menurut MDN, properti ini menerapkan efek grafis ke area di belakang elemen dan butuh latar transparan atau semi transparan supaya kelihatan [9].
Yang digandakan hanya kerangka
Jebakan dari membuat komponen tampilan kedua ini jelas: dua versi logika jawaban. Kalau banner fallback, render markdown, kartu situs, sumber knowledge, tampilan error, dan tombol retry ditulis ulang di komponen mobile, dalam dua sprint Anda punya dua perilaku yang mulai menyimpang.
Jalannya beda. Komponen ChatOutputPanel mengekspor TurnBody, dan komponen mobile tinggal memakainya. Semua logika jawaban tetap satu sumber; yang berbeda cuma kerangka tata letak di luarnya, dari gelembung sampai composer. Waktu desktop dapat fitur baru di TurnBody, ponsel ikut dalam satu commit yang sama.
Sesuai cara React diajarkan
Pola ini nyaris kata per kata dengan Thinking in React: UI dipecah menjadi komponen, dan tiap komponen idealnya hanya menangani satu tanggung jawab [10]. Tanggung jawab mobile thread adalah menyusun ulang percakapan untuk jempol; tanggung jawab TurnBody adalah merender satu giliran bicara dengan benar. Dua komponen, dua alasan berubah, tidak ada yang digandakan.
Saat menilai komponen sumber untuk panel tengah, saya juga pernah menulis tentang kartu sumber yang pindah ke bawah jawaban chat; sama seperti di sana, pemakaian ulang lewat named export jadi kontrak yang menjaga konsistensi.
Ukurannya membuktikan poinnya sendiri: kerangka mobile itu sekitar 271 baris, tapi tidak satu baris pun berisi logika jawaban baru. Kalau suatu saat desainnya berubah total, yang saya sentuh cuma lapisan tampilan.
Sumber
- [8] MDN: position, diakses 2026-09-08
- [9] MDN: backdrop-filter, diakses 2026-09-08
- [10] react.dev: Thinking in React, diakses 2026-09-08