Storybook & Atomic Design - 1.9. - Building Our Navigation
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!
In this lesson, we'll be building our Navigation component.
The Navigation component falls under the concept of a molecule, as it will hold many children nodes of the classification atom (links, list items, buttons).
Initially, we will focus on passing one prop to our Navigation component. The prop will be -
direction - string
items - array
For each array item in our `items'props we can expect an object with the following keys -
We will want to create the Navigation component in a new directory under components, molecules then navigation. This directory will house the component itself, the associated stories and styled-components logic.
Our navigation component accepts two props, one for the styled direction of the navigation items and one that contains an array of objects to return a group of anchor elements.
The first prop is named
direction'and will be a string, the second named
items'which is an array we can map over to return several anchor tag elements within our styled `nav'element.
First, we destructure the props passed and extract the named values of
direction'and
items`.
Our component will immediately return our Styled-Component `StyledNavigation'which we defined above.
Within our Styled-Component children, we loop through every node available within our array.
For every node we find, we are then immediately destructuring the keys of the node object and extracting named values for
title'and
url`.
We then use an arrow function to pass these values into a return statement which will return an anchor HTML element with the href property set to the value of
url'and finally using the
title'value as the inner text of the anchor tag.
import React from 'react';
import StyledNavigation from './navigation.styles';
const Navigation = ({ direction, items }) => (
<StyledNavigation direction={direction}>
{items.map(item => (
<a href={item.url}>{item.title}</a>
))}
</StyledNavigation>
);
To keep consistency with our other components and to ensure the Navigation component accepts a valid array of values, we will define the propTypes our component should expect.
As we are defining an array of objects, we will use a new syntax to define a complex set of props using
arrayOf'and
shape'to tell our component to expect an array of objects with specific keys.
arrayOf'tells the component to accept an array for
items`.
shape'allows us to create a custom structure which in this case is an object of keys
title'and `url'both of the type string.
import React from 'react';
import { arrayOf, shape, string } from 'prop-types';
import StyledNavigation from './navigation.styles';
const Navigation = ({ direction, items }) => (
<StyledNavigation direction={direction}>
{items.map(item => (
<a href={item.url}>{item.title}</a>
))}
</StyledNavigation>
);
// Expected prop values
Navigation.propTypes = {
direction: string.isRequired,
items: arrayOf(
shape({
title: string.isRequired,
url: string.isRequired,
}),
),
};
// Default prop values
Navigation.defaultProps = {
direction: 'horizontal',
items: [],
};
export default Navigation;
As we haven't used any of the reserved names of
arrayOf
,
shape
, or
string'for any other values in our component, we can destructure these named values from our
prop-types'package using the following.
import { arrayOf, shape, string } from 'prop-types';
With the new values available to us, we can remove any references to `PropTypes'in our type definitions.
import React from 'react';
import { arrayOf, shape, string } from 'prop-types';
import StyledNavigation from './navigation.styles';
Now we have a type defined navigation component which will return a navigation list dynamic to the data it receives as props.
In a future lesson, we'll revisit this component to add responsive styles, but for now, we've got a working navigation molecule that we can use in our Footer and Header organisms.