Design System v0.6.0

Komponen

Komponen guest-side

Setiap contoh di halaman ini adalah komponen Svelte asli dari src/lib, bukan tiruan. Semuanya membungkus kelas vc- yang hanya membaca token. Geometri mengikuti komponen di kode; peta ke file-nya ada di bagian Keputusan. Teks specimen memakai bahasa UI produk (Inggris); angka dan nama memakai placeholder.

Pemakaian

// +layout.svelte (sekali)
import '@vilacation/designkit/styles.css';

// komponen
import { Button, VillaCard, TabBar } from '@vilacation/designkit';

Font (Fraunces dan Montserrat) tidak ikut dibundel; frontend sudah memuatnya lewat @fontsource-variable. Harga, tanggal, dan teks dikirim sudah diformat dari pemanggil: kit tidak mengarang atau memformat data.

Button

Varian

Ukuran

State

Brand, Outline, dan Link adalah tiga varian Button di mobile (ui/button.tsx); Primary navy adalah tombol Sign In di web. Brand persis aslinya (teal-500 dengan teks putih), kontrasnya 2.16:1. Accent adalah pasangan aman (teal-800, 4.88:1). Outline di kit memakai teks teal-800 karena aslinya teks teal-500 di atas putih (2.16:1). Satu tombol utama per layar. Isi href untuk merender sebagai tautan.

Header

Tinggi 64px di mobile dan 88px mulai 768px (sama dengan --site-header-height). Prop transparent untuk di atas foto hero. Logo dimuat dari URL; kalau gagal, tampil teks pengganti.

Search bar

Komponen signature. Persempit jendela di bawah 768px untuk melihat versi mobile (segmen bertumpuk, tombol Search lebar penuh). Memakai shadow float yang sama dengan nav bawah, karena sama-sama mengambang. Isi destination, dates, dan guests dengan teks yang sudah diformat; kosong menampilkan placeholder.

Field

Helper text goes here.

Enter a complete email address.

Tinggi 48px, font 16px (mencegah auto-zoom di iOS). Error ditandai warna dan teks bantu, tidak warna saja. Fokus memakai outline teal-600. Label, id, dan aria-describedby dihubungkan otomatis.

Chip & badge

Chip (bisa diklik)

Badge status booking (usulan label, cocokkan dengan status backend)

Pending host Awaiting payment Confirmed Payment failed Completed Cancelled

Alert

Info Neutral information that helps the guest decide.
Success Confirmation of something that already happened.
Warning Something needs attention before it becomes a problem.

Villa card

Tiga state: default (tombol hati interaktif), sold out (opacity 65%, sama dengan kode), dan skeleton. Geometri dari home-property-card.tsx: foto radius 14, judul 13px bold, lokasi 12px, label "Price before tax" 11px, harga Fraunces 14px/800. Tombol hati memakai putih 92% (bukan blur). Badge "Instant" di web memakai emoji api; di kit diganti teks, tanpa emoji. Tidak ada komponen rating sampai ada data review nyata. Catatan kontras: harga (2.98:1), lokasi dan label (3.10:1), dan badge Sold Out (3.76:1) mengikuti nilai asli di kode. Isi image untuk foto asli.

Guest stepper

Adults

Optional hint text

2

Children

Optional hint text

0

Interaktif. Tombol menonaktifkan diri di batas min dan max; batas sebenarnya datang dari kapasitas villa, bukan dari kit.

Date range calendar

November 2026

Mo
Tu
We
Th
Fr
Sa
Su

Interaktif (klik awal lalu akhir). Tanggal tidak tersedia ditandai coret dan nonaktif, ilustrasi saja: kit tidak memvalidasi rentang yang melewati tanggal tidak tersedia, itu tugas logika booking. Minggu dimulai Senin. start, end, dan month bisa di-bind.

Price summary

Rp X.XXX.XXX × [N] nightsRp X.XXX.XXX

