After spending a little more than a decade, and had worked with vast variety products and projects, personally, I think atomic design be a prefect fit for scalable / long-term development.
To avoid wast your time, I would to address that atomic design implementation could be a overkill for known short term projects (less than 6 months), as I mentioned before frameworks like bootstrap and foundation would do just fine
Great, you are still reading.
In short, the implementation is a sorting process: Sorting components based on its atomic category.
Sorting the category of each component is the critical part of implementation. My team had ran in to major incorrect implementation of atomic design once, we ended up having massive refactoring and complex modification across multiple components.
In the retrospect, we had agreed that developers and designers shall work closely and shall figure out how components should be used before the development.
We had clarified sorting process as below:
We are limited to three main categories in atomic design: Atoms, Molecules and Organisms (since the Theme is unique for us), and sorting with structure and scope.
For the simple components, they could be easily sorted by their complexity (HTML structure).
Here is a quick checklist we generated to identify simple components:
-
Atoms: one element (HTML tag), no internal functions, may have style alterations, will always be used by Molecules and Organisms
-
Molecules: component that combined with multiple elements (HTML tags and/or atoms), but NOT consuming the full width (edge to edge) of device, and will be used by Organisms as a whole, may have internal functions (with Javascript), may have style and function alterations.
-
Organisms: similar to molecule, but it always consumes the full width of the device, always be a used at root level (direct child of the page)
If we stacked the required Organisms we will get Pages (in atomic design).
The reality is there will be complex components, and we will need to consider the scope of the components.
This is the part I mentioned earlier which tripped us, and cost us days in development.
Scope means the control area of the component, and components shall work independently. For instance, the padding
of components is in the scope, but the margin
set shall be controlled by its parent component (if it is necessary).
Only following this scope set, the components will be to achieve independent and be able to 'included' (consumed) as a whole by others.
Only in this way, the code base will be able to assemble reliable user interface function swiftly.
As I mentioned before, designers and developers shall clarify the way that the component works, which means things like how it should be included, different alterations and scope of each component in a large scale.
The list below demonstrates how we believe the component including should work in atomic design
-
Organisms can include other
organisms
molecules
atoms
-
Molecules can include other
molecules
atoms
-
Atoms can NOT include any other components
Now, let's take a close look at one mistake we made.
Incorrect scope sample
<div class="organism-a">
<div class="molecule-0">
<input class="organism-a__element" /> <!-- should not be here -->
<div class="molecule-1"></div>
<p class="atom"> text, just text</p>
</div>
</div>
Because the mixed scope modification (<input class="organism-a__element" />
inside of molecule-0
the molecule-0
), the code above is not reuseable as a whole.
Since we can not simply include molecule-0
.html in organism-a
and call it done, which is what atomic design component suppose to do.
No panic is needed, there are few solutions for this issue
It could be the case that the organism-a__element
is implemented in a inappropriate scope. Placing organism-a__element
out of molecule-0
could be one of the solutions. then add organism-a
alteration with js or other render language
<div class="organism-a">
<input class="organism-a__element"/><-- move out -->
<div class="molecule-0">
<div class="molecule-1"></div>
<p class="atom"> text, just text</p>
</div>
</div>
Or, it could be the case, that code base requires a state middleware (like Redux) to support passing data between components to support alteration of molecule-0
.
With the middleware, we could achieve the desired style changes or function calls via data communication.
In other words, replacing organism-a__element
with molecule-0__element
and implement the update via data would solve the problem.
<div class="organism-a">
<div class="molecule-0">
<input class="molecule-0__element" /> <!-- update style via data -->
<div class="molecule-1"></div>
<p class="atom"> text, just text</p>
</div>
</div>
With correct categorization, the scope of component in code base would be independent from each other.
Now we could go further and improve our code base folder structure for scaling with packaging.
We could follow the Separation of concerns, and placing code and files in one package friendly file structure. When scaling process kick in, it is super easy to break down the code base.
Below is a sample package friendly file structure.
src
|- atoms
| |- button
| | |- index.css
| | |- index.html
| |- typography
...
|- molecules
| |- search-bar
| | |- index.html
| | |- index.js
| | |- index.css
...
|- organisms
...
Here is how we could scale this package structure for all online services:
-
The whole
atoms
folder could isolated and shipped as the base npm package for supporting all higher level packages. -
Each component in
molecules
folder could be separated as an individual npm package (or as one package) and useatoms
package as its dependency. -
Same as molecules packages, each organism could be exported as a npm packages.
Once we achieved package structure, this library of npm packages is ready to be imported into any related online services development.
From this point on, we will have a consistent styled components with shared code packages. We will be able to fix issues across the multiple platforms with one source packages update.
Finally, we could focus on building new component packages and updating existing library, instead of maintaining same fix patch in multiple places.
That will dramatically improve the working satisfaction and and reduce develop cycle.