# Storybook readme

# Usage
We use [storybook](https://storybook.js.org/) to build our UI component page. You can reference official docs for more details.
## How to run storybook
```
npm run storybook
```
## File Hierarchy
- `media_v2/js/stories/*.stories.js` where to be parsed story files by storybook for creating document page.
- `media_v2/js/stories/mocks` where to mock global package that used in component.
- `.storybook/.config.js` where to define global variable that used in component.
- `.storybook/.main.js` where to settle webpack.config for storybook
The basic file name of a single stroy page is just like `{group or component name}.stories.js`
(e.g. media_v2/js/stories/Form.stories.js).
(e.g. media_v2/js/stories/Pagination.stories.js).
## How to create a new story
The following is some case to create stories.
### Basic

After creat Button.stories.js file, you just need define 3 parts.
1. import js and style files for this component that you want to introduce.
```
import React from 'react';
import * as Button from 'app/modules/react/button';
import 'modules/button.css';
```
2. define the stories name
```
export default {
title: "Button"
};
```
3. export component and the exported name will be the story name. and you can export many stories in this stories.js file.
```
export const ButtonComponent = () => (
<Button label="test" theme="primary"></Button>
)
```
### Addon-Actions and Addon-Knobs
Use some storybook addon components to support document. See more detail in
[official docs](https://storybook.js.org/addons/).

1. import addon components into stories.js
```
import { action } from '@storybook/addon-actions';
import { text, boolean, select} from "@storybook/addon-knobs";
```
2. Fill in component props. And you can controll the props in the view instantly.
```
export const Dynamic = () => (
<Button
label={text('label', 'custom-button')}
theme={select('theme', themeTypes, themeTypes[0])}
size={select('size', sizes, sizes[0])}
labelNoWrapped={boolean('labelNoWrapped', false)}
isFullWidth={boolean('isFullWidth', false)}
isDisabled={boolean('isDisabled', false)}
isLabelCenter={boolean('isLabelCenter', false)}
isInline={boolean('isInline', false)}
iconName={text('iconName', 'btn-display-collapse')}
{...methods}
/>
);
```
## How to mock global variables or package in component
Because too many coupling in our production component, we can't use them in storybook directly. If do it, you will get ```XXX not defined```. (e.g. `i18n`、`settings`、`Modernizr`).
If you meet this situation, you can try the following method to mock thme.
### Define mock global variable
In `.storybook/config.js` you can define global variable. (e.g. jquery、Modernizer、dataLayer)
```
import $ from 'jquery';
window.$ = $;
window.Modernizr = {
android: true,
ios: false,
prefixed: prop=>prop
}
window.dataLayer = {
push: ()=>{}
}
```
### Mock package module
In production we define many useful AMD module but out of webpack.
In in storybook we can't transfter to AMD module, the storybook will throw errors. And We can try to mock them by webpack module alias. (e.g. i18n、settings)
You can write webpack resolve.alias to use mock module.
1. Write mock module into ```media_v2/js/stories/mocks```. e.g. i18n module
```
const Jed = require('jed');
let i18n = new Jed({
"domain": "messages",
"locale_data": {
"messages": {
"": {"domain": "messages"}
}
}
});
i18n.gettext = (word)=>word;
module.exports = i18n;
```
2. Write alias into webpack ```.storybook/main.js```.
```
config.resolve.alias = {
...
'i18n': 'stories/mocks/i18n.js'
};
```