Fee nameRp X.XXX.XXX

TaxesRp X.XXX.XXX

TotalRp X.XXX.XXX

Rincian dan total selalu terlihat sebelum pembayaran. Komponen fee dan pajak mengikuti kebijakan harga sebenarnya; di sini hanya struktur.

Nav bawah mengambang (mobile)

Pil mengambang, bukan bar penuh: radius 30, border tipis, shadow float, item aktif berlatar teal-50 dengan teks dan ikon teal-600 (geometri dari MobileNav.svelte dan bottom-navbar.tsx). Empat tujuan: Home, Explore, Messages, Profile; Messages dan Profile meminta login, tahan lewat onnavigate dengan event.preventDefault(). Di produk pakai prop fixed (menempel 12px dari bawah plus safe area, hilang ≥ 768px). Angka "3" pada badge hanya contoh tampilan.

Modal dan Drawer

Modal mengikuti AuthDialog.svelte: lebar 480 (560 untuk form panjang), radius 30, header berlatar teal-25. Drawer mengikuti SearchFilterDrawer.svelte: penuh layar di mobile, panel 448px mulai 640px. Keduanya: Escape dan klik scrim menutup, fokus pindah ke dialog (bukan ke field, supaya keyboard layar sentuh tidak langsung muncul), fokus kembali ke pemicu saat ditutup, scroll halaman dikunci. Scrim memakai warna solid, tanpa blur.

Toast

Tampilan statis

Saved to wishlist

Warna dan perilaku dari ToastContainer.svelte: hilang sendiri setelah 5 detik, tumpukan di atas tengah (maks 400px), role="alert" hanya untuk error. Pasang <ToastContainer /> sekali di layout root; panggil toasts.show({ type, title }) dari mana saja.

Checkbox, Switch, Counter

AdultsAge 13 or above
2

Area sentuh 44px. Kotak centang dan switch terisi teal-800 (lulus AA dengan tanda putih). Counter memakai IconButton, dan tombol kurang/tambah nonaktif di batas min/max.

Tabs

Tab terpilih: overview. Panah kiri/kanan berpindah tab. Untuk konten di dalam halaman; navigasi utama tetap TabBar.

EmptyState

No stays match your filters

Try other dates or remove a filter.

Bottom sheet

Drawer dengan side="bottom": menempel di bawah, sudut atas radius 30, ada pegangan kecil, tinggi maksimum 88% layar. Mulai 640px dipusatkan selebar 560px. Perilaku sama dengan Drawer samping.

PhotoGallery

Mengikuti PropertyGalleryDrawer.svelte: kategori, foto utama dengan panah dan penghitung, lalu semua foto sebagai thumbnail. Tanpa src tampil kotak bernomor (foto di sini belum ada). Biasanya dibungkus Drawer atau Modal. Panah 44px, thumbnail aria-pressed.

Peta: bingkai dan penanda

Atribusi penyedia peta

Kit tidak membundel peta. Frontend memakai Leaflet; MapFrame hanya bingkai dan atribusi, MapMarker penanda harga yang bisa dipasang di penyedia mana pun. Penanda memakai teal-800 (teal-600 dengan teks putih 11px hanya 2.98:1 di kode), aktif berlatar ink-900. Popup memakai kelas vc-map-popup. Penyedia dan lisensi tile perlu diputuskan dev team: frontend saat ini memuat tile dari mt1.google.com langsung.

Pola validasi form

Aturan: validasi saat submit, bukan saat mengetik. Setiap field salah mendapat pesan di bawahnya (Field error, ditandai warna, ikon, dan teks), plus ringkasan di atas form yang menerima fokus dan menaut ke tiap field. Isian tidak dihapus saat gagal.

Header dengan navigasi desktop

Prop links menampilkan navigasi horizontal mulai 768px; di mobile navigasi tetap TabBar. Tautan aktif teal-800 dengan garis bawah teal-600.