You can configure React Storybook in different ways. We'll discuss them here.
React Storybook comes with a command line API, which you usually use inside a NPM script. Here's the options it has:
You must set a port on which React Storybook starts its web server. Here's how to specify it:
start-storybook -p 6977
Sometimes, you ship your static files directly inside your project. In Meteor apps, this is done with the public
directory in the app root. So, you can ask React Storybook to serve those static files.
Here's how to tell React Storybook to use that directory to load static files:
start-storybook -p 6977 -s ./public
React Storybook uses .storybook
directory as a default location for its basic and custom webpack configuration.
Here's how to tell React Storybook to use a custom directory to load your configuration files:
start-storybook -p 6977 -s ./public -c ./storybook-config
We need to create stories to show your components inside React Storybook. For that, we need to use this API.
This is how you can create stories:
import React from 'react';
import { storiesOf } from '@kadira/storybook';
storiesOf('Button', module)
.add('with a text', () => (
<button>My First Button</button>
))
.add('with no text', () => (
<button></button>
));
Here you can chain the add
method and create as many stories as you need.
Usually, our components accept event handlers. Actions help us to debug those event handlers. These actions are logged in the Action Logger
info window in React Storybook.
This is how we can create an action:
import React from 'react';
import { storiesOf, action } from '@kadira/storybook';
storiesOf('Button', module)
.add('with a text', () => (
<button onClick={action('click the button')}>My First Button</button>
));
Here we create an action named click the button
. It gives a function to the onClick
prop in our button.
Then, when you click on the button, it will log something like this into the Action Logger:
{
"name": "click the button",
"args": [
"[SyntheticMouseEvent]",
".1",
{
"isTrusted": false
}
]
}
Here we can see the name we've mentioned when creating the action. After that, we can see the arguments passed to the onClick
event handler. In this case, we've three arguments. [SyntheticMouseEvent]
is the actual event object passed by React and you can use that to get more details.
For simplicity, React Storybook does not show the actual object. Instead it will show
[SyntheticMouseEvent]
.
React Storybook uses a JavaScript file located at .storybook/config.js
as the entry point. This is the file loaded by webpack when it's initializing. You can configure a few things inside it.
Loading modules is the main task of this configuration file. You can do so like this:
import { configure } from '@kadira/storybook';
function loadStories() {
require('../components/stories/button');
// require as many stories as you need.
}
configure(loadStories, module);
Or, if you prefer to keep your stories close to your components, and use a convention to name them (i.e. buttonStory.js
), you can require them like this:
import { configure } from '@kadira/storybook';
const req = require.context('./', true, /Story\.js$/)
function loadStories() {
req.keys().forEach(req)
}
configure(loadStories, module);
Sometimes your app has some common CSS files, so this is the best place to load them. In our Redux to-do example, we load todomvc CSS like this:
import { configure } from '@kadira/storybook';
import 'todomvc-app-css/index.css'
function loadStories() {
...
}
configure(loadStories, module);
React Storybook is not your app. So, sometimes you won’t be able to use some of the APIs and functionalities inside it. So, you need to turn them off or do something else.
Let's have a look at an example.
In some of our apps we use react-komposer
(especially in Mantra apps). So, if you use any container created by react-komposer
, it usually throws an error since React Storybook does not initialize them properly.
In such a scenario, you can disable react-komposer
like this:
import { configure } from '@kadira/storybook';
import { disable } from 'react-komposer';
disable();
function loadStories() {
...
}
configure(loadStories, module);
React Storybook is built on top of webpack. If you need, you can customize the webpack configurations used by React Storybook.
We usually use this feature to add CSS support.
To do so, you need to create a file at .storybook/webpack.config.js
and export a module like this:
const path = require('path');
module.exports = {
plugins: [
// your custom plugins
],
module: {
loaders: [
{
test: /\.css?$/,
loaders: [ 'style', 'raw' ],
include: path.resolve(__dirname, '../')
}
]
}
}
You can customize the UI by duplicating the original components such as layout.js file, put it in .storybook/layout.js
and setting webpack config like this :
const path = require('path');
module.exports = {
plugins: [
new webpack.NormalModuleReplacementPlugin(/^\.\/layout$/, 'custom-layout')
],
resolve: {
alias: {
'custom-layout': path.resolve('.storybook/layout.js')
}
}
}
You can pass options to this config file as you wish. But, there are some stuff like devServer we'll always add by default.
So, usually you need to use this config for doing following things:
- for loading CSS,
- for adding custom resolve extensions,
- for adding resolve aliases.