Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storybook support for cells #231

Closed
tmeasday opened this issue Mar 12, 2020 · 4 comments · Fixed by #742
Closed

Storybook support for cells #231

tmeasday opened this issue Mar 12, 2020 · 4 comments · Fixed by #742

Comments

@tmeasday
Copy link

We (storybook team) think this is a really interesting project, and we'd love to help getting first class support for SB in the project (as mentioned in the README).

One thing that's especially interesting is the Cell files; you don't need to squint very hard to see they look a lot like story files (as pointed out by @sw-yx).

We've been thinking about it and we reckon someone could pretty easily write a babel plugin or webpack loader to compile a Cell file to a CSF file. This would be similar to the way that Storybook natively supports MDX by compiling it to CSF via a webpack loader.

That would mean that a user of Redwood could have a storybook setup where they just point SB at all their cell files and get a bunch of stories for free. That'd be pretty amazing! I'm sure there are lot more points we could integrate but this one seems like the most interesting (to me anyway).

Here's a bit of detail on how it might work:

If you take the example UsersCell.js file from the homepage:

export const QUERY = gql`
  query USERS {
    users {
      id
      name
    }
  }
`
export const Loading = () => <div>Loading users...</div>
export const Empty = () => <div>No users yet!</div>
export const Failure = ({ message }) => <div>Error: {message}</div>
export const Success = ({ users }) => {
  return (
    <ul>
      { users.map(user => (
        <li>{user.id} | {user.name}</li>
      ))}
    </ul>
  )
}

The compiler might compile it to something like:

export default {
  title: 'UsersCell',
}

const QUERY = gql`
  query USERS {
    users {
      id
      name
    }
  }
`
export const Loading = () => <div>Loading users...</div>
export const Empty = () => <div>No users yet!</div>
export const Failure = ({ message }) => <div>Error: {message}</div>
Failure.story = {
  args: { message: faker.string() }
};
export const Success = ({ users }) => {
  return (
    <ul>
      { users.map(user => (
        <li>{user.id} | {user.name}</li>
      ))}
    </ul>
  )
}
Success.story = {
  args: { users: generateMockFromQuery(QUERY) }
}

To implement the generateMockFromQuery() function we could use Apollo's query mocking code.

[Note that the syntax above uses the new args feature that's coming in SB6 and we are publishing an RFC about this week, but hopefully you get the idea!]


If the user wanted to write a set of specific stories (i.e. for different values of users in the success case), I guess a generator that generated a story file that just imported from the Cell and re-exported would make sense.

import { QUERY, Loading, Empty, Failure as FailureInput, Success as SuccessInput } from './UsersCell';

export default {
  title: 'UsersCell',
}

export { Loading, Empty };

export const Failure = props => <FailureInput {...props} />;
Failure.story = {
  args: { message: faker.string() }
};

export const Success = props => <SuccessInput {...props} />;
// User can override this or make multiple stories based on `SuccessInput`
Success.story = {
  args: { users: generateMockFromQuery(QUERY) }
}

Another option is the single-file components (that combine cells and stories) that @sw-yx mentioned, but I'm not sure of folks' appetite for that.

@peterp
Copy link
Contributor

peterp commented Mar 12, 2020

First off, I wanted to say that we love Storybook! Thanks for putting so much work into it. It's a fantastic feeling to hear from you!

That would mean that a user of Redwood could have a storybook setup where they just point SB at all their cell files and get a bunch of stories for free.

Storybook is how we think people should be building and documenting components. We want to make the integration as smooth as possible.

Thanks for the direction and advice!

@thedavidprice thedavidprice pinned this issue Mar 12, 2020
@mojombo
Copy link
Contributor

mojombo commented Mar 12, 2020

@tmeasday Wow, thanks for the suggestions! First class Storybook support is critical to the overall dream of Redwood app development, so it makes me really excited that you're interested in helping. We'll be spending some time addressing issues that are coming in from the community, but Storybook is high on the priority list for when things settle down a bit. We'll keep you in the loop, and if you have time to experiment in the meantime, we'd love if you shared what you learn!

@mohsen1
Copy link
Contributor

mohsen1 commented Apr 11, 2020

Note: Webpack can not tree-shake static member assignments like Success.story = unless it is wrapped in if (process.env.NODE_ENV === "development").

I suggest a sibling file named UsersCell.story.ts that imports components from UsersCell.ts

@weaversam8
Copy link

I've been playing around with Storybook on a non-Redwood project, and one thing that's been really nice is pairing it with GraphQL mocking. Since we're embracing GraphQL, we should be prepared to automatically run a mocked GraphQL server on the same port / location as the normal one as part of our Storybook development flow (whatever would run when we type the imaginary command yarn rw sb/yarn redwood storybook)

Just something to think about when we do finally implement this.

@peterp peterp mentioned this issue Jun 23, 2020
12 tasks
@peterp peterp unpinned this issue Jun 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants