Building a Design-Driven Workflow in Storybook.js with Angular and Sketch – Part 1
Crafting a good and consistent user experience for your product is hard work and requires a lot of dedication. Therefore setting up a bullet-proof workflow that keeps everyone in the team in the right mindset is key.
What we’ll be doing
The goal of this series is to give you an idea of what Storybook is and how to set it up in your Angular project. I’ll go into a bit of detail about why and how I think this process helps in creating a shared context for your team, as well. At the end of this post, you’ll have an instance of Storybook up and running, wired up to your Angular project.
For your convenience, I’ve prepared a GitHub repository that you can check
Assembling A Team
The most crucial of every good design workflow is getting everyone on board. A lot of confusion, redesigns and respeccing can be easily avoided by offering everyone a seat at the table in the first place. I, for one, like to invite at least one member of each department to my UX workshops. Now, this might sound like endless discussions and disagreements to you at first. But the reality is, if you respect everyone equally and treat their opinions with the importance they deserve, you are going to find lasting consensus quite easily.
Removing Layers of Abstraction
Most of the projects I’ve worked on in the past used an established setup, keeping everyone working on the visual parts of the product in their respective tooling comfort zone:
- Designers: Sketch/Figma/Adobe XD, InVision or Sketch Cloud
- Frontend Developers: discrete styleguide in plain HTML and CSS with some kind of preprocessor, some kind of single page application
So what’s the problem here, you might ask? Well, the answer is: If the process is working out for you, you’re good to go. For small teams, this usually means you have one designer teaming up with two to three frontend developers.
For me, this usually meant being some kind of bottleneck and/or single point of failure. I’d prepare prototypes in Sketch, based on the specs we wrote out. Maybe I’d even build prototypical components in HTML and CSS, then someone would pick those up and transport them over to Angular.
However, once there was a lot of things to do on the
This process felt rather tedious in the long run, and I found it relying too heavily on one person. So, what can we do about that?
Sharing Context
Let’s be honest, though. Nobody wants to be the limiting factor in a team. This only leads to yourself trying to fit everything in and quickly being overwhelmed and overworked. Splitting the workload and having everyone involved leads to a healthier work environment and we get the benefit of collaborative design for free – that’s a classic win-win situation!
In order to get everyone on board, though, you will have to create a welcoming environment and move out of your comfort zone. The way I went about this, is to think about everyone’s needs and find the sweet spot. The point where our needs overlap. Let’s see what this meant for my time, then:
- Developers: automate as much as possible, don’t repeat yourself (DRY), work with real data right ASAP
- Designers: create sophisticated designs, test different iterations of a component, don’t want to get involved with the technical in’s and out’s too much
Alright, great! No we know what we need. Some kind of cradle for all the application’s parts that we use to design, develop and test the components with. This may sound quite daunting at
Progress is Iterative
Now, you’ve figured where you as a team want your sweet spot to be. The workflow is laid out, you’ve drawn some fancy diagrams to convince your boss — in short, you’re ready to hustle. Chances are, though, you can’t refactor the whole project and lock yourself in for the next few months.
Crafting a good and consistent user experience for your product is hard work and requires a lot of dedication.
But don’t worry! We can do this, step by step. Even in a very cost-effective and non-blocking manner. The nice thing about the workflow I’m going to introduce here is that you can drop it into your project and get working on new features right away. And if you do have the time to refactor and rebuild, you can do that as well. The main thing to remember here, though, is that we’re in for the long run. Remember: Crafting a good and consistent user experience for your product is hard work and requires a lot of dedication.
Setting Up The Workbench
The tools I found to be most effective for our workflow were Sketch and Storybook.
Using Storybook in an existing project
The short route: @storybook/.stories.ts
npx -p @storybook/cli sb init
.storybook/config.js
and change the following line:
const req = require.context('../src/stories', true, /\.stories\.ts$/);
to this:
const req = require.context('../src', true, /.stories.ts$/);
Now we don’t need to create a stories
npm run storybook
and see your very own Storybook instance in the browser. Awesome!
The full config.js
file:
import { configure } from '@storybook/angular';
// automatically import all files ending in *.stories.ts
const req = require.context('../src', true, /\.stories.ts$/);
function loadStories() {
req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
Creating Your First Story
Now that we have our basic setup up and running, we will want to add a first component to test with Storybook. For this, we will add a simple input.component.ts
:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-input',
templateUrl: './input.component.html'
})
export class InputComponent {
@Input() public label = 'Label';
@Input() public placeholder = 'Placeholder';
}
In this component we specify properties for a label, placeholder and the disabled state of the input. These are the properties we want to test in our first story. We will also add a template called input.component.html
to apply those properties:
<label for="input">{{ label }}</label>
<input type="text" id="input" [placeholder]="placeholder">
And now we get to the good parts – testing the component. In order to do so, we will add a input.component.stories.ts
file right next to our component and write our first story. We’ll start with defining a story:
storiesOf('Input', module)
Now we’ll want to define our use-cases by using the .add
function. For our most basic use-case, we will add a Default
-story, that just pulls up our component.
.add('Default', () => ({
component: InputComponent,
}));
Once you npm run storybook
Testing Your Component With Data
For the projects I’m working on, I like to create stories for most, if not all, of the use cases that appear in the live project. With props
@Input() public disabled = false;
We’ll also want to test this newly created property with a story – after all, that’s we’re here for. Right?
.add('Disabled', () => ({
component: InputComponent,
}))
Just like with our very first story, we will define a name for our story and specify which component we’re going to test. Once that’s done, we can go right ahead and throw some properties in the mix.
.add('Disabled', () => ({
component: InputComponent,
props: {
label: 'The disabled label',
placeholder: 'The disabled placeholder',
disabled: true,
}
}))
Once Storybook refreshes, you should be able to see your new test case Disabled
The “Convince Your Boss Kit”
So now you have created your very own Storybook. But what should you tell your boss to get him to greenlight this effort for your project? Here’s some reasons why you should be using Storybook in your project. Developing components with Storybook:
- provides an easy way to test edge cases, which would usually be hard to reach and keep track of in your live application
- lets you present different aspects of a feature in a clear and easy to understand manner once it’s deployed somewhere
- enables you to test those components right away without being dependent on other business logic, data or component hierarchies
- paves the way for unit testing, since you already have mock data and testable components at your disposal
- gives everyone in the team a shared context to talk about.
- makes reviewing features easy
- helps you avoid regressions, especially when you implement automated testing
- provides a common place for everyone in the team to experiment and play with the components
Wrapping Up
That’s it for this part of the series. By now, you have successfully
Have you tried this workflow and are keen to share your experiences? I’d love to hear from you on twitter!