formdecorationinputMenengah4 mnt baca

InputDecoration

Percantik input: label, hint, icon, border, dan pesan error.

Kenapa InputDecoration Penting?

Input polos (kotak abu-abu tanpa label) membuat user menebak-nebak: field apa ini, formatnya bagaimana, dan kenapa error. InputDecoration menjawab semuanya dalam satu tempat: label, contoh format, ikon, sampai pesan error.

dart
TextField(
  decoration: InputDecoration(
    labelText: 'Email',
    hintText: '[email protected]',
    prefixIcon: const Icon(Icons.email),
    suffixIcon: IconButton(
      icon: const Icon(Icons.clear),
      onPressed: () => _emailController.clear(),
    ),
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(12),
    ),
    filled: true,
    fillColor: Colors.grey[100],
  ),
)

Label vs Hint: Jangan Tertukar

  • labelText: mengambang ke atas saat field fokus atau terisi, jadi selalu terlihat. Ini identitas field.
  • hintText: contoh format, hilang begitu user mengetik. Ini bantuan sementara.

Aturan aksesibilitasnya sederhana: jangan pakai hint sebagai pengganti label untuk field wajib. Saat user mengetik, hint hilang dan mereka lupa sedang mengisi field apa. Screen reader pun lebih mengandalkan label.

Untuk teks bantuan yang tidak boleh hilang, pakai helperText (misalnya "Minimal 8 karakter, campur huruf dan angka").

Border untuk Setiap State

Field punya beberapa kondisi visual, dan tiap kondisi bisa punya border sendiri:

dart
InputDecoration(
  labelText: 'Password',
  enabledBorder: OutlineInputBorder(
    borderRadius: BorderRadius.circular(12),
    borderSide: const BorderSide(color: Colors.grey),
  ),
  focusedBorder: OutlineInputBorder(
    borderRadius: BorderRadius.circular(12),
    borderSide: const BorderSide(color: Colors.deepPurple, width: 2),
  ),
  errorBorder: OutlineInputBorder(
    borderRadius: BorderRadius.circular(12),
    borderSide: const BorderSide(color: Colors.red),
  ),
  focusedErrorBorder: OutlineInputBorder(
    borderRadius: BorderRadius.circular(12),
    borderSide: const BorderSide(color: Colors.red, width: 2),
  ),
)

Daripada mengulang di setiap field, set sekali secara global:

dart
MaterialApp(
  theme: ThemeData(
    inputDecorationTheme: InputDecorationTheme(
      border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
      filled: true,
      fillColor: Colors.grey[100],
      contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
    ),
  ),
)

Catatan teknis: errorText yang di-set manual akan menimpa pesan error dari validator pada TextFormField. Pilih satu: validasi otomatis via validator, atau error manual via errorText untuk kasus seperti error dari server.

Contoh Nyata: Field Password dengan Toggle

dart
bool _sembunyi = true; // di State

TextField(
  obscureText: _sembunyi,
  decoration: InputDecoration(
    labelText: 'Kata Sandi',
    hintText: 'Minimal 8 karakter',
    prefixIcon: const Icon(Icons.lock_outline),
    suffixIcon: IconButton(
      icon: Icon(_sembunyi ? Icons.visibility : Icons.visibility_off),
      onPressed: () => setState(() => _sembunyi = !_sembunyi),
    ),
    border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
  ),
)

Edge Case yang Sering Terjadi

  • Layout melompat saat error muncul: pesan error menambah tinggi field sehingga form "melompat". Atasi dengan memberi ruang tetap: bungkus field dalam SizedBox/Container dengan tinggi cukup, atau set errorStyle dengan tinggi baris kecil.
  • Suffix icon menutupi teks panjang: beri contentPadding kanan yang cukup agar teks tidak tertutup ikon.
  • counterText: maxLength otomatis menampilkan counter "3/16". Kalau tidak mau, set counterText: '' (bukan menghapus maxLength, supaya batas tetap jalan).
  • Dense untuk form padat: isDense: true + contentPadding kecil membuat form admin/data-entry lebih ringkas tanpa custom widget.

Kapan JANGAN Berlebihan

Dekorasi yang konsisten lebih penting daripada dekorasi yang ramai. Hindari: warna border berbeda-beda tiap field, terlalu banyak ikon dekoratif yang tidak punya fungsi, dan radius border yang tidak konsisten. Satu inputDecorationTheme global biasanya mengalahkan 20 dekorasi manual yang berbeda-beda.

Tantangan

Field password rapi

Buat TextField password dengan labelText 'Kata Sandi', prefixIcon lock, suffixIcon visibility yang toggle obscureText, dan border rounded 12.