Aksesibilitas
Standar yang dipegang library ini, satu pengecualian yang tercatat, dan bagaimana semuanya dijaga test — bukan niat baik.
Standar
Sasarannya WCAG 2.2 level AA dan pola WAI-ARIA Authoring Practices untuk tiap jenis komponen. Dua hal itu bukan hiasan di halaman ini: setiap halaman dokumentasi dijalankan lewat axe di mode terang dan gelap sebagai bagian dari bun run check, dan satu pelanggaran menggagalkan suite.
Prinsip yang dipakai saat membuat komponen: pakai yang sudah disediakan browser lebih dulu — <dialog>, Popover API, <button> sungguhan, <a> sungguhan untuk navigasi. Perangkap fokus, urutan Tab, dan Escape yang benar lebih murah didapat dari platform daripada ditulis ulang (#002).
Keyboard
- Semua yang bisa diklik bisa dicapai dengan TabTab dan dijalankan dengan EnterEnter atau SpasiSpace.
- Kelompok pilihan — tab, segmen, menu, opsi select — punya satu perhentian Tab, lalu panah untuk berpindah di dalamnya. Itu pola WAI-ARIA, dan alasannya praktis: daftar 200 negara tidak boleh berarti 200 kali Tab.
- Fokus selalu terlihat: halo 3px berwarna kontrolnya sendiri, muncul saat fokus datang dari keyboard (
focus-visible), tidak saat diklik mouse. - Lapisan yang menyela mengembalikan fokus ke pemicunya saat ditutup. Panel yang sudah pergi tidak pernah meninggalkan fokus di
<body>. - EscapeEsc menutup apa pun yang mengapung, kecuali yang sengaja dibuat wajib diselesaikan (
dismissible: false).
Kontras
Semua pasangan warna diukur, bukan dikira-kira. Satu di antaranya tidak lolos AA, dan itu keputusan brand yang tercatat, bukan kelalaian.
| Pasangan | Terang | Gelap | AA (4.5:1) |
|---|---|---|---|
| Primary solid (putih di atas #1C9DBD) | 3.18 | 3.18 | Pengecualian brand |
| Neutral solid | 16.97 | 16.21 | Lolos |
| Success solid | 4.64 | 7.89 | Lolos |
| Warning solid (teks navy) | 7.90 | 10.16 | Lolos |
| Danger solid | 4.83 | 4.83 | Lolos |
| Teks primary (outline, ghost, link, soft) | 5.71 – 6.10 | 10.32 | Lolos |
| Isi halaman (content di atas surface) | 13.6 | 14.8 | Lolos |
| Teks redup (content-muted) | 5.41 – 5.80 | 6.20 | Lolos |
Pengecualian itu: teks putih di atas #1C9DBD mengukur 3.18:1. Warna itu warna resmi Waste4Change dan tombol primary memakainya apa adanya; menggelapkannya sampai lolos AA berarti tombol utama tidak lagi berwarna brand. Keputusannya diambil sadar (#008), dan konsekuensinya ditanggung: jangan memakai primary solid untuk teks kecil di bawah 14px, dan jangan menjadikannya satu-satunya penanda status. Kalau sebuah pesan harus terbaca oleh siapa pun dalam kondisi apa pun, pakai neutral atau varian soft yang teksnya jauh lebih kontras.
Pengecualian itu juga ditulis ke dalam test: helper axeViolations di e2e/utils.ts hanya memaafkan pasangan putih di atas #1c9dbd. Kegagalan kontras lain apa pun adalah bug yang menggagalkan suite.
Pola per komponen
Tiap komponen mengikuti pola WAI-ARIA untuk jenisnya. Ini daftarnya, supaya jelas apa yang sudah ditangani library dan apa yang tidak perlu ditambahkan sendiri:
| Komponen | Pola |
|---|---|
| Modal, Drawer, ConfirmDialog | <dialog> + showModal(): lapisan teratas, perangkap fokus, Escape, halaman jadi inert |
| FormSelect, FormPhone, CommandPalette | combobox + listbox + aria-activedescendant — fokus tetap di kolom ketik |
| DropdownMenu | menu button: aria-haspopup, panah, Home/End, typeahead |
| Tabs | tablist dengan roving tabindex, aktivasi otomatis atau manual |
| SegmentedControl | radiogroup: satu perhentian Tab, panah memilih |
| Popover | dialog non-modal: fokus masuk dan kembali, halaman tidak di-inert |
| Accordion | tombol yang menunjuk panelnya lewat aria-controls + aria-expanded |
| Table | th dengan scope dan aria-sort; seleksi baris memakai checkbox sungguhan |
| Timeline, Stepper | ol/li — urutan adalah bagian dari maknanya; Stepper menandai aria-current="step" |
| Toast, ConfirmDialog | role="status" untuk kabar, role="alertdialog" untuk pertanyaan yang menyela |
Yang tetap jadi tugas aplikasi
Komponen tidak bisa menjamin halaman yang memakainya bisa diakses. Empat hal ini tetap milik halaman:
- Nama yang berarti. Library menyediakan tempatnya (
label,aria-label) dan teks bawaan yang aman, tetapi hanya halaman yang tahu bahwa tombol itu menyalin kode referensi, bukan sekadar “salin”. - Urutan heading. Judul halaman
h1, sectionh2, dan seterusnya tanpa melompat. Komponen memakaih2–h6sesuai proptitleTag. - Kabar hasil tindakan. Simpan berhasil, filter diterapkan, unggahan selesai — umumkan lewat
W4cToastataurole="status"milik halaman. Progress melaporkan angka, bukan kabar. - Bahasa halaman. Setel
<html lang="id">, supaya pembaca layar melafalkan teks Indonesia dengan benar.