Satu set warna, ukuran, dan komponen untuk semua aplikasi Karlo, supaya tombol, status, atau konfirmasi hapus tampil dan bekerja sama di mana pun pengguna berada. Hari ini Platform dan TMS masing-masing punya versinya sendiri, dan dua file Figma juga berbeda dari keduanya.
2 aplikasi hari ini
Platform (React) dan TMS (Svelte), dikerjakan tim yang berbeda. Aplikasi React ketiga menyusul.
Platform jadi acuan
Library komponen Platform menentukan nama dan tampilan. TMS mengikutinya.
Satu tempat
Halaman ini: token, komponen, dan aturan di satu tempat, untuk desain dan engineering.
Cara kerja
Nilai dan aturan ditulis sekali di sini. Tempat-tempat di bawah menyalinnya; tidak ada yang mengetik warna dua kali.
karlo-design
Token (warna, ukuran) dan spesifikasi komponen di halaman ini.
Desain
Library Figma
Satu file bersama. Desainer tinggal menarik Button, Dialog, StatusBadge, tidak menggambarnya ulang. Warna masuk sebagai Figma variables.
Engineer Platform
Storybook Platform
Komponen React asli milik Platform. Implementasi acuan.
Engineer TMS
Storybook TMS
Komponen Svelte milik TMS, dibangun dengan spek dan nama yang sama.
Komponen atau varian baru: disetujui desain, ditambahkan ke spek di sini, lalu Figma dan setiap aplikasi mengikuti. Tidak ada yang baru langsung masuk ke satu aplikasi saja.
Siapa mengerjakan apa
Desain
Pemilik tampilan. Mengelola library Figma, menyetujui setiap komponen atau varian baru, menjawab keputusan yang masih terbuka.
PM
Pemilik kata-kata dan alur: nama status, pesan, kapan perlu konfirmasi. Menentukan apa yang dilihat pengguna setelah sebuah aksi.
Engineer Platform
Menjaga library acuan dan Storybook-nya. Merapikan item untuk Platform saat menyentuh komponen tersebut.
Engineer TMS
Membangun library TMS sesuai spek, dengan nama dari Platform. Mengganti tombol, dialog, dan tabel buatan halaman dengan komponen library.
Kondisi hari ini
Kenapa ini perlu sekarang, dalam angka dari kode.
10
lebar dialog di Platform, diatur per dialog. Spek punya 3.
18
warna hex langsung di StatusBadge Platform saja, bukan token.
65
file TMS yang membuat tombol sendiri, bukan memakai Button.
3
sumber yang tidak sama: Storybook Platform, Figma Shipper, dan Figma Transporter.
0
komponen Figma yang ditandai siap untuk development.
6
cara berbeda TMS menampilkan error di form.
Fondasi
Bagian terkecil. Setiap komponen dibangun hanya dari ini. Nama-nama ini yang dilihat desainer di Figma dan dipakai engineer di kode.
Brand
primary#4193d0
primary-dark#2e7ab5
accent#3b9fe0
ink#0c1424
Teks
text-primary#212121
text-secondary#424242
text-subtle#757575
text-muted#9e9e9e
text-inactive#bdbdbd
Latar dan garis tepi
bg-page#f9fafb
bg-card#ffffff
bg-surface#fafafa
bg-input-filled#e8f4fd
border#eaeaea
border-input#d9d9d9
Status
status-info#2e90fa
status-success#027a48
status-warning#f79009
status-danger#d04141
status-neutral#344054
status-purple#7a5af8
Ukuran teks
Aaxs12px
Aasm13px
Aabase14px
Aamd15px
Aalg16px
Aaxl20px
Aa2xl32px
Jarak
xs4px
sm8px
md16px
lg24px
xl32px
2xl48px
Sudut membulat
sm8px
md12px
xl12px
2xl16px
lg20px
pill24px
Diurutkan berdasarkan ukuran. Nama di Platform tidak berurutan: xl sama dengan md, dan lg (20) lebih besar dari 2xl (16). Desain perlu menamai ulang skalanya sekali; sampai saat itu, pakai sm, md, lg, dan pill untuk pekerjaan baru.
Komponen
Komponen inti adalah design system-nya: ada di library Figma dan di setiap aplikasi. Pola dibangun dari komponen inti. Tabel menunjukkan posisi tiap aplikasi; bagian di bawahnya menjelaskan setiap komponen secara lengkap.
Bukan bagian design system: bagian milik satu area produk. Boleh tetap di Storybook aplikasinya, tapi dibangun dari komponen di atas dan tidak ada di library Figma.
Bagian Spot Order: Platform DocumentCard, DriverCard, FleetCard, NegotiationTimeline, OfferInput
Bagian fitur TMS: TMS AgreementVersions, MapView, TruckMatrix
Setiap komponen secara lengkap
Gambar di sini statis, seperti story 'All Variants' di Storybook. Untuk mencoba props secara langsung, buka Storybook tiap aplikasi: di sana kodenya asli. Storybook Platform ditautkan di setiap bagian.
Menjalankan aksi. Satu tombol primary per area; sisanya secondary, outline, atau ghost.
sm
md
lg
icon
primary
Simpan
Simpan
Simpan
+
secondary
Simpan
Simpan
Simpan
+
outline
Simpan
Simpan
Simpan
+
ghost
Simpan
Simpan
Simpan
+
danger
Simpan
Simpan
Simpan
+
State. Saat loading, lebar tombol tetap.
default
hover
focus
disabled
loading
primary
Simpan
Simpan
Simpan
Simpan
Simpan
outline
Simpan
Simpan
Simpan
Simpan
Simpan
danger
Simpan
Simpan
Simpan
Simpan
Simpan
Prop (nama di Platform)
Nilai
Default
Catatan
variant
primary, secondary, outline, ghost, danger
primary
danger hanya untuk aksi yang menghapus atau tidak bisa dibatalkan.
size
sm, md, lg, icon
md
sm di tabel dan toolbar padat, lg untuk form lebar penuh ala mobile. icon = persegi, hanya ikon, wajib aria-label.
disabled
boolean
false
Opasitas 60%, tanpa hover.
asChild
boolean
false
Dirender sebagai link (react-router Link) dengan gaya tombol.
type
button, submit, reset
button
Lakukan
Label berupa kata kerja dalam bahasa Indonesia: 'Simpan', 'Tambah Truk', bukan 'OK'.
Bentuk pill (bulat penuh) di semua ukuran.
Di footer dialog: batal pakai outline, konfirmasi pakai primary atau danger. Urutan: lihat Dialog.
Loading: lebar tetap, Spinner menggantikan label, tombol dinonaktifkan.
Jangan
Jangan menambah warna lewat className. Tampilan baru = varian baru, disetujui desain.
Jangan memakai <button> mentah dengan gaya sendiri di halaman.
Perubahan di TMS
Hapus varian cta dan ctaFilled (sama dengan outline dan primary).
Tambah secondary, ukuran sm, md, lg, icon, dan loading.
Ganti <button> mentah di 65 file.
Catatan token: danger memakai #D04141 (teks putih 4.6:1). Button Platform merender bg-danger, yaitu #EF5350 (3.3:1, terlalu rendah untuk teks). Platform sebaiknya pindah ke token danger-strong.
Loading belum ada di Button Platform. Dicantumkan di sini supaya TMS dan Platform membuatnya dengan cara yang sama.
Menampilkan status sebuah data (order, dokumen, truk). Hanya teks, tidak bisa diklik.
Daftar status lengkap beserta labelnya menunggu topik review 4 (nama status). Label di bawah hanya contoh.
Draftneutral
Dalam Perjalananinfo
Selesaisuccess
Menunggu Konfirmasiwarning
Dibatalkandanger
Negosiasipurple
Prop (nama di Platform)
Nilai
Default
Catatan
variant
neutral, info, success, warning, danger, purple
neutral
Warna nadanya. Status mana dapat warna apa ditentukan oleh satu daftar bersama.
children
teks
Label status dalam bahasa Indonesia.
Lakukan
Warna punya arti: success = selesai, warning = menunggu pihak lain, danger = gagal atau batal, info = sedang berjalan, neutral = draf atau tidak aktif, purple = negosiasi.
Satu label per kode status, sama di semua aplikasi.
Pill, bergaris tepi, 13px medium, satu baris.
Jangan
Jangan memilih warna per halaman. Daftar status yang menentukan.
Jangan memakai warna hex langsung (StatusBadge Platform punya 18; pakai token badge).
Perubahan di TMS
Tetap menerima kode status, tapi warna dan label diambil dari daftar status bersama.
Menampilkan daftar data. Daftar memuat data berikutnya saat di-scroll (lihat daftar infinite scroll); tidak ada pager nomor halaman.
No. Order
Asal
Tujuan
Harga (Rp)
Status
ORM261029690002
Jakarta
Surabaya
12.500.000
Dalam Perjalanan
⋯
ORM261029080003
Bekasi
Semarang
8.200.000
Dibatalkan
⋯
ORM261029260006
Bandung
Cirebon
3.750.000
Selesai
⋯
Memuat data...
Baris terakhir: memuat data berikutnya saat pengguna scroll.
Prop (nama di Platform)
Nilai
Default
Catatan
header
array kolom
Label, perataan, bisa diurutkan.
data
array baris
onClickRow
function
Klik baris membuka detail.
handleSort
function
Ikon urut di header.
selectableRows, handleSelect
boolean, function
false
Kolom checkbox.
row border
DANGER, WARNING, SUCCESS
Garis tepi berwarna pada baris, untuk SLA atau masalah.
Lakukan
Header 12px semibold dengan latar abu muda; sel 12px, padding 16 x 12.
Angka dan uang rata kanan.
Status memakai StatusBadge, aksi berupa tombol ikon di ujung baris.
Di akhir daftar: baris loading saat memuat, lalu tidak ada apa-apa (tidak perlu teks 'habis').
Jangan
Jangan memakai #FAFAFA langsung (Table Platform punya 8 warna hex; pakai token tabel).
Perubahan di TMS
Hapus pager Prev/Next DataTable yang tidak dipakai; muat data saat di-scroll.
Pakai token tabel untuk warna header dan baris.
Field
Usulan dari TMS
Membungkus satu kontrol form beserta label, teks bantuan, dan pesan error, supaya semua form punya jarak dan posisi error yang sama.
Kapan error muncul (saat keluar dari isian atau saat submit) dan kapan hilang menunggu topik review 2. Platform belum punya Field: ini komponen TMS, diusulkan untuk keduanya.
Nomor Polisi *
B 1234 XYZ
Sesuai STNK.
Nomor Polisi *
Nomor polisi wajib diisi.
Kapasitas
12000Kg
Berat maksimal muatan.
Normal dengan teks bantuan, wajib diisi dengan error, dan dengan suffix satuan.
Prop (nama di Platform)
Nilai
Default
Catatan
label
teks
13px medium, di atas kontrol (Label Platform).
required
boolean
false
Tanda * merah setelah label.
help
teks
Baris abu-abu di bawah kontrol.
error
teks
Baris merah di bawah kontrol, menggantikan help. Kontrolnya memakai varian error.
wide
boolean
false
Melebar dua kolom di form dua kolom.
Lakukan
Setiap Input, Select, Textarea, dan unggahan berada di dalam Field.
Teks error menyebut apa yang harus diperbaiki: 'Nomor polisi wajib diisi', bukan 'Invalid'.
Help dan error memakai tempat yang sama di bawah kontrol, supaya tata letak tidak bergeser.
Jangan
Jangan menaruh label di samping kontrol di satu form dan di atas di form lain.
Jangan menampilkan error hanya lewat toast.
Perubahan di Platform
Tambah Field (membungkus Label) saat form berikutnya dibuat atau diubah.
Perubahan di TMS
Sudah punya Field. Sesuaikan nama props setelah Platform mengadopsinya.
Memilih satu nilai dari daftar tetap. Untuk daftar panjang atau perlu pencarian, pakai Combobox.
Pilih jenis trukplaceholder
Wingboxterpilih
Pilih jenis truktidak valid
WingboxPickup BoxWingboxTrontonTrailerterbuka
Platform hari ini: sudut 8px. Input di sebelahnya berbentuk pill (lihat catatan).
1200Wingbox
Prop (nama di Platform)
Nilai
Default
Catatan
SelectTrigger invalid
boolean
false
Garis tepi merah, sama seperti error Input.
SelectContent position
popper, item-aligned
popper
Daftar terbuka di bawah pemicu dengan lebar yang sama.
SelectItem
value, teks
Lakukan
Placeholder menyebut apa yang dipilih: 'Pilih jenis truk'.
Di dalam Field, sama seperti Input.
Jangan
Jangan memakai <select> bawaan dengan gaya sendiri.
Perubahan di TMS
Ganti select bawaan dengan select ala Radix (bits-ui) yang sesuai Platform.
Bentuk tidak seragam di Platform: Select berupa persegi membulat (8px, teks 12px semibold) sedangkan Input berbentuk pill (14px regular). Dalam satu baris form keduanya tidak sejajar. Desain perlu memilih satu bentuk untuk keduanya; gambar di atas menunjukkan Platform apa adanya.
Pesan yang tetap tampil selama suatu keadaan berlaku: dokumen ditolak, langkah yang belum selesai, peringatan tentang order.
Dokumen SIM ditolak. Unggah ulang sebelum 30 Okt.danger
Nada 'error': artinya sama dengan danger, tampilannya beda.error
Semua dokumen sudah diverifikasi.success
Order ini menunggu konfirmasi transporter.Lihat orderwarning
Lengkapi profil perusahaan untuk mulai menerima order.warningSoft
Prop (nama di Platform)
Nilai
Default
Catatan
tone
danger, error, success, warning, warningSoft
danger
icon
node
trailing
node
Aksi di kanan, misalnya 'Lihat' atau 'Batal'.
Lakukan
Tepat di atas area yang dibahas.
Tetap tampil sampai keadaannya berubah; tanpa tombol tutup kecuali hanya informasi.
Jangan
Jangan menggambar kotak berwarna sendiri per halaman.
Perubahan di TMS
Tambah StatusBanner; ganti kotak berwarna buatan sendiri.
Platform punya 5 nada untuk 4 arti: danger dan error tampil berbeda tapi artinya sama. Usulan: pertahankan danger, hapus error; putuskan apakah warningSoft tetap ada.
Memfilter daftar per status, dengan jumlah per status. Diletakkan di atas tabel.
Semua (24)Menunggu Konfirmasi (5)Dalam Perjalanan (12)Selesai (7)Dibatalkan (0)
Prop (nama di Platform)
Nilai
Default
Catatan
tabs
{ key, label, count }[]
count opsional.
activeKey
string
onChange
function
Lakukan
12px semibold; yang aktif teks gelap dengan garis biru 5px di bawahnya.
Bisa di-scroll ke samping di layar kecil (memudar di tepi).
Label memakai nama status dari daftar bersama.
Jangan
Jangan memakai #909090 langsung untuk teks tidak aktif (pakai token).
Perubahan di TMS
Ganti nama PillTab menjadi FilterTabs dan samakan tampilannya.
PageHeader
Usulan dari TMS
Baris judul di setiap halaman: ikon, judul, subjudul opsional, dan aksi halaman di kanan.
Platform belum punya PageHeader; judul halamannya datang dari shell (huruf kapital). Mana yang dipakai adalah topik review tentang judul halaman. Ini komponen TMS sebagai usulan.
▦
Daftar TrukKelola armada dan dokumen truk
ExportTambah Truk
Prop (nama di Platform)
Nilai
Default
Catatan
title
teks
icon
komponen
Kotak biru muda 44px.
subtitle
teks
actions
node
Tombol di kanan, primary paling akhir.
Lakukan
Setiap halaman punya satu, supaya pengguna selalu tahu posisinya.
Maksimal satu tombol primary di aksi.
Jangan
Jangan menulis judul sendiri per halaman dengan ukuran sendiri.
Perubahan di Platform
Putuskan bersama desain apakah halaman memakai PageHeader atau tetap judul dari shell.
Perubahan di TMS
Sudah punya PageHeader.
App shell
Bingkai di sekeliling setiap halaman: top bar navy, sidebar putih dengan menu ikon, area halaman.
karloGiga Transport · Admin
Orders / Spot Order
Diperkecil. Top bar 64px navy, sidebar 240px, item aktif pill biru muda, judul halaman huruf kapital.
Prop (nama di Platform)
Nilai
Default
Catatan
top bar
64px, navy
sidebar
240px, diciutkan 80px
nav item
pill, kotak ikon 30px
Hover dan aktif: biru muda.
page title
20px semibold huruf kapital
Level induk abu-abu lebih muda.
Lakukan
Bingkai sama di setiap aplikasi, supaya pengguna yang berpindah aplikasi tetap merasa familiar.
Grup sidebar terbuka di tempat; halaman aktif selalu ditandai.
Jangan
Jangan membuat navigasi kedua di dalam halaman.
Perubahan di TMS
Terapkan token shell: warna dan tinggi top bar, bentuk dan warna aktif item sidebar.
Shell ada di layout masing-masing aplikasi, bukan di library komponen. Nilainya di tokens/component/shell.json, diukur dari Platform.
Langkah berikutnya
Apa yang dikerjakan setiap kelompok, berurutan. Tidak ada yang saling menghambat.
Keputusan terbuka untuk PM dan desain
Empat pertanyaan yang hanya bisa dijawab PM dan desain, karena Platform sendiri punya lebih dari satu jawaban hari ini. Pertanyaannya ada di halaman review, lengkap dengan screenshot dan tempat menjawab.
Umpan balik setelah aksi
Toast, banner, atau popup, dan apakah ada yang boleh tanpa pesan?
Daftar infinite scroll: hapus pager DataTable yang tidak dipakai, muat data saat di-scroll seperti Platform.
Bagian fitur TMS: pindahkan ke folder fitur masing-masing.
Dibaca dari kode sumber Platform dan TMS pada 2026-11-02. Untuk nanti: aplikasi React baru (Vite, TypeScript, Tailwind) juga akan memakai design system ini. Bisa dimulai dari komponen inti Platform yang diubah ke TypeScript. Belum ada yang perlu dilakukan sekarang.