Flutterexperts

Empowering Vision with FlutterExperts' Expertise
Design System with Atomic Design in Flutter

One of the most widely used methods for design teams to arrange and maintain the modules and components they utilise is atomic design. This file structure methodology separates each page’s components.

This blog will explore the Design System with Atomic Design in Flutter. We see how to execute a demo program in your applications.

If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.


Table Of Contents:

What is a Design System?

What is an Atomic Design?

Why does Flutter require System Design?

How does it contribute to the creation of more testable code?

What benefits does Atomic Design offer a design system?

How to implement in Flutter?

Conclusion



What is a Design System?:

A design system is a group of reusable parts, rules, and ideas that guarantee UI design and development is scalable, consistent, and efficient. It emphasises a product or group of products’ visual appeal, usability, and interface coherence.

Consider the design system as an internal product of the business rather than a project, and as such, it requires updating when new components, solutions, and style guides are created. Text tone of voice, branded application concepts, rounded buttons, and code snippets.

What is an Atomic Design?:

Atomic design is a methodology that helps us to think about the user interface in a hierarchical approach and stresses the relevance of the quality of effective pattern libraries, presenting strategies to optimize the workflow of design and development in a team. You can construct user interfaces (UIs) with greater consistency and quality by using atomic design, which also describes what occurs during the development and upkeep of design systems.

Atomic design is a conceptual model that helps us think of our user interfaces as both a collection of elements and a coherent whole at the same time. It is not a linear process.

Why does Flutter require System Design?

The versatility of Flutter’s custom widget creation frequently results in redundant components and misunderstandings regarding widget granularity. Grouping widgets by page, app-wide, or a combination of both may be difficult for teams to decide. Because they are afraid of damaging current implementations or leaving out functionalities, new members may design their widgets.

By providing pre-defined, reusable components that adhere to design rules, encouraging modularity, and minimising redundancy, a design system helps to alleviate these problems. The declarative structure of Flutter makes it even easier to develop design systems, facilitating the efficient propagation of changes throughout the application and improving scalability, maintainability, and testability.

How does it contribute to the creation of more testable code?:

By dividing the user interface (UI) into discrete, modular components that are separate from the business logic of the application, design systems improve testability. Design systems serve as a UI API that the application can use, in contrast to conventional solutions where widgets communicate directly with business logic.

Widgets may be constructed separately from logic thanks to this division, which makes it easier to test with custom data, streamlines the procedure, and guarantees more dependable, maintainable code. Although this may seem too wonderful to be true, we will see how it turns out in the article’s following sections.

What benefits does Atomic Design offer a design system?:

  1. Reusable Components — You can have the components you need for any design problem by building your library. Additionally, it’s quite easy to mix and match the components.
  2. Layout that’s easy to comprehend and maintain — Atomically built applications typically have considerably easier-to-read code than more conventionally structured ones. This holds both throughout the construction process and later on when the application is being examined for reference or small adjustments.
  3. Fewer components overall – Developers are more likely to utilise pre-existing components rather than generating new ones for slight modifications if they are shown a list of atoms, molecules, and organisms before they begin working on an application.

How to implement in Flutter?

In the hierarchy of our interface design systems, each of the five phases is essential. Let’s examine each step in further detail.

1. Atoms:

The tiniest UI building blocks are called atoms. These widgets are straightforward, reusable, and independent of other elements.

// Atom demo
class CustomTextFieldAtom extends StatelessWidget {
  final String labelText;
  final TextEditingController controller;
  final bool obscureText;
  final TextInputType keyboardType;
  final String? Function(String?)? validator;
  final IconData? prefixIcon;

  const CustomTextFieldAtom({
    required this.labelText,
    required this.controller,
    this.obscureText = false,
    this.keyboardType = TextInputType.text,
    this.validator,
    this.prefixIcon,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      controller: controller,
      obscureText: obscureText,
      keyboardType: keyboardType,
      validator: validator,
      decoration: InputDecoration(
        labelText: labelText,
        prefixIcon: prefixIcon != null ? Icon(prefixIcon) : null,
        border: const OutlineInputBorder(),
      ),
    );
  }
}

2. Molecules:

Atomic combinations that cooperate to carry out a task are called molecules. They frequently contain tiny, reusable UI components and are a tad more complicated.

// Molecule demo: A search input
class SearchInputMolecule extends StatelessWidget {
  final String labelText;
  final Function(String)? onSearch;
  final TextEditingController controller;

