mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-01 05:05:25 +08:00
Merge branch 'source' into storyrouter3
This commit is contained in:
commit
4459c0df37
4
.eslintignore
Normal file
4
.eslintignore
Normal file
@ -0,0 +1,4 @@
|
||||
dist
|
||||
build
|
||||
coverage
|
||||
node_modules
|
28
.eslintrc.js
Normal file
28
.eslintrc.js
Normal file
@ -0,0 +1,28 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'./node_modules/eslint-config-airbnb-base/rules/es6.js',
|
||||
],
|
||||
plugins: [
|
||||
'prettier',
|
||||
],
|
||||
parser: 'babel-eslint',
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
},
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
rules: {
|
||||
strict: 0,
|
||||
'prettier/prettier': ['warn', {
|
||||
printWidth: 100,
|
||||
tabWidth: 2,
|
||||
bracketSpacing: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
}],
|
||||
quotes: ['warn', 'single'],
|
||||
'arrow-parens': ['warn', 'as-needed'],
|
||||
},
|
||||
}
|
12
.remarkrc
Normal file
12
.remarkrc
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"plugins": [
|
||||
"remark-preset-lint-recommended",
|
||||
["remark-lint-list-item-indent", false],
|
||||
["remark-lint-code", {"js": {
|
||||
"module": "node_modules/remark-lint-code-eslint",
|
||||
"options": {
|
||||
"fix": true
|
||||
}
|
||||
}}]
|
||||
]
|
||||
}
|
21
.travis.yml
Normal file
21
.travis.yml
Normal file
@ -0,0 +1,21 @@
|
||||
language: node_js
|
||||
branches:
|
||||
except:
|
||||
- master
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- ".cache"
|
||||
notifications:
|
||||
email: false
|
||||
node_js:
|
||||
- node
|
||||
before_install: "./scripts/travis/before_install.sh"
|
||||
after_success: "./scripts/travis/after_success.sh"
|
||||
script:
|
||||
- npm run lint
|
||||
git:
|
||||
depth: 1
|
||||
env:
|
||||
global:
|
||||
- secure: yNNjO4HvIcBH2r+EpWr29TQZzUJoQCC7MlxDtWW5XCsiL7lwnAxRk9DJ1edjYyd2lt4UWVyiQYD7708YMq7sR9TQWN195kcVnd1k5JzNBvePK9VjrmX2e2gRsbSQmWYQXFuUvbEbBmZUPhWbgaTzDzSdzsoFpTqJg3Q328S2GleixtPLBly5SC59Zar9tGw7OyVmPRN9GdKbVQfPQcmHDY+fHKzAqBaenlL/dC6UR9N+w5oWr3KFH/smrVzbDEonoKaZqvj02LnHVctGL6XCopoNbm7ldf/A6qKS/9D/MrLiLP3O3umCPhnGH8L8bNw7I6pdIKbroISUd+v5FqoCLN1iLO5wDY73gKUdwYUAt37KEhFUJPDwr/YYxRP0fZHIF0lI44w0RgN7N27ISwu9dw6Zq6a28+UcBRyemsvfXodBO9jiAW8R0pQhqWZ9yc2vZfFVfRh5SbHBLqIc0uHcqAtnkx8XU72bDDbqmA0dCA+LwAPX3doaaP37C5BzO+khGODpG+4R0nSsuTdPB6+jbBuS84V9YUAAl95hhMlYA9hvI3GdDjPkahuaYdUrYmqSh3v2XIhEA+D6BjXaGLYwcFpZzLB8pzZbRZVR4RdmuGF1J+ozxZNiKPPqcmK7XFlGWJ2b2+fFw3ZuHU6grDdCe1zpLYzrx1Om6QBUir83oGM=
|
@ -6,10 +6,8 @@ This site has also has the documentation for Storybook.
|
||||
|
||||
### Usage
|
||||
|
||||
```
|
||||
npm i
|
||||
npm start
|
||||
```
|
||||
npm i
|
||||
npm start
|
||||
|
||||
### Edit Documentation
|
||||
|
||||
|
29
package.json
29
package.json
@ -24,7 +24,27 @@
|
||||
"@kadira/storybook-addon-actions": "^1.1.3",
|
||||
"@kadira/storybook-addon-links": "^1.0.1",
|
||||
"@kadira/storybook-addons": "^1.6.1",
|
||||
"gh-pages": "^0.12.0"
|
||||
"babel-cli": "^6.24.1",
|
||||
"babel-core": "^6.24.1",
|
||||
"babel-eslint": "^7.2.2",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-polyfill": "^6.23.0",
|
||||
"babel-preset-env": "^1.4.0",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-0": "^6.24.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-airbnb-base": "^11.1.3",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-jest": "^20.0.0",
|
||||
"eslint-plugin-prettier": "^2.0.1",
|
||||
"gh-pages": "^0.12.0",
|
||||
"markdownlint-cli": "^0.3.1",
|
||||
"prettier": "^1.3.0",
|
||||
"remark-cli": "^3.0.1",
|
||||
"remark-lint": "^6.0.0",
|
||||
"remark-lint-code": "^2.0.0",
|
||||
"remark-lint-code-eslint": "^2.0.0",
|
||||
"remark-preset-lint-recommended": "^2.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
@ -34,10 +54,11 @@
|
||||
"main": "n/a",
|
||||
"scripts": {
|
||||
"build-storybook": "build-storybook",
|
||||
"build": "gatsby build && cp CNAME ./public",
|
||||
"deploy": "gh-pages -r git@github.com:storybooks/storybooks.github.io.git -d public -o origin -b master",
|
||||
"build": "gatsby build && cp CNAME .travis.yml ./public",
|
||||
"deploy": "gh-pages -t -r git@github.com:storybooks/storybooks.github.io.git -d public -o origin -b master",
|
||||
"deploy-travis": "gh-pages -t -r https://${GH_TOKEN}@github.com/storybooks/storybooks.github.io.git -d public -o origin -b master",
|
||||
"develop": "gatsby develop",
|
||||
"storybook": "start-storybook -p 9009",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"lint": "remark . # -- -o to update"
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
id: 'addon-gallery'
|
||||
title: 'Addon Gallery'
|
||||
---
|
||||
|
||||
This is a list of available addons for Storybook.
|
||||
|
||||
## Built-In Addons.
|
||||
@ -14,7 +15,7 @@ With actions, you can inspect events related to your components. This is pretty
|
||||
|
||||
Also, you can think of this as a way to document events in your components.
|
||||
|
||||
### [Links](https://github.com/storybooks/storybook/tree/master/packages/addon-links)
|
||||
### [Links](https://github.com/storybooks/storybook/tree/master/packages/addon-links)
|
||||
|
||||
With links you can link stories together. With that, you can build demos and prototypes directly from your UI components. (Like you can do with [Invision](https://www.invisionapp.com/) and [Framer.js](https://framerjs.com/))
|
||||
|
||||
|
@ -2,13 +2,14 @@
|
||||
id: 'api'
|
||||
title: 'API'
|
||||
---
|
||||
|
||||
## Core Addon API
|
||||
|
||||
This is the core addon API. This is how to get the addon API:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import addonAPI from '@kadira/storybook-addons';
|
||||
~~~
|
||||
```
|
||||
|
||||
Have a look at the API methods for more details:
|
||||
|
||||
@ -23,12 +24,12 @@ It has a NodeJS [EventEmitter](https://nodejs.org/api/events.html) compatible AP
|
||||
This method allows you to register an addon and get the storybook API. You can do this only in the Manager App.
|
||||
See how we can use this:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
// Register the addon with a unique name.
|
||||
addonAPI.register('kadira/notes', (storybookAPI) => {
|
||||
|
||||
});
|
||||
~~~
|
||||
```
|
||||
|
||||
Now you'll get an instance to our StorybookAPI. See the [api docs](/docs/react-storybook/addons/api#storybook-api) for Storybook API regarding using that.
|
||||
|
||||
@ -37,7 +38,7 @@ Now you'll get an instance to our StorybookAPI. See the [api docs](/docs/react-s
|
||||
This method allows you to add a panel to Storybook. (Storybook's Action Logger is a panel). You can do this only in the Manager App.
|
||||
See how you can use this method:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
const MyPanel = () => (
|
||||
<div>
|
||||
This is a panel.
|
||||
@ -51,13 +52,13 @@ addonAPI.addPanel('kadira/notes/panel', {
|
||||
<MyPanel />
|
||||
),
|
||||
});
|
||||
~~~
|
||||
```
|
||||
|
||||
As you can see, you can set any React Component as the panel. Currently, it's just a text. But you can do anything you want.
|
||||
|
||||
You also pass the channel and the Storybook API into that. See:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
addonAPI.register('kadira/notes', (storybookAPI) => {
|
||||
// Also need to set a unique name to the panel.
|
||||
addonAPI.addPanel('kadira/notes/panel', {
|
||||
@ -67,7 +68,7 @@ addonAPI.register('kadira/notes', (storybookAPI) => {
|
||||
),
|
||||
})
|
||||
})
|
||||
~~~
|
||||
```
|
||||
|
||||
## Storybook API
|
||||
|
||||
@ -79,55 +80,55 @@ Let's have a look at API methods.
|
||||
|
||||
With this method, you can select a story via an API. This method accepts two parameters.
|
||||
|
||||
1. story kind name
|
||||
2. story name (optional)
|
||||
1. story kind name
|
||||
2. story name (optional)
|
||||
|
||||
Let's say you've got a story like this:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
storiesOf('Button', module)
|
||||
.add('with text', () => (
|
||||
<Button onClick={action('clicked')}>Hello Button</Button>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
This is how you can select the above story:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
storybookAPI.selectStory('Button', 'with text');
|
||||
~~~
|
||||
```
|
||||
|
||||
### storybookAPI.setQueryParams()
|
||||
|
||||
This method allows you to set query string parameters. You can use that as temporary storage for addons. Here's how you set query params.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
storybookAPI.setQueryParams({
|
||||
abc: 'this is abc',
|
||||
bbc: 'this is bbc',
|
||||
});
|
||||
~~~
|
||||
```
|
||||
|
||||
> If you need to remove a query param, use `null` for that. For an example, let's say we need to remove bbc query param. This is how we do it:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
storybookAPI.setQueryParams({
|
||||
bbc: null,
|
||||
});
|
||||
~~~
|
||||
```
|
||||
|
||||
### storybookAPI.getQueryParam()
|
||||
|
||||
This method allows you to get a query param set by above API `setQueryParams`. For example, let's say we need to get the bbc query param. Then this how we do it:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
storybookAPI.getQueryParam('bbc');
|
||||
~~~
|
||||
```
|
||||
|
||||
### storybookAPI.onStory(fn)
|
||||
|
||||
This method allows you to register a handler function which will be called whenever the user navigates between stories.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
storybookAPI.onStory((kind, story) => console.log(kind, story));
|
||||
~~~
|
||||
```
|
||||
|
@ -9,36 +9,36 @@ Basically, there are two types of addons. (Decorators and Native Addons)
|
||||
|
||||
## 1. Decorators
|
||||
|
||||
These are wrapper components or Storybook decorators that wrap a story.
|
||||
Decorators are wrapper components or Storybook decorators that wrap a story.
|
||||
|
||||
### Wrapper Components
|
||||
|
||||
For example, let's say we want to center a story rendered on the screen. For that, we can use a wrapper component like this:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
const Center = ({ children }) => (
|
||||
<div style={{ textAlign: "center" }}>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
~~~
|
||||
```
|
||||
|
||||
Then we can use it when writing stories.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
storiesOf('Button', module)
|
||||
.add('with text', () => (
|
||||
<Center>
|
||||
<Button onClick={action('clicked')}>Hello Button</Button>
|
||||
</Center>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
### Storybook Decorators
|
||||
|
||||
You can also expose this functionality as a Storybook decorator and use it like this.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
const CenterDecorator = (story) => (
|
||||
<div style={{ textAlign: "center" }}>
|
||||
{story()}
|
||||
@ -53,11 +53,11 @@ storiesOf('Button', module)
|
||||
.add('with some emojies', () => (
|
||||
<Button onClick={action('clicked')}>😀 😎 👍 💯</Button>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
You can also add a decorator globally for all stories like this:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import { storiesOf, addDecorator } from '@kadira/storybook';
|
||||
import { action } from '@kadira/storybook-addon-actions';
|
||||
import { linkTo } from '@kadira/storybook-addon-links';
|
||||
@ -81,7 +81,7 @@ storiesOf('Button', module)
|
||||
.add('with some emojies', () => (
|
||||
<Button onClick={action('clicked')}>😀 😎 👍 💯</Button>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
> You can call `addDecorator()` inside the story definition file as shown above. But adding it to the Storybook config file is a much better option.
|
||||
|
||||
@ -99,6 +99,6 @@ It will allow you to inspect the parameters of any event of your components.
|
||||
|
||||
See the following links to learn more about native addons:
|
||||
|
||||
* [Using addons](/docs/react-storybook/addons/using-addons)
|
||||
* [Addon gallery](/docs/react-storybook/addons/addon-gallery)
|
||||
* [Write your own addon](/docs/react-storybook/addons/writing-addons)
|
||||
- [Using addons](/docs/react-storybook/addons/using-addons)
|
||||
- [Addon gallery](/docs/react-storybook/addons/addon-gallery)
|
||||
- [Write your own addon](/docs/react-storybook/addons/writing-addons)
|
||||
|
@ -11,17 +11,17 @@ We are going to use an addon called [Notes](https://github.com/storybooks/storyb
|
||||
|
||||
First, we need to install the addons:
|
||||
|
||||
~~~sh
|
||||
```sh
|
||||
npm i --save-dev @kadira/storybook-addon-actions @kadira/storybook-addon-links @kadira/storybook-addon-notes
|
||||
~~~
|
||||
```
|
||||
|
||||
Then, we need to create a file called `addons.js` inside the storybook config directory and add the following content:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import '@kadira/storybook-addon-actions/register';
|
||||
import '@kadira/storybook-addon-links/register';
|
||||
import '@kadira/storybook-addon-notes/register';
|
||||
~~~
|
||||
```
|
||||
|
||||
This will register all the addons and you'll be able to see the actions and notes panels (in that order) when you are viewing the story. (Links do not register a tab--check individual addon docs to see which Storybook features they use!)
|
||||
|
||||
@ -29,7 +29,7 @@ This will register all the addons and you'll be able to see the actions and note
|
||||
|
||||
Now when you are writing a story it like this and add some notes:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import { action } from '@kadira/storybook-addon-actions';
|
||||
@ -39,11 +39,11 @@ import { WithNotes } from '@kadira/storybook-addon-notes';
|
||||
|
||||
storiesOf('Button', module)
|
||||
.add('with some emoji', () => (
|
||||
<WithNotes notes={'Here we use some emoji as the Button text. Isn\\'t it look nice?'}>
|
||||
<WithNotes notes={'Here we use some emoji as the Button text. Doesn't it look nice?'}>
|
||||
<Button onClick={action('clicked')}>😀 😎 👍 💯</Button>
|
||||
</WithNotes>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
Then you'll be able to see those notes when you are viewing the story.
|
||||
|
||||
|
@ -21,11 +21,11 @@ As shown in the above image, there's a communication channel that the Manager Ap
|
||||
|
||||
With an addon, you can add more functionality to Storybook. Here are a few things you could do:
|
||||
|
||||
* Add a panel to Storybook (like Action Logger).
|
||||
* Interact with the story and the panel.
|
||||
* Set and get URL query params.
|
||||
* Select a story.
|
||||
* Register keyboard shortcuts (coming soon).
|
||||
- Add a panel to Storybook (like Action Logger).
|
||||
- Interact with the story and the panel.
|
||||
- Set and get URL query params.
|
||||
- Select a story.
|
||||
- Register keyboard shortcuts (coming soon).
|
||||
|
||||
With this, you can write some pretty cool addons. Look at our [Addon gallery](/docs/react-storybook/addons/addon-gallery) to have a look at some sample addons.
|
||||
|
||||
@ -33,14 +33,13 @@ With this, you can write some pretty cool addons. Look at our [Addon gallery](/d
|
||||
|
||||
Let's write a simple addon for Storybook. It's a Notes addon on which you can display some notes for a story.
|
||||
|
||||
|
||||
> Just for the simplicity, we'll write the addon right inside our app. But we can easily move it into a separate NPM module.
|
||||
|
||||
## How it looks
|
||||
|
||||
We write a story for our addon like this:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import { action } from '@kadira/storybook-addon-actions';
|
||||
@ -54,11 +53,11 @@ storiesOf('Button', module)
|
||||
</WithNotes>
|
||||
))
|
||||
.add('with some emoji', () => (
|
||||
<WithNotes notes={'Here we use some emoji as the Button text. Isn\'t it look nice?'}>
|
||||
<WithNotes notes={'Here we use some emoji as the Button text. Doesn't it look nice?'}>
|
||||
<Button onClick={action('clicked')}>😀 😎 👍 💯</Button>
|
||||
</WithNotes>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
Then it will appear in the Notes panel like this:
|
||||
|
||||
@ -68,10 +67,10 @@ Then it will appear in the Notes panel like this:
|
||||
|
||||
First, create an `addons.js` inside the Storybook config directory and add the following content to it.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
// Register the actions addon that we used above
|
||||
import '@kadira/storybook-addon-actions/register';
|
||||
~~~
|
||||
```
|
||||
|
||||
We'll use this file shortly to register the Notes addon we are building.
|
||||
|
||||
@ -81,7 +80,7 @@ Now we need to create two files, `register.js` and `index.js,` inside a director
|
||||
|
||||
Let's add the following content to the `index.js`. It will expose a class called `WithNotes`, which wraps our story.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import addons from '@kadira/storybook-addons';
|
||||
|
||||
@ -96,7 +95,7 @@ export class WithNotes extends React.Component {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
In this case, our component can access something called the channel. It lets us communicate with the panel (where we display notes). It has a NodeJS [EventEmitter](https://nodejs.org/api/events.html) compatible API.
|
||||
|
||||
@ -104,7 +103,7 @@ In the above case, it will emit the notes text to the channel, so our panel can
|
||||
|
||||
Then add the following code to the register.js.
|
||||
|
||||
See: https://gist.github.com/arunoda/fb3859840ff616cc5ea0fa3ef8e3f358
|
||||
See: <https://gist.github.com/arunoda/fb3859840ff616cc5ea0fa3ef8e3f358>
|
||||
|
||||
It will register our addon and add a panel. In this case, the panel represents a React component called `Notes`. That component has access to the channel and storybook api.
|
||||
|
||||
@ -118,20 +117,19 @@ It also listens to another event, called onStory, in the storybook API, which fi
|
||||
|
||||
Now, finally, we need to register the addon by importing it to the `.storybook/addons.js` file.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
// Register the actions addon that we used above
|
||||
import '@kadira/storybook-addon-actions/register';
|
||||
|
||||
// Our addon
|
||||
import '../src/notes-addon/register';
|
||||
~~~
|
||||
```
|
||||
|
||||
> Above code runs in the Manager App but not in the preview area.
|
||||
|
||||
|
||||
That's it. Now you can create notes for any story as shown below:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import { action } from '@kadira/storybook-addon-actions';
|
||||
@ -145,11 +143,11 @@ storiesOf('Button', module)
|
||||
</WithNotes>
|
||||
))
|
||||
.add('with some emojies', () => (
|
||||
<WithNotes notes={'Here we use emojies as the Button text. Isn\'t it look nice?'}>
|
||||
<WithNotes notes={'Here we use emojies as the Button text. Doesn't it look nice?'}>
|
||||
<Button onClick={action('clicked')}>😀 😎 👍 💯</Button>
|
||||
</WithNotes>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
## Addon API
|
||||
|
||||
@ -166,7 +164,7 @@ In addition to moving the above code to an NPM module, we've set `react` and `@k
|
||||
|
||||
When you are developing your addon as a package, you can't use `npm link` to add it your project. Instead add your package as a local dependency into your `package.json` as shown below:
|
||||
|
||||
~~~json
|
||||
```json
|
||||
{
|
||||
...
|
||||
"dependencies": {
|
||||
@ -174,7 +172,7 @@ When you are developing your addon as a package, you can't use `npm link` to add
|
||||
}
|
||||
...
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
### Package Maintenance
|
||||
|
||||
|
@ -12,15 +12,13 @@ For that, Storybook comes with a tool to export your storybook into a static web
|
||||
|
||||
Simply add the following NPM script:
|
||||
|
||||
~~~sh
|
||||
```json
|
||||
{
|
||||
...
|
||||
"scripts": {
|
||||
"storybook": "build-storybook -c .storybook -o .out"
|
||||
}
|
||||
...
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
Then run `npm run storybook`.
|
||||
|
||||
@ -29,10 +27,10 @@ Now you can deploy the content in the `.out` directory wherever you want.
|
||||
|
||||
To test it locally, simply run the following commands:
|
||||
|
||||
~~~sh
|
||||
```sh
|
||||
cd .out
|
||||
python -m SimpleHTTPServer
|
||||
~~~
|
||||
```
|
||||
|
||||
## Deploying to GitHub Pages
|
||||
|
||||
|
@ -9,6 +9,6 @@ Here are some answers to frequently asked questions. If you have a question, you
|
||||
|
||||
Create React App does not allow providing options to Jest in your `package.json`, however you can run `jest` with commandline arguments:
|
||||
|
||||
~~~
|
||||
```sh
|
||||
npm test -- --coverage --collectCoverageFrom='["src/**/*.{js,jsx}","!src/**/stories/*"]'
|
||||
~~~
|
||||
```
|
||||
|
@ -5,7 +5,7 @@ title: 'Introduction'
|
||||
|
||||
React Storybook is a UI development environment for your React components. With it, you can visualize different states of your UI components and develop them interactively.
|
||||
|
||||
It runs outside of your app. So you can develop UI components in isolation without worrying about app specific dependencies and requirements.
|
||||
React Storybook runs outside of your app. So you can develop UI components in isolation without worrying about app specific dependencies and requirements.
|
||||
|
||||

|
||||
|
||||
@ -13,6 +13,6 @@ React Storybook also comes with a lot of [addons](/docs/react-storybook/addons/i
|
||||
|
||||
Here are some featured storybooks that you can reference to see how Storybook works:
|
||||
|
||||
* [React Button](http://kadira-samples.github.io/react-button) - [source](https://github.com/kadira-samples/react-button)
|
||||
* [Demo of React Dates](http://airbnb.io/react-dates/) - [source](https://github.com/airbnb/react-dates)
|
||||
* [Demo of React Native Web](http://necolas.github.io/react-native-web/storybook/) - [source](https://github.com/necolas/react-native-web)
|
||||
- [React Button](http://kadira-samples.github.io/react-button) - [source](https://github.com/kadira-samples/react-button)
|
||||
- [Demo of React Dates](http://airbnb.io/react-dates/) - [source](https://github.com/airbnb/react-dates)
|
||||
- [Demo of React Native Web](http://necolas.github.io/react-native-web/storybook/) - [source](https://github.com/necolas/react-native-web)
|
||||
|
@ -6,20 +6,20 @@ title: 'Quick Start Guide'
|
||||
React Storybook is very easy to use. You can use it with any kind of React project.
|
||||
Follow these steps to get started with Storybook.
|
||||
|
||||
~~~sh
|
||||
```sh
|
||||
npm i -g getstorybook
|
||||
cd my-react-app
|
||||
getstorybook
|
||||
~~~
|
||||
```
|
||||
|
||||
This will configure your app for Storybook. After that, you can run your Storybook with:
|
||||
|
||||
~~~
|
||||
```sh
|
||||
npm run storybook
|
||||
~~~
|
||||
```
|
||||
|
||||
Then you can access your storybook from the browser.
|
||||
|
||||
---
|
||||
* * *
|
||||
|
||||
To learn more about what `getstorybook` command does, have a look at our [Slow Start Guide](/docs/react-storybook/basics/slow-start-guide).
|
||||
|
@ -17,28 +17,27 @@ In this guide, we are trying to set up Storybook for your React project.
|
||||
|
||||
First of all, you need to add `@kadira/storybook` to your project. To do that, simply run:
|
||||
|
||||
~~~sh
|
||||
```sh
|
||||
npm i --save-dev @kadira/storybook
|
||||
~~~
|
||||
```
|
||||
|
||||
## Add react and react-dom
|
||||
|
||||
Make sure that you have `react` and `react-dom` in your dependencies as well:
|
||||
|
||||
~~~sh
|
||||
```sh
|
||||
npm i --save react react-dom
|
||||
~~~
|
||||
```
|
||||
|
||||
Then add the following NPM script to your package json in order to start the storybook later in this guide:
|
||||
|
||||
~~~js
|
||||
```json
|
||||
{
|
||||
...
|
||||
"scripts": {
|
||||
"storybook": "start-storybook -p 9001 -c .storybook"
|
||||
}
|
||||
...
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
## Create the config file
|
||||
|
||||
@ -48,7 +47,7 @@ For the basic Storybook configuration file, you don't need to do much, but simpl
|
||||
|
||||
To do that, simply create a file at `.storybook/config.js` with the following content:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import { configure } from '@kadira/storybook';
|
||||
|
||||
function loadStories() {
|
||||
@ -57,7 +56,7 @@ function loadStories() {
|
||||
}
|
||||
|
||||
configure(loadStories, module);
|
||||
~~~
|
||||
```
|
||||
|
||||
That'll load stories in `../stories/index.js`.
|
||||
|
||||
@ -67,7 +66,7 @@ Just like that, you can load stories from wherever you want to.
|
||||
|
||||
Now you can write some stories inside the `../stories/index.js` file, like this:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf, action } from '@kadira/storybook';
|
||||
|
||||
@ -78,20 +77,20 @@ storiesOf('Button', module)
|
||||
.add('with some emoji', () => (
|
||||
<button onClick={action('clicked')}>😀 😎 👍 💯</button>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
Story is a single state of your component. In the above case, there are two stories for the native button component:
|
||||
|
||||
1. with text
|
||||
2. with some emoji
|
||||
1. with text
|
||||
2. with some emoji
|
||||
|
||||
## Run your Storybook
|
||||
|
||||
Now everything is ready. Simply run your storybook with:
|
||||
|
||||
~~~js
|
||||
```sh
|
||||
npm run storybook
|
||||
~~~
|
||||
```
|
||||
|
||||
Then you can see all your stories, like this:
|
||||
|
||||
|
@ -22,7 +22,7 @@ This is just one way to do that. You can always edit your storybook config file
|
||||
This is how you write stories:
|
||||
(Let's assume there's a component called "Button" in `src/components/Button.js`.)
|
||||
|
||||
~~~js
|
||||
```js
|
||||
// file: src/stories/index.js
|
||||
|
||||
import React from 'react';
|
||||
@ -36,7 +36,7 @@ storiesOf('Button', module)
|
||||
.add('with some emoji', () => (
|
||||
<Button onClick={action('clicked')}>😀 😎 👍 💯</Button>
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
This will show stories in your storybook like this:
|
||||
|
||||
@ -44,14 +44,13 @@ This will show stories in your storybook like this:
|
||||
|
||||
This is just our core API for writing stories. In addition to this, you can use the official and third party Storybook [addons](/docs/react-storybook/addons/introduction) to get more functionality.
|
||||
|
||||
|
||||
## Loading stories dynamically
|
||||
|
||||
Sometimes, you will want to load your stories dynamically rather than explicitly requiring them in the Storybook config file.
|
||||
|
||||
For example, you may write stories for your app inside the `src/components` directory with the `.stories.js` extension. Then you will want to load them at once. Simply edit your config directory at `.storybook/config.js` as follows:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import { configure } from '@kadira/storybook';
|
||||
|
||||
const req = require.context('../src/components', true, /\.stories\.js$/)
|
||||
@ -61,7 +60,7 @@ function loadStories() {
|
||||
}
|
||||
|
||||
configure(loadStories, module);
|
||||
~~~
|
||||
```
|
||||
|
||||
Here we use Webpack's [require.context](https://webpack.github.io/docs/context.html#require-context) to load modules dynamically. Have a look at the relevant Webpack [docs](https://webpack.github.io/docs/context.html#require-context) to learn more about how to use require.context.
|
||||
|
||||
@ -69,7 +68,7 @@ Here we use Webpack's [require.context](https://webpack.github.io/docs/context.h
|
||||
|
||||
A decorator is a way to wrap a story with a common set of component(s). Let's say you want to center all your stories. Here is how we can do this with a decorator:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import MyComponent from '../my_component';
|
||||
@ -82,14 +81,15 @@ storiesOf('MyComponent', module)
|
||||
))
|
||||
.add('without props', () => (<MyComponent />))
|
||||
.add('with some props', () => (<MyComponent text="The Comp"/>));
|
||||
~~~
|
||||
```
|
||||
|
||||
Here we only add the decorator for the current set of stories. (In this example, we add it just for the **MyComponent** story group.)
|
||||
|
||||
But, you can also add a decorator **globally** and it'll be applied to all the stories you create. This is how to add a decorator like that:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import { configure, addDecorator } from '@kadira/storybook';
|
||||
|
||||
addDecorator((story) => (
|
||||
<div style={{textAlign: 'center'}}>
|
||||
{story()}
|
||||
@ -97,9 +97,9 @@ addDecorator((story) => (
|
||||
));
|
||||
|
||||
configure(function () {
|
||||
...
|
||||
// ...
|
||||
}, module);
|
||||
~~~
|
||||
```
|
||||
|
||||
## Managing stories
|
||||
|
||||
@ -112,31 +112,29 @@ But you might ask, how do I manage stories If I have many of them? Here's how di
|
||||
|
||||
For example, you can prefix story names with a dot (`.`):
|
||||
|
||||
~~~js
|
||||
```js
|
||||
storiesOf('core.Button', module)
|
||||
~~~
|
||||
```
|
||||
|
||||
Then you can filter stories to display only the stories you want to see.
|
||||
Then you can filter stories to display only the stories you want to see.
|
||||
|
||||
### Run multiple storybooks
|
||||
|
||||
You can run multiple storybooks for different kinds of stories (or components). To do that, you can create different NPM scripts to start different stories. See:
|
||||
|
||||
~~~js
|
||||
```json
|
||||
{
|
||||
...
|
||||
"scripts": {
|
||||
"start-storybook-for-theme": "start-storybook -p 9001 -c .storybook-theme"
|
||||
"start-storybook-for-theme": "start-storybook -p 9001 -c .storybook-theme",
|
||||
"start-storybook-for-app": "start-storybook -p 8001 -c .storybook-app"
|
||||
}
|
||||
...
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
### Use multiple repos
|
||||
|
||||
This is a popular option. You can create different repos for different kinds of UI components and have a storybook for each of them. Here are some ways to separate them:
|
||||
|
||||
* Have one repo for the theme, and one for the app.
|
||||
* Have one repo for each UI component and use those in different apps.
|
||||
* Have a few repos for different kinds of UI components and use them in different apps.
|
||||
- Have one repo for the theme, and one for the app.
|
||||
- Have one repo for each UI component and use those in different apps.
|
||||
- Have a few repos for different kinds of UI components and use them in different apps.
|
||||
|
@ -7,13 +7,13 @@ Sometimes, you may need to add different tags to the HTML head. This is useful f
|
||||
|
||||
You can do this very easily. Simply create a file called `head.html` inside the Storybook config directory and add tags like this:
|
||||
|
||||
~~~html
|
||||
```html
|
||||
<script src="https://use.typekit.net/xxxyyy.js"></script>
|
||||
<script>try{ Typekit.load(); } catch(e){ }</script>
|
||||
~~~
|
||||
```
|
||||
|
||||
That's it. Storybook will inject these tags.
|
||||
|
||||
> **Important**
|
||||
|
||||
>
|
||||
> Storybook will inject these tags to the iframe where your components are rendered. So, these won’t be loaded into the main Storybook UI.
|
||||
|
@ -11,7 +11,7 @@ Here are all those options:
|
||||
|
||||
## For start-storybook
|
||||
|
||||
~~~
|
||||
```log
|
||||
Usage: start-storybook [options]
|
||||
|
||||
Options:
|
||||
@ -22,11 +22,11 @@ Options:
|
||||
-h, --host [string] Host to run Storybook
|
||||
-s, --static-dir <dir-names> Directory where to load static files from
|
||||
-c, --config-dir [dir-name] Directory where to load Storybook configurations from
|
||||
~~~
|
||||
```
|
||||
|
||||
## For build-storybook
|
||||
|
||||
~~~
|
||||
```log
|
||||
Usage: build-storybook [options]
|
||||
|
||||
Options:
|
||||
@ -36,4 +36,4 @@ Options:
|
||||
-s, --static-dir <dir-names> Directory where to load static files from
|
||||
-o, --output-dir [dir-name] Directory where to store built files
|
||||
-c, --config-dir [dir-name] Directory where to load Storybook configurations from
|
||||
~~~
|
||||
```
|
||||
|
@ -2,6 +2,7 @@
|
||||
id: 'custom-webpack-config'
|
||||
title: 'Custom Webpack Config'
|
||||
---
|
||||
|
||||
**NOTE: Storybook doesn't currently support webpack 2, so write your storybook webpack config to be webpack 1.x-compatable.**
|
||||
|
||||
The default Webpack config of React Storybook is usually well balanced for a medium-size React project (specially created with [Create React App](https://github.com/facebookincubator/create-react-app)) or a library. But if you already have your own Webpack setup, that's not useable.
|
||||
@ -13,7 +14,7 @@ That's why we allow you to customize our Webpack setup. There are a few ways to
|
||||
Let's say you want to add [SASS](http://sass-lang.com/) support to Storybook. This is how to do it.
|
||||
Simply add the following content to a file called `webpack.config.js` in your Storybook config directory (`.storybook` by default ).
|
||||
|
||||
~~~js
|
||||
```js
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
@ -27,13 +28,12 @@ module.exports = {
|
||||
]
|
||||
}
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
Since this config file stays in the Storybook directory, you need to set the include path as above. If the config directory stays in a different directory, you need to set the include path relative to that.
|
||||
|
||||
You also need to install the loaders (style, css, and sass) used in above config manually.
|
||||
|
||||
|
||||
> Once you create this `webpack.config.js` file, Storybook won't load the [default Webpack config](/docs/react-storybook/configurations/default-config) other than loading JS files with the Babel loader.
|
||||
|
||||
### Supported Webpack Options
|
||||
@ -41,9 +41,9 @@ You also need to install the loaders (style, css, and sass) used in above config
|
||||
You can add any kind of Webpack configuration options with the above config, whether they are plugins, loaders, or aliases.
|
||||
But you won't be able to change the following config options:
|
||||
|
||||
* entry
|
||||
* output
|
||||
* js loader with babel
|
||||
- entry
|
||||
- output
|
||||
- js loader with babel
|
||||
|
||||
## Full Control Mode
|
||||
|
||||
@ -51,7 +51,7 @@ Sometimes, you will want to have full control over the webpack configuration. Ma
|
||||
|
||||
To enable that, you need to export a **function** from the above `webpack.config.js` file, just like this:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
// Export a function. Accept the base config as the only param.
|
||||
module.exports = function(storybookBaseConfig, configType) {
|
||||
// configType has a value of 'DEVELOPMENT' or 'PRODUCTION'
|
||||
@ -68,13 +68,13 @@ module.exports = function(storybookBaseConfig, configType) {
|
||||
// Return the altered config
|
||||
return storybookBaseConfig;
|
||||
};
|
||||
~~~
|
||||
```
|
||||
|
||||
Storybook uses the config returned from the above function. So, try to edit the `storybookBaseConfig` with care. Make sure to preserve the following config options:
|
||||
|
||||
* entry
|
||||
* output
|
||||
* first loader in the module.loaders (Babel loader for JS)
|
||||
- entry
|
||||
- output
|
||||
- first loader in the module.loaders (Babel loader for JS)
|
||||
|
||||
Other than that, you should try to keep the default set of plugins.
|
||||
|
||||
@ -83,18 +83,18 @@ Other than that, you should try to keep the default set of plugins.
|
||||
You may want to keep Storybook's [default config](/docs/react-storybook/configurations/default-config), but just need to extend it. If so, this is how you do it using the Full Control Mode.
|
||||
Add following content to the `webpack.config.js` in your Storybook config directory.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
// load the default config generator.
|
||||
var genDefaultConfig = require('@kadira/storybook/dist/server/config/defaults/webpack.config.js');
|
||||
const genDefaultConfig = require('@kadira/storybook/dist/server/config/defaults/webpack.config.js');
|
||||
|
||||
module.exports = function(config, env) {
|
||||
var config = genDefaultConfig(config, env);
|
||||
module.exports = (config, env) => {
|
||||
const config = genDefaultConfig(config, env);
|
||||
|
||||
// Extend it as you need.
|
||||
|
||||
return config;
|
||||
};
|
||||
~~~
|
||||
```
|
||||
|
||||
## Using Your Existing Config
|
||||
|
||||
@ -102,5 +102,5 @@ You may have an existing Webpack config for your project. So, you may need to co
|
||||
|
||||
But you don't need to. There are a few options:
|
||||
|
||||
* Simply import your main Webpack config into Storybook's `webpack.config.js` and use the loaders and plugins used in that.
|
||||
* Create a new file with common Webpack options and use it in both inside the main Webpack config and inside Storybook's `webpack.config.js`.
|
||||
- Simply import your main Webpack config into Storybook's `webpack.config.js` and use the loaders and plugins used in that.
|
||||
- Create a new file with common Webpack options and use it in both inside the main Webpack config and inside Storybook's `webpack.config.js`.
|
||||
|
@ -28,18 +28,18 @@ You can simply import CSS files wherever you want, whether it's in the storybook
|
||||
|
||||
Basically, you can import CSS like this:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
// locally
|
||||
import './styles.css'
|
||||
// or from NPM modules
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
~~~
|
||||
```
|
||||
|
||||
### Image and Static File Support
|
||||
|
||||
You can also import images and media files directly via JavaScript. This helps you to write stories with media files easily. This is how to do it:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf, action } from '@kadira/storybook';
|
||||
|
||||
@ -49,11 +49,10 @@ storiesOf('<img>', module)
|
||||
.add('with a image', () => (
|
||||
<img src={imageFile} />
|
||||
));
|
||||
~~~
|
||||
```
|
||||
|
||||
When you are building a storybook, we'll also export the imported image. So, this is a good approach to loading all of your static content.
|
||||
|
||||
|
||||
> Storybook also has a way to mention static directories via the -s option of the `react-storybook` and `build-storybook` commands.
|
||||
|
||||
### JSON Loader
|
||||
@ -64,6 +63,5 @@ You can import `.json` files, as you do with Node.js. This will also allow you t
|
||||
|
||||
You can use any of the NPM modules installed on your project. You can simply import and use them.
|
||||
|
||||
|
||||
> Unfortunately, we don't support Meteor packages. If your UI component includes one or more Meteor packages, try to avoid using them in UI components.
|
||||
> If they are containers, you can use [React Stubber](https://github.com/kadirahq/react-stubber) to use them in Storybook.
|
||||
|
@ -1,8 +1,8 @@
|
||||
----
|
||||
id: 'env-vars'
|
||||
title: 'Using Environment Variables'
|
||||
---
|
||||
* * *
|
||||
|
||||
id: 'env-vars'
|
||||
|
||||
## title: 'Using Environment Variables'
|
||||
|
||||
Sometimes, we may use configuration items inside Storybook. It might be a theme color, some client secret, or a JSON string. So, we usually tend to hard code them.
|
||||
|
||||
@ -10,16 +10,16 @@ But you can expose those configurations via "environment variables." For that, y
|
||||
|
||||
For an example, let's expose two environment variables like this:
|
||||
|
||||
~~~sh
|
||||
```sh
|
||||
STORYBOOK_THEME=red STORYBOOK_DATA_KEY=12345 npm run storybook
|
||||
~~~
|
||||
```
|
||||
|
||||
Then we can access these environment variables anywhere inside our JS code like below:
|
||||
|
||||
~~~js
|
||||
```js
|
||||
console.log(process.env.STORYBOOK_THEME)
|
||||
console.log(process.env.STORYBOOK_DATA_KEY)
|
||||
~~~
|
||||
```
|
||||
|
||||
> Even though we can access these env variables anywhere in the client side JS code, it's better to use them only inside stories and inside the main Storybook config file.
|
||||
|
||||
@ -33,5 +33,5 @@ Then they'll be hard coded to the static version of your Storybook.
|
||||
|
||||
In addition to the above prefixed environment variables, you can also pass the NODE_ENV variable to Storybook. But, you normally don't need to do that since we set a reasonable default value for it.
|
||||
|
||||
* When running `npm run storybook`, we set NODE_ENV to 'development'
|
||||
* When building storybook, we set NODE_ENV to 'production'
|
||||
- When running `npm run storybook`, we set NODE_ENV to 'development'
|
||||
- When building storybook, we set NODE_ENV to 'production'
|
||||
|
@ -11,8 +11,7 @@ Storybook provides two ways to do that.
|
||||
|
||||
You can import any media assets by simply importing (or requiring) them as shown below.
|
||||
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf, action } from '@kadira/storybook';
|
||||
|
||||
@ -22,8 +21,7 @@ storiesOf('<img>', module)
|
||||
.add('with a image', () => (
|
||||
<img src={imageFile} />
|
||||
));
|
||||
~~~
|
||||
|
||||
```
|
||||
|
||||
This is enabled with our [default config](/docs/react-storybook/configurations/default-config). But, if you are using a [custom Webpack config](/docs/react-storybook/configurations/custom-webpack-config), you need to add the [file-loader](https://github.com/webpack/file-loader) into your custom Webpack config.
|
||||
|
||||
@ -33,18 +31,17 @@ You can also configure a directory (or a list of directories) for searching stat
|
||||
|
||||
See the following npm script on how to use it:
|
||||
|
||||
~~~js
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"start-storybook": "start-storybook -s ./public -p 9001"
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
```
|
||||
|
||||
Here `./public` is our static directory. Now you can use static files in the public directory in your components or stories like this.
|
||||
|
||||
~~~js
|
||||
```js
|
||||
import React from 'react';
|
||||
import { storiesOf, action } from '@kadira/storybook';
|
||||
|
||||
@ -53,21 +50,21 @@ storiesOf('<img>', module)
|
||||
.add('with a image', () => (
|
||||
<img src="/image.png" />
|
||||
));
|
||||
~~~
|
||||
|
||||
```
|
||||
|
||||
> You can also pass a list of directories, instead of a single directory, as shown below.
|
||||
> ~~~js
|
||||
>
|
||||
> ```json
|
||||
> {
|
||||
> "scripts": {
|
||||
> "start-storybook": "start-storybook -s ./public,./static -p 9001"
|
||||
> }
|
||||
> }
|
||||
> ~~~
|
||||
> ```
|
||||
|
||||
## Absolute versus relative paths
|
||||
|
||||
Sometimes, you may want to deploy your storybook into a subpath, like https://kadira-samples.github.io/react-button.
|
||||
Sometimes, you may want to deploy your storybook into a subpath, like <https://kadira-samples.github.io/react-button>.
|
||||
|
||||
In this case, you need to have all your images and media files with relative paths. Otherwise, Storybook cannot locate those files.
|
||||
|
||||
|
@ -12,12 +12,12 @@ In that, you can see the Storybook's manager UI. It has UI elements that are no
|
||||
For an example, let's assume the above storybook runs on port 9009 and we can access it via [http://localhost:9009](http://localhost:9009/).
|
||||
Then Let's pick a single story: the "with text" story of the Button. So, in this case:
|
||||
|
||||
* selectedKind = Button
|
||||
* selectedStory = with text
|
||||
- selectedKind = Button
|
||||
- selectedStory = with text
|
||||
|
||||
Then, we can see the above story using the following URL:
|
||||
|
||||
http://localhost:9009/iframe.html?selectedKind=Button&selectedStory=with+text&dataId=0
|
||||
<http://localhost:9009/iframe.html?selectedKind=Button&selectedStory=with+text&dataId=0>
|
||||
|
||||

|
||||
|
||||
|
@ -1,17 +1,19 @@
|
||||
---
|
||||
id: 'manual-testing'
|
||||
title: 'Manual Testing'
|
||||
---
|
||||
---
|
||||
|
||||
Now we arrive at the most interesting (but also hardest) part of UI testing. We usually do this as a team.
|
||||
|
||||
First, we need to make a pretty solid Storybook or a set of Storybooks covering most of the scenarios of our UI components. For that we can follow the following structure:
|
||||
|
||||
* Write stories for your individual UI components.
|
||||
* Write another set of stories for integrating the above UI components (you could consider your pages).
|
||||
- Write stories for your individual UI components.
|
||||
- Write another set of stories for integrating the above UI components (you could consider your pages).
|
||||
|
||||
For the individual UI components, you may be using a different repository. Then, keep a storybook inside it for those components. Then, in the main app, write stories for integrations.
|
||||
|
||||
## Testing Plan
|
||||
|
||||
Open a new PR (or multiple of them). Then run your Storybook and start reviewing one story at a time. Then you can comment on the PR.
|
||||
|
||||
> Join our [Newsletter](http://tinyletter.com/storybooks) or [Slack Team](https://storybooks-slackin.herokuapp.com/) to get updates.
|
||||
|
@ -9,9 +9,9 @@ There are different aspects we need to look at when testing UI. There are also a
|
||||
|
||||
Before we talk about testing, we need to think about why we need to test. There are many reasons; here are some of our reasons:
|
||||
|
||||
* To find bugs.
|
||||
* To make sure things won't break between new code commits.
|
||||
* To keep tests as living documentations.
|
||||
- To find bugs.
|
||||
- To make sure things won't break between new code commits.
|
||||
- To keep tests as living documentations.
|
||||
|
||||
Specifically, testing is important when working with teams since it allows different people the ability to contribute with confidence.
|
||||
|
||||
@ -27,10 +27,10 @@ Here we'll focus on the structure of the UI and how it's laid out. For an exampl
|
||||
|
||||
For structural testing, we are testing whether or not it has following content:
|
||||
|
||||
* A title with "Login in to Facebook"
|
||||
* Two inputs for the username and password.
|
||||
* A submit button.
|
||||
* An error screen to show errors.
|
||||
- A title with "Login in to Facebook"
|
||||
- Two inputs for the username and password.
|
||||
- A submit button.
|
||||
- An error screen to show errors.
|
||||
|
||||
For React, we have been using [Enzyme](https://github.com/airbnb/enzyme) as a way to do structural testing, but now we can also use [Jest's snapshot testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html) to make things even more simple.
|
||||
|
||||
@ -40,8 +40,8 @@ UI is all about interacting with the user. We do this with a bunch of UI element
|
||||
|
||||
Let's again use the above login component as an example. It should do these things:
|
||||
|
||||
* When we click the submit button, it should give us the username and password.
|
||||
* When we click the "Forgotten Account" link, it should redirect to a new page.
|
||||
- When we click the submit button, it should give us the username and password.
|
||||
- When we click the "Forgotten Account" link, it should redirect to a new page.
|
||||
|
||||
We have few ways to do this type of testing with React. The simple way is to use [Enzyme](https://github.com/airbnb/enzyme).
|
||||
|
||||
@ -51,10 +51,10 @@ UI is all about styles (whether they're simple, beautiful, or even ugly). With s
|
||||
|
||||
If we are using inline styles all the way, we can use JEST snapshot testing. But to get even better results, we should consider using tools such as:
|
||||
|
||||
* [BackstopJS](https://github.com/garris/BackstopJS)
|
||||
* [PhantomCSS](https://github.com/Huddle/PhantomCSS)
|
||||
* [Gemini](https://github.com/gemini-testing/gemini)
|
||||
* [Happo](https://github.com/Galooshi/happo)
|
||||
- [BackstopJS](https://github.com/garris/BackstopJS)
|
||||
- [PhantomCSS](https://github.com/Huddle/PhantomCSS)
|
||||
- [Gemini](https://github.com/gemini-testing/gemini)
|
||||
- [Happo](https://github.com/Galooshi/happo)
|
||||
|
||||
### 4. Manual Testing
|
||||
|
||||
@ -70,7 +70,7 @@ A **story** is a smallest unit in Storybook. It's a fully functioning UI element
|
||||
|
||||
Let's look at how Storybook can help you do the above mentioned different aspects of testing.
|
||||
|
||||
* [Structural Testing with StoryShots](/docs/react-storybook/testing/structural-testing)
|
||||
* [Interaction Testing with Specs Addon](/docs/react-storybook/testing/interaction-testing)
|
||||
* [Storybook as the Base for CSS/Style Testing](/docs/react-storybook/testing/css-style-testing)
|
||||
* [Storybook for Manual UI Testing](/docs/react-storybook/testing/manual-testing)
|
||||
- [Structural Testing with StoryShots](/docs/react-storybook/testing/structural-testing)
|
||||
- [Interaction Testing with Specs Addon](/docs/react-storybook/testing/interaction-testing)
|
||||
- [Storybook as the Base for CSS/Style Testing](/docs/react-storybook/testing/css-style-testing)
|
||||
- [Storybook for Manual UI Testing](/docs/react-storybook/testing/manual-testing)
|
||||
|
@ -13,8 +13,8 @@ Then, after we've completed any UI changes, we compare new snapshots with the sn
|
||||
|
||||
If things are not the same, we can do two things:
|
||||
|
||||
1. We can consider new snapshots that show the current state, and then update them as new snapshots.
|
||||
2. We can find the root cause for the change and fix our code.
|
||||
1. We can consider new snapshots that show the current state, and then update them as new snapshots.
|
||||
2. We can find the root cause for the change and fix our code.
|
||||
|
||||
> We can also commit these snapshots directly into the source code.
|
||||
|
||||
@ -25,33 +25,34 @@ If things are not the same, we can do two things:
|
||||
First, make sure you are inside a Storybook-enabled repo (make sure it has few stories).
|
||||
Then, install StoryShots into your app with:
|
||||
|
||||
~~~sh
|
||||
```sh
|
||||
npm i -D @kadira/storyshots
|
||||
~~~
|
||||
```
|
||||
|
||||
Then, add the following NPM script into your package.json:
|
||||
|
||||
~~~js
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"test-storybook": "storyshots"
|
||||
}
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
Now you can run the above command with:
|
||||
~~~sh
|
||||
|
||||
```sh
|
||||
npm run test-storybook
|
||||
~~~
|
||||
```
|
||||
|
||||
This will save the initial set of snapshots inside your Storybook config directory.
|
||||
|
||||

|
||||

|
||||
|
||||
After you complete any changes, you can run the above NPM script again and find our structural changes.
|
||||
|
||||

|
||||
|
||||
---
|
||||
* * *
|
||||
|
||||
StoryShots also comes with a few important [productive features](https://github.com/storybooks/storybook/tree/master/packages/storyshots#key-features) that can be customized. Have a look at the StoryShots [repo](https://github.com/storybooks/storybook/tree/master/packages/storyshots) for more information.
|
||||
|
@ -6,12 +6,12 @@ A real documentation site would have live examples here. But since this
|
||||
site isn't documenting anything real, here's the list of modules used on
|
||||
this site.
|
||||
|
||||
* [React](https://facebook.github.io/react/docs/)
|
||||
* [GatsbyJS](https://github.com/gatsbyjs/gatsby)
|
||||
* [TypographyJS](https://kyleamathews.github.io/typography.js/#/)
|
||||
* [React Router](https://github.com/rackt/react-router)
|
||||
* [Underscore.String](http://epeli.github.io/underscore.string/)
|
||||
* [React Responsive Grid](http://kyleamathews.github.io/react-responsive-grid/#/)
|
||||
* [Color Pairs Picker](http://kyleamathews.github.io/color-pairs-picker/)
|
||||
* [React Document Title](https://github.com/gaearon/react-document-title)
|
||||
* [Lodash](https://lodash.com/)
|
||||
- [React](https://facebook.github.io/react/docs/)
|
||||
- [GatsbyJS](https://github.com/gatsbyjs/gatsby)
|
||||
- [TypographyJS](https://kyleamathews.github.io/typography.js/#/)
|
||||
- [React Router](https://github.com/rackt/react-router)
|
||||
- [Underscore.String](http://epeli.github.io/underscore.string/)
|
||||
- [React Responsive Grid](http://kyleamathews.github.io/react-responsive-grid/#/)
|
||||
- [Color Pairs Picker](http://kyleamathews.github.io/color-pairs-picker/)
|
||||
- [React Document Title](https://github.com/gaearon/react-document-title)
|
||||
- [Lodash](https://lodash.com/)
|
||||
|
14
scripts/travis/after_success.sh
Executable file
14
scripts/travis/after_success.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||
echo "We are in a pull request, not releasing"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $TRAVIS_BRANCH == 'source' ]]; then
|
||||
npm run build
|
||||
git config --global user.email "nobody@nobody.org"
|
||||
git config --global user.name "Travis CI"
|
||||
npm run deploy-travis
|
||||
fi
|
38
scripts/travis/before_install.sh
Executable file
38
scripts/travis/before_install.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
# Note: do not do set -x or the passwords will leak!
|
||||
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||
echo "We are in a pull request, not setting up release"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $TRAVIS_BRANCH == 'master' ]]; then
|
||||
# rm -rf .git
|
||||
# git init
|
||||
# git clean -dfx
|
||||
# git remote add origin https://github.com/atlassian/lerna-semantic-release.git
|
||||
# git fetch origin
|
||||
# git clone https://github.com/$TRAVIS_REPO_SLUG.git $TRAVIS_REPO_SLUG
|
||||
# git checkout $TRAVIS_BRANCH
|
||||
#
|
||||
# git config credential.helper store
|
||||
# echo "https://${RELEASE_GH_USERNAME}:${RELEASE_GH_TOKEN}@github.com/atlassian/lerna-semantic-release.git" > ~/.git-credentials
|
||||
#
|
||||
# npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN -q
|
||||
# npm prune
|
||||
#
|
||||
# git config --global user.email "design-platform@atlassian.com"
|
||||
# git config --global user.name "Design Platform"
|
||||
# git config --global push.default simple
|
||||
#
|
||||
# git fetch --tags
|
||||
# git branch -u origin/$TRAVIS_BRANCH
|
||||
# git fsck --full #debug
|
||||
# echo "npm whoami"
|
||||
# npm whoami #debug
|
||||
# echo "git config --list"
|
||||
# git config --list #debug
|
||||
echo "We are on master"
|
||||
exit 0
|
||||
fi
|
Loading…
x
Reference in New Issue
Block a user