thumnail

Membangun Flutter Project dengan Konsep Atomic Design

Fri, March 2025 09:54:07

Dalam pengembangan aplikasi, menjaga struktur kode agar tetap rapi, reusable, dan mudah di-maintain adalah hal yang sangat penting. Salah satu pendekatan desain yang populer adalah Atomic Design. Konsep ini awalnya diperkenalkan oleh Brad Frost dan banyak diadaptasi ke berbagai framework, termasuk Flutter. Artikel ini akan membahas secara mendalam bagaimana menerapkan konsep Atomic Design di Flutter, lengkap dengan contoh kode dan penjelasan langkah demi langkah.

Apa Itu Atomic Design?

Atomic Design adalah metode untuk membangun UI secara bertahap, dengan membagi komponen menjadi bagian kecil yang bisa digunakan ulang. Konsep ini dibagi ke dalam lima level utama:

  1. Atom — Komponen paling kecil yang tidak bisa dipecah lagi, seperti teks, tombol, ikon, atau input field.
  2. Molecule — Gabungan dari beberapa atom yang bekerja bersama, misalnya input field dengan ikon.
  3. Organism — Kombinasi dari molekul dan atom yang membentuk bagian UI yang lebih besar, seperti form login.
  4. Template — Struktur halaman tanpa data spesifik, hanya layout saja.
  5. Page — Halaman penuh yang berisi komponen yang sudah diisi data.

Dalam implementasi di Flutter, kita akan lebih banyak berfokus pada Atom, Molecule, dan Organism agar lebih efisien dan reusable.


Struktur Folder

Agar proyek lebih terorganisir, kita mulai dengan menyiapkan struktur folder yang sesuai dengan konsep Atomic Design:

/lib
  └── components
      ├── atoms
      │   ├── custom_button.dart
      │   ├── custom_text.dart
      │   └── custom_icon.dart
      │
      ├── molecules
      │   └── custom_textfield.dart
      │
      └── organisms
          └── login_form.dart

  └── pages
      └── login_page.dart

Dengan struktur ini, setiap level desain punya tempat tersendiri. Ini akan mempermudah kita saat ingin mencari atau mengubah komponen tertentu.


Membuat Komponen Atom

Kita mulai dengan membuat komponen dasar di folder atoms. Komponen ini akan sering digunakan di berbagai tempat.

custom_button.dart

import 'package:flutter/material.dart';

class CustomButton extends StatelessWidget {
  final String text;
  final VoidCallback onPressed;

  const CustomButton({
    Key? key,
    required this.text,
    required this.onPressed,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(
        padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
      ),
      child: Text(
        text,
        style: TextStyle(fontSize: 16),
      ),
    );
  }
}

Komponen ini adalah atom yang hanya menerima teks dan fungsi onPressed. Kita bisa memakainya di banyak tempat tanpa perlu menulis ulang.


Membuat Komponen Molecule

Selanjutnya kita buat molekul, yaitu gabungan beberapa atom yang membentuk komponen lebih kompleks. Misalnya TextField yang dilengkapi dengan ikon visibility untuk password.

custom_textfield.dart

import 'package:flutter/material.dart';

class CustomTextField extends StatefulWidget {
  final String label;
  final bool isPassword;
  final TextEditingController controller;

  const CustomTextField({
    Key? key,
    required this.label,
    required this.controller,
    this.isPassword = false,
  }) : super(key: key);

  @override
  _CustomTextFieldState createState() => _CustomTextFieldState();
}

class _CustomTextFieldState extends State<CustomTextField> {
  bool _isObscured = true;

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: widget.controller,
      obscureText: widget.isPassword ? _isObscured : false,
      decoration: InputDecoration(
        labelText: widget.label,
        suffixIcon: widget.isPassword
            ? IconButton(
                icon: Icon(
                  _isObscured ? Icons.visibility_off : Icons.visibility,
                ),
                onPressed: () {
                  setState(() {
                    _isObscured = !_isObscured;
                  });
                },
              )
            : null,
        border: OutlineInputBorder(),
      ),
    );
  }
}

Molekul ini lebih kompleks karena memiliki logika state sendiri. Kita bisa memakainya di form yang butuh input dengan ikon.


Membuat Komponen Organism

Sekarang kita gabungkan molekul dan atom ke dalam organism yang lebih besar. Misalnya form login lengkap.

login_form.dart

import 'package:flutter/material.dart';
import '../atoms/custom_button.dart';
import '../molecules/custom_textfield.dart';

class LoginForm extends StatelessWidget {
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        CustomTextField(
          label: "Email",
          controller: emailController,
        ),
        SizedBox(height: 16),
        CustomTextField(
          label: "Password",
          controller: passwordController,
          isPassword: true,
        ),
        SizedBox(height: 24),
        CustomButton(
          text: "Login",
          onPressed: () {
            print("Login dengan: \${emailController.text}");
          },
        ),
      ],
    );
  }
}

Membuat Halaman Utama

Sekarang kita buat halaman utama yang memanggil organism LoginForm.

login_page.dart

import 'package:flutter/material.dart';
import '../components/organisms/login_form.dart';

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login Page')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Center(child: LoginForm()),
      ),
    );
  }
}

Kesimpulan

Dengan menerapkan konsep Atomic Design di Flutter, kita bisa:

Atomic Design membuat kode lebih bersih dan profesional. Apakah kamu tertarik menerapkan ini di proyek Flutter kamu? Selamat mencoba dan semoga berhasil membangun aplikasi yang scalable dan maintainable.