
How I Build: Using Storybook and Angular to make UI components in isolation

Aphinya Dechalert
Aphinya Dechalert is an Angular-heavy, full-stack developer embarking on a series of learning projects with defined outcomes, documented through Medium and LinkedIn.
As front-end developers, we've all experienced it in some form - the unwieldy task of keeping your coded visual assets in check. It's not too bad when you've just got a handful of elements. But when you've reached more than a dozen CSS rules, cascaded and single tree vertical inheritance, a wrong sequence or misplaced rule can lead to a visual disaster.
Then there's the task of catering to different screen sizes, devices, and styling framework. What is supposed to be a simple thing turns into an organizational nightmare.
This is CSS in a nutshell. There's spaghetti code, but nothing compares to spaghetti CSS. If only we had a centralized system that allowed us to just code each element individually, see it on the screen, and then plop it wherever we liked.
Frameworks like Bootstrap can solve this problem, but it's not the same. Sometimes, you just need custom elements. This is where Storybook comes in.
What is Storybook and why does it matter?
Storybook is an open-source tool that allows you to create UI components in isolation from your chosen front-end framework (including React, Angular, and Vue) – whilst having the ability to be fully integrated at the same time.
On the surface, it sounds like another Bootstrapping organizational tool, but it's not. With Bootstrap, you still need to translate and apply it to fit with the front-end framework. Styling is independent from the component. Changes to a component's structure or requirements can break the UI.
With Storybook, the component comes first and sits in isolation from the data and logical layers. In a way, Storybook adds an independent UI layer. It's sort of like how the service and data layers independently operate and only come together when called on. This process decouples the UI experiences from the rendering process. Rather than creating the components on the spot, you draw instead from a premade component library that you've developed.
How Storybook works with Angular
When it comes to Angular (my framework of choice), dealing with your UI components can quickly turn into a repetitive and fragmented process. It's easy to have components for everything, with repeated parts that draw from different data sources. This can leave you with dozens of UI component parts that are built almost identically but in fact do different things. For example, a button may encompass tasks such as sending a request to login, sign up, or cancel a process. The UI may need to be duplicated each time in their respective component CSS file.
It's inefficient but that's what we end up doing.
Storybook moves the UI away from the component. To help you understand Storybook faster, here is a comparison diagram of where the UI tool sits vs. the traditional default CSS setup.
The decoupling of the UI element from the UI layer makes each Storybook 'story' easier to use and build with.
So how do you add Storybook to your Angular app? It's as easy as adding Storybook to your Angular project.
# Navigate to your Angular project and add Storybook CLI
npx -p @storybook/cli sb init
npx -p @storybook/cli
will install Storybook CLI for your specific project. sb
becomes an executable command for Storybook. sb init
is the part that tells your CLI to set up your Angular app with Storybook.
Running sb init
will add a .storybook
file, which contains a config
file and a stories
folder under src.
.storybook/config.js
, you can change the context and move your stories folder out of your application src
code. This will decouple your visuals from your Angular code. However, by default, Storybook puts your stories folder inside your source code folder.#example for changing context out from src folder
#before
configure(require.context('../src/stories', true, \/.stories\.ts$/), module)
#after and repointing a different stories container folder
configure(require.context('../stories', true, \/.stories\.ts$/), module)
npm run storybook
.This will generate a storybook for you. It comes with a watch, so it will automatically reload if you make any changes in your code.
Creating your first Storybook story in Angular
In this part, we're going to create a hypothetical to-do story. What this will do is create a visual template with a checkbox, followed by a text.
import { storiesOf, moduleMetadata } from '@storybook/angular';
const todo: Todo = {
title: 'get groceries',
done: false
}
storiesOf('todo', module).addDecorator(moduleMetadata({
declarations: [TodoComponent]
})).add('todo not completed', () => {
return {
template: ' ',
props: {
todo
}
}
}).add('todo is completed', () => {
return {
template: ' ',
props: {
todo: {...todo, done: true}
}
}
})
In the above example, there are four parts to the code. The first two lines are your imports. Line four is setting up some mock data context for your stories.
Line nine sets up your actual stories with storiesOf(<storyName>, module)
.
The first method - addDecorator()
- allows you to wrap your stories with extra markup or context mocking. In the example above, we've done both. The first add()
creates a context called 'todo not completed', followed by a callback anonymous function that returns a template and some properties. The properties used for rendering in Storybook's view is the const
we set up earlier.
The second add()
creates the second context for the todo
story, where 'todo is completed', using a similar template but with different properties.
Final thoughts
There's a little bit more to Storybook but this is the general starter gist of it. You can wire in real data by importing the associated controller and linking it all up via event emitters. To use your Storybook stories in Angular, just import the story into your controller so you can pass it to your UI. Now you don't need to worry about keeping track of states and how each state change will impact the UI's appearance. All you have to do is ensure that the data passed is correct.
For me, Storybook has made the process of communicating with designers and non-developer people a lot easier. It strips away the 'noise' of code and creates a side document that can be used on the fly for presentations. This additional feature is something that all React, Vue, and other supported frontend frameworks and libraries can benefit from.
As your UI assets grow, the complexity of managing UI gets separated out. The generated Storybook stories can double up as a digital design document that allows developers, designers, and other business stakeholders to see exactly what everything looks like in context. All of this is done in isolation from the logical layers and process of UI composition.
Storybook allows your UI to become atomic and module by design, making it easier to deal with in the long run.
About Triplebyte
Triplebyte helps engineers find great jobs by assessing their abilities, not by relying on the prestige of their resume credentials. Take our 30 minute multiple-choice coding quiz to connect with your next big opportunity and join our community of 200,000+ engineers.