Skip to content

Instantly share code, notes, and snippets.

@tmeasday
Last active March 7, 2018 04:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmeasday/d6beb7d98fd7dec1fc8bd7003138dc1a to your computer and use it in GitHub Desktop.
Save tmeasday/d6beb7d98fd7dec1fc8bd7003138dc1a to your computer and use it in GitHub Desktop.

Here's a rough plan of where I am interested in taking Storybook's Story API.

The basic idea is to transition towards a new API that is:

  1. More powerful
  2. More flexible and interoperable with other tools
  3. More familiar+idomatic.

The ground work of @storybook/core has been done, now we can do the fun stuff!

Ideas of what I'd like to add:

1. Story parameters.

The PR for this is ready and will go into 3.5. The next part of this is using it in all the addons. So:

storiesOf('Component', module)

  // Instead of this slightly weird API
  .add('with some emoji', withNotes('A very simple component')(() => </Component>));

  // A more familiar:
  .add('with some emoji', () => </Component>, { notes: 'A very simple component' });

It'll make it easy to add per-story parameters to things like storyshots also:

storiesOf('Component', module)
  .add('with some emoji', () => </Component>, { storyshots: { skip: true } });

2. Add ref to story context

Allow you to do the following in decorators/addons:

addDecorator(story => {
  return story({
    storyRef: ref => {
      // ref is a React ref to the story element, so you can inspect it directly.
    }
  })
});

I'm not sure what the equivalent concept is in the other view layers, I need to do more research.

3. Split component "examples" from story definitions

Here, by "example" I really just mean the "story component": ie the () => <Component with={props} /> part (this is just a stateless functional component after all).

In order to allow many many other things, for instance reusing story examples in tests, we should move towards an API where the component examples are defined separately from the storybook parts, which after all are just a mechanism to describe in-storybook-UI behaviour (see below).

So, at first:

import { storiesOf } from '@storybook/react';

import Component from './Component';

export basic = () => <Component with="basic-props" />;
export complex = () => <Component with="complex-props" />;

storiesOf('Component', module)
  .add('basic', basic, { params }); //etc

Moving perhaps towards a world where you don't need to worry about the boilerplate storiesOf etc. (Not sure where the params / other decorators are best defined).

A second step could be defining the examples in Component.examples.js so that the stories file becomes:

import { storiesOf } from '@storybook/react';

import Component from './Component';
import { basic, complex } from './Component.examples';

storiesOf('Component', module)
  .add('basic', basic, { params }); //etc

Note that this doesn't necessarily require a change to anything bar documentation.

As an example of what the above gives you, here is a test that reuses an example:

import React from 'react';
import { shallow } from 'enzyme';

import { basic } from './Component.examples';

describe('Component', () => {
  it('the basic example renders three Foos', () => {
    const wrapper = shallow(<MyComponent />);
    expect(wrapper.find(Foo)).to.have.length(3);
  });
});

Ultimately we may want to make storybook autodetect *.example.js and do something smart with them.

4. Separating "development" from "documentation" modes.

Apologies that this section is not tightly specced at all

Make it easy to define Component.README.md or the like that can use the component's examples.

We would add a new "context" to the build (in addition to manager and preview) that would render markdown files into a documentation style UI. Each markdown file can contain one or more preview iframe rendered based on some syntax (probably borrowed from styleguidist or equivalent):

## My component

Here is the basic description, let's see it:

<Story name="basic" />

Here's the source:

<StorySource name="basic" />

This would lead toward a migration of documentation style addons away from the current manager UI (so strip down the current UI to be more focused on development). But that would be a few more steps away.

We would want a way to customize addons per-components, have a documentation template, and more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment