Storybook & Atomic Design - 1.13. - Building Our Homepage
by Jack Pritchard
Hey! Just so you know, this article is over 2 years old. Some of the information in it might be outdated, so take it with a grain of salt. I'm not saying it's not worth a read, but don't take everything in it as gospel. If you're curious about something, it never hurts to double-check with a more up-to-date source!
When building out pages with React and Storybook it is best to think of the page not as a component but as a high-level grouping wrapper.
The page concept should not have much, if any, custom logic within the component itself. Instead, it should rely on the styles and functionality that we've created in our smaller concepts (atoms, molecules, and organisms).
A login form should be an organism of it's own and imported to a login page.
A homepage shouldn't have any CSS tightly coupled to it, it should implement the styles found within the components themselves instead.
If you find yourself reaching for CSS or functions that you need for a page, first think about how you can build these in reusable components that aren't confined to the single page you are working on.
The homepage structure is very similar to the blog post template.
The main difference here is that the page doesn't include a Styled-Component as the parent wrapper of the page.
This is because, again, we don't want to tightly couple any styles associated with a page in our application. Doing so will prevent components from becoming reusable, and often creates tricky situations later when we have overriding styles fighting one another in our application.
import React from 'react';
import Banner from '../../organisms/banner/banner';
import Carousel from '../../organisms/carousel/carousel';
import Footer from '../../organisms/footer/footer';
import Header from '../../organisms/header/header';
To emulate how our page will act later on we'll need some JSON data to parse out into React components.
Again, if you've been following along this won't be new, we're using the Storybook knobs to create interactive fields for our page template, and separating the default values, labels and group ID for these fields into a JSON file.
{
"header": {
"default": {
"navigation": [
{
"title": "general",
"items": [
{
"icon": null,
"title": "Shop",
"url": "#"
},
{
"icon": null,
"title": "About Celtic Elements",
"url": "#"
},
{
"icon": null,
"title": "FAQ",
"url": "#"
},
{
"icon": null,
"title": "Contact",
"url": "#"
}
]
},
{
"title": "account",
"items": [
{
"icon": null,
"title": "Insights",
"url": "#"
},
{
"icon": null,
"title": "Account",
"url": "#"
},
{
"icon": "user",
"title": "User",
"url": "#"
},
{
"icon": "bag",
"title": "Cart",
"url": "#"
}
]
}
]
},
"group": "Global",
"label": "Header content"
},
"footer": {
"default": {
"menus": [
{
"title": "Menu 1",
"items": [{ "title": "Home", "url": "/" }]
},
{
"title": "Menu 2",
"items": [{ "title": "About", "url": "/" }]
},
{
"title": "Menu 3",
"items": [{ "title": "Contact", "url": "/" }]
}
]
},
"label": "Footer Content",
"group": "Global"
},
"banner": {
"content": {
"default": "Creating a Positive Day",
"group": "Banner",
"label": "Banner Content"
},
"cta": {
"default": {
"href": "#",
"label": "Call to action",
"target": null
},
"group": "Banner",
"label": "Banner Call to Action"
},
"title": {
"default": "Creating a Positive Day",
"group": "Banner",
"label": "Banner Title"
}
},
"carousel": {
"items": {
"default": [
{
"category": {
"href": "/category/beauty-routine",
"label": "Beauty routine"
},
"description": "Celtic Elements is a Welsh, Vegan, Wellness brand. We use Welsh natural ingredients from the hillsides & coast of Wales in our Skincare, Body care and Well being ranges.",
"description": "Celtic Elements is a Welsh, Vegan, Wellness brand. We use Welsh natural ingredients from the hillsides & coast of Wales in our Skincare, Body care and Well being ranges.",
"description": "Celtic Elements is a Welsh, Vegan, Wellness brand. We use Welsh natural ingredients from the hillsides & coast of Wales in our Skincare, Body care and Well being ranges.",
We can then import the JSON payload in our Page Template Storybook story and configure the `object'knob to give viewers of the component an input field to manipulate the prop data provided.
import React from 'react';
import { array, object, text } from '@storybook/addon-knobs';
import { withDesign } from 'storybook-addon-designs';
We now have a homepage built within our system which we can send to QA (Quality Assurance) stakeholders or designers for review.
The page has been built using modular, reusable components which means that if there is feedback on a component, we can update it in isolation and have the changes ripple throughout all of our developed pages, reducing the time required for feedback amends and creating a more flexible system.