Skip to content

Instantly share code, notes, and snippets.

Storybook Addons long-term plan

Motivation:

  • Consolidate addon API
  • Ensure where possible addons are framework independent.
  • Provide guidance around avoiding anti-patterns (addon-info, etc)

High level plan:

The key plan is to try and make addons run in the manager context rather than the preview context where possible.

Decorator / addon preview API proposal.

Currently the principal way addons work in the preview context (ie acting on the story) is via decorators.

Types of decorator

There are 3 types of thing that the decorators do:

  • Altering the story in a very real way: "modifiers"
  • Inspecting the story, and sending telemetry somewhere (typically to the manager context via the addon channel): "inspectors"
import { storiesOf } from '@kadira/storybook';
import Histogram from './Histogram';
const latencies = [];
for (var i = 20; i <= 120; i += 20) {
latencies.push(i);
}
storiesOf('Histogram')
.add('Typical', () => <Histogram data={latencies.map(latency => ({
storiesOf('Task')
.add('inbox task', () => (
<Task task={{
title: "Test Task",
subtitle: "on TestBoard",
state: "TASK_INBOX"
}} />
));
import React from 'react';
import styled, {injectGlobal} from 'styled-components';
injectGlobal`
@import url('https://fonts.googleapis.com/css?family=Nunito+Sans:400,400i,800');
`;
const CommentListDiv = styled.div`
font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #333;
import React from 'react';
export default function({loading, comments, totalCount}) {
if (loading) {
return <div>empty</div>;
}
if (comments.length === 0) {
return <div>loading</div>;
}
import React from 'react';
import {storiesOf} from '@kadira/storybook';
import CommentList from '../CommentList';
storiesOf('CommentList', CommentList)
.add('HasData', () => (
<CommentList comments={testComments.slice(0, 3)} totalCount={3} />
))
.add('Paginated', () => <CommentList comments={testComments} totalCount={10} />)
// This is the avatar for a particular app, with a particular bump endpoint (GraphQL in this case)
import React from 'react';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
import Avatar from './Avatar';
export default graphql(gql`
mutation bumpUser($userId: ID!) {
@tmeasday
tmeasday / avatar.js
Last active March 31, 2017 06:58
Embedded Styles
import React, { Component, PropTypes } from 'react';
import styled from 'styled-components';
const AvatarDiv = styled.div`
border-radius: 0.2px;
border: 1px solid #eee;
`;
const BumpSpan = styled.span`
position: relative;
@tmeasday
tmeasday / avatar.js
Last active March 31, 2017 06:55
Presentational split
import React, { Component, PropTypes } from 'react';
import $ from 'jquery';
const BUMP_URL = (id) => `/bump/${id}`;
const Avatar = ({ name, avatar_url, onBump }) => (
<div className="avatar image-link">
<img src={avatar_url} title={name} />
<span class="image-action" onClick={onBump}>Bump</span>
</div>