  const SearchInputMolecule({
    Key? key,
    required this.labelText,
    this.onSearch,
    required this.controller,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        GestureDetector(
          onTap: () => onSearch?.call(controller.text),
          child: CustomIcon(Icons.search),
        ),
        SizedBox(width: 10),
        Expanded(
          child: CustomTextField(
            controller: controller,
            decoration: InputDecoration(
              labelText: labelText,
            ),
          ),
        ),
      ],
    );
  }
}

3. Organisms:

Groups of molecules and/or atoms that make up a certain area of the interface are called organisms. Usually, they stand in for more substantial, independent UI elements.

// Organism demo: A search card
class SearchCardOrganism extends StatelessWidget {
  final String labelText;
  final Function(String) onSearch;
  final List<String> recentSearches;
  final TextEditingController controller;

  const SearchCardOrganism({
    Key? key,
    required this.labelText,
    required this.onSearch,
    required this.controller,
    this.recentSearches = const [],
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 4,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          SearchInputMolecule(
            labelText: labelText,
            onSearch: onSearch,
            controller: controller,
          ),
          if (recentSearches.isNotEmpty)
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Wrap(
                spacing: 8,
                children: recentSearches
                    .map((search) => ActionChip(
                          label: Text(search),
                          onPressed: () {
                            controller.text = search;
                            onSearch(search);
                          },
                        ))
                    .toList(),
              ),
            ),
        ],
      ),
    );
  }
}

4. Template:

Templates combine creatures to provide a page with its skeleton or structure. The layout is specified, but specific content is left to be added later.

class SearchPageTemplate extends StatelessWidget {
  final String pageTitle;
  final String searchLabel;
  final Function(String) onSearch;
  final TextEditingController searchController;
  final List<String> recentSearches;

  const SearchPageTemplate({
    Key? key,
    required this.pageTitle,
    required this.searchLabel,
    required this.onSearch,
    required this.searchController,
    this.recentSearches = const [],
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(pageTitle),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: SearchCardOrganism(
              labelText: searchLabel,
              onSearch: onSearch,
              controller: searchController,
              recentSearches: recentSearches,
            ),
          ),
         // Body Widgets     
        ],
      ),
    );
  }
}

5. Page:

The last step is creating pages, where particular data is entered into templates to produce completely functional screens. They serve as a representation of the real user interface that the user uses.

class ProductSearchPage extends StatefulWidget {
  @override
  _ProductSearchPageState createState() => _ProductSearchPageState();
}

class _ProductSearchPageState extends State<ProductSearchPage> {
  final TextEditingController _searchController = TextEditingController();
  List<String> _recentSearches = [];
  List<Product> _searchResults = [];

  void _handleSearch(String query) {
    setState(() {
      // Update recent searches
      if (!_recentSearches.contains(query)) {
        _recentSearches.insert(0, query);
        if (_recentSearches.length > 5) {
          _recentSearches = _recentSearches.take(5).toList();
        }
      }

      // Perform search logic
      _searchResults = _performProductSearch(query);
    });
  }

  List<Product> _performProductSearch(String query) {
    // Simulated search logic
  }

  @override
  Widget build(BuildContext context) {
    return SearchPageTemplate(
      pageTitle: 'Product Search',
      searchLabel: 'Search Products',
      onSearch: _handleSearch,
      searchController: _searchController,
      recentSearches: _recentSearches,
      resultWidget: ListView.builder(
        itemCount: _searchResults.length,
        itemBuilder: (context, index) {
          final product = _searchResults[index];
          return ListTile(
            title: Text(product.title),
            subtitle: Text('\$${product.price}'),
          );
        },
      ),
    );
  }
}

Conclusion:

In the article, I have explained the  Design System with Atomic Design basic structure in a flutter; you can modify this code according to your choice. This was a small introduction to the  Design System with Atomic Design in Flutter, On User Interaction from my side, and it’s working using Flutter.

I hope this blog will provide you with sufficient information on trying the Design System with Atomic Design in Flutter in your projects. When used with Flutter, the atomic design pattern and design systems offer a streamlined and effective method for creating modular, scalable, and testable user interfaces. The interface can be made consistent, less redundant, and easier to design, and reusable parts: atoms, molecules, creatures, templates, and pages.

We can create Flutter apps that are both technically sound and aesthetically pleasing by fusing the strength of design systems with atomic design principles. Using this method will surely improve your development workflow, making your codebase more structured, reusable, and future-proof, regardless of how big or small your project is. So please try it.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.


Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire Flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on FacebookGitHubTwitter, and LinkedIn.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.


Leave comment

Your email address will not be published. Required fields are marked with *.