Design for Success

with React and Storybooks

Chris Saylor

Lead Engineer @ Zumba

@cjsaylor

View the slides

goo.gl/Y33QR9

Design?

That's someone elses job.

Ugh, another sketch/photoshop slice job. Maybe, if I had been involved...

Why do we do it?

  • No code involved, so designers can work autonomously
  • Developers usually viewed as "bad" designers
  • Developers say no too often

Why Should we care about design?

Bad UX designs makes us susceptible to disruption.

Common Design Workflow

= ?

Image source: @nicolesaidy

How do we bridge the gap?

Common Design Workflow

= ?

Image source: @nicolesaidy

Storybook.js

Why not just create an html styleguide?

  • Gets stale almost immediately.
  • The language barrier between designers and developers makes it hard to reference.

Why Storybook.js?

  • Integrates with React, Vue.js, and Angular
  • Immediate feedback of changes
  • Easily see history of changes
  • At the end of the design phase, we have functional components!

How?

Keep data retrieval separate

Typical React Tutorial Component

export default class ListComponent extends React.Component {
    state = { items: [] }

    async componentDidMount() {
        this.setState({
            items: await fetch('/items')
        });
    }

    renderItems() {
        return this.state.items.map(item => <li>{item}</li>)
    }

    render = () => (
        <ul>{ this.renderItems() }</ul>
    )
}

Separate!

Use props to display

export default class ListComponent extends React.Component {

    renderItems = () => {
        return (this.props.items || [])
            .map(item => <li>{item}</li>)
    }

    render = () => <ul>{ this.renderItems() }</ul>
}

Pass the state data to the view

import List from './list-component';
export default class ListContainer extends React.Component {

    state = { items: [] }

    async componentDidMount() {
        this.setState({
            items: await fetch('/items')
        });
    }

    render = () => <List items={this.state.items}/>
}

Storytime!

import { storiesOf } from '@storybook/react';
import List from './list-component';

storiesOf('List', module)
    .add('No items', () => <List />)
    .add('One item', () => <List items={['item 1']} />)
    .add('Multiple items', () => (
        <List items={['item 1', 'item 2', 'item 3']} />
    ));

Storybook Capabilities

  • Show when user actions occur in the view

Add a click action

export default class ListComponent extends React.Component {

    onClick = (e) => {
        this.props.onItemClicked(e.target.innerText);
    }

    renderItems = () => {
        return (this.props.items || [])
            .map(item => (
                <li onClick={this.onClick}>{item}</li>
            ));
    }

    render = () => <ul>{ this.renderItems() }</ul>

}

Add the "actions" addon

$ npm install @storybook/addon-actions
// addons.js
import '@storybook/addon-actions/register';

This is what is responsible for showing the action panel

Modify our story for the action

import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import List from './list-component';

storiesOf('List', module)
    .add('Multiple items', () => {
        return (
            <List
                onItemClicked={action('Item clicked!')}
                items={['item 1', 'item 2', 'item 3']}
            />
        );
    });

Storybook Capabilities

  • Allow User Input In Stories

Add the "knobs" addon

$ npm install @storybook/addon-knobs
// addons.js
import '@storybook/addon-knobs/register';

This is what is responsible for showing the panel

Modify the story

import { storiesOf } from '@storybook/react';
import List from './list-component';
import { action } from '@storybook/addon-actions';
import {withKnobs, array} from '@storybook/addon-knobs';

storiesOf('List', module)
    .addDecorator(withKnobs)
    .add('Multiple items', () => (
        <List
            onItemClicked={action('Item clicked!')}
            items={
                array('Items', [
                    'item 1',
                    'item 2',
                    'item 3'
                ])
            }
        />
    ));

Storybook Capabilities

  • Interactive Unit Tests

Utilize in Your Workflow

Styleguides

  • Show what components are available for composition
  • Can show full page layouts

Prototyping

  • No backend required
  • Get a feel for the product before investing in backend integration

Product Demos

  • Stitch together stories With the link addon to demo a product.

Case Studies

Conclusion

  • Getting involved in the design process doesn't have to be scary
  • Start fresh or add to existing React/VueJS app
  • Hit the ground running when designs are finished
  • Version control designs and their stories

Questions?

Resources

Fin