diff --git a/docs/src/pages/configurations/custom-webpack-config/index.md b/docs/src/pages/configurations/custom-webpack-config/index.md
index d4d9d2e8c704..fe5ef3d0b5ac 100644
--- a/docs/src/pages/configurations/custom-webpack-config/index.md
+++ b/docs/src/pages/configurations/custom-webpack-config/index.md
@@ -16,10 +16,10 @@ There are a few ways to do it:
You'll get _extend-mode_ by returning an object.
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 ).
+Add the following content to a file called `webpack.config.js` in your Storybook config directory (`.storybook` by default ).
```js
-const path = require('path');
+const path = require("path");
module.exports = {
module: {
@@ -27,11 +27,11 @@ module.exports = {
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
- include: path.resolve(__dirname, '../')
+ include: path.resolve(__dirname, "../")
}
]
}
-}
+};
```
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.
@@ -45,9 +45,9 @@ You also need to install the loaders (style, css, sass, as well as node-sass) us
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
For the advanced usage we strongly recommend [full control mode](#full-control-mode).
@@ -60,7 +60,7 @@ That's where you can use our full control mode.
To enable that, you need to export a **function** from the above `webpack.config.js` file, just like this:
```js
-const path = require('path');
+const path = require("path");
// Export a function. Accept the base config as the only param.
module.exports = (storybookBaseConfig, configType) => {
@@ -72,7 +72,7 @@ module.exports = (storybookBaseConfig, configType) => {
storybookBaseConfig.module.rules.push({
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
- include: path.resolve(__dirname, '../')
+ include: path.resolve(__dirname, "../")
});
// Return the altered config
@@ -82,10 +82,10 @@ module.exports = (storybookBaseConfig, configType) => {
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)
-- all existing plugins
+* entry
+* output
+* first loader in the module.loaders (Babel loader for JS)
+* all existing plugins
> If your custom webpack config uses a loader that does not explicitly include specific file extensions via the `test` property, it is necessary to `exclude` the `.ejs` file extension from that loader.
@@ -96,7 +96,7 @@ 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
-const path = require('path');
+const path = require("path");
module.exports = (baseConfig, env, defaultConfig) => {
// Extend defaultConfig as you need.
@@ -104,20 +104,22 @@ module.exports = (baseConfig, env, defaultConfig) => {
// For example, add typescript loader:
defaultConfig.module.rules.push({
test: /\.(ts|tsx)$/,
- include: path.resolve(__dirname, '../src'),
- loader: require.resolve('ts-loader')
+ include: path.resolve(__dirname, "../src"),
+ loader: require.resolve("ts-loader")
});
- defaultConfig.resolve.extensions.push('.ts', '.tsx');
+ defaultConfig.resolve.extensions.push(".ts", ".tsx");
return defaultConfig;
};
```
+For full instructions on Typescript setup, check [our dedicated Typescript page](/configurations/typescript-config/).
+
## Using Your Existing Config
You may have an existing Webpack config for your project. So, you may need to copy and paste some config items into Storybook's custom Webpack config file.
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`.
+* 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`.
diff --git a/docs/src/pages/configurations/typescript-config/index.md b/docs/src/pages/configurations/typescript-config/index.md
new file mode 100644
index 000000000000..83365957de0c
--- /dev/null
+++ b/docs/src/pages/configurations/typescript-config/index.md
@@ -0,0 +1,219 @@
+---
+id: 'typescript-config'
+title: 'Typescript Config'
+---
+
+This is a central reference for using Storybook with Typescript.
+
+## Dependencies you may need
+
+```bash
+yarn add -D typescript
+yarn add -D awesome-typescript-loader
+yarn add -D @storybook/addon-info react-docgen-typescript-webpack-plugin # optional but recommended
+yarn add -D jest "@types/jest" ts-jest #testing
+```
+
+We have had the best experience using `awesome-typescript-loader`, but other tutorials may use `ts-loader`, just configure accordingly. You can even use `babel-loader` with a `ts-loader` configuration.
+
+## Setting up Typescript to work with Storybook
+
+We first have to use the [custom Webpack config in full control mode, extending default configs](/configurations/custom-webpack-config/#full-control-mode--default):
+
+```js
+const path = require("path");
+const TSDocgenPlugin = require("react-docgen-typescript-webpack-plugin");
+module.exports = (baseConfig, env, config) => {
+ config.module.rules.push({
+ test: /\.(ts|tsx)$/,
+ loader: require.resolve("awesome-typescript-loader")
+ });
+ config.plugins.push(new TSDocgenPlugin()); // optional
+ config.resolve.extensions.push(".ts", ".tsx");
+ return config;
+};
+```
+
+The above example shows a working config with the TSDocgen plugin also integrated; remove the optional sections if you don't plan on using them.
+
+## `tsconfig.json`
+
+```json
+{
+ "compilerOptions": {
+ "outDir": "build/lib",
+ "module": "commonjs",
+ "target": "es5",
+ "lib": ["es5", "es6", "es7", "es2017", "dom"],
+ "sourceMap": true,
+ "allowJs": false,
+ "jsx": "react",
+ "moduleResolution": "node",
+ "rootDirs": ["src", "stories"],
+ "baseUrl": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "suppressImplicitAnyIndexErrors": true,
+ "noUnusedLocals": true,
+ "declaration": true,
+ "allowSyntheticDefaultImports": true,
+ "experimentalDecorators": true
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "build", "scripts"]
+}
+```
+
+This is for the default configuration where `/stories` is a peer of `src`. If you have them all in just `src` you may wish to replace `"rootDirs": ["src", "stories"]` above with `"rootDir": "src",`.
+
+## Using Typescript with the TSDocgen addon
+
+The very handy [Storybook Info addon](https://github.com/storybooks/storybook/tree/master/addons/info) autogenerates prop tables documentation for each component, however it doesn't work with Typescript types. The current solution is to use [react-docgen-typescript-loader](https://github.com/strothj/react-docgen-typescript-loader) to preprocess the Typescript files to give the Info addon what it needs. The webpack config above does this, and so for the rest of your stories you use it as per normal:
+
+```js
+import React from "react";
+import { storiesOf } from "@storybook/react";
+import { withInfo } from "@storybook/addon-info";
+import { action } from "@storybook/addon-actions";
+import TicTacToeCell from "./TicTacToeCell";
+
+const stories = storiesOf("Components", module);
+
+stories.add(
+ "TicTacToeCell",
+ withInfo({ inline: true })(() => )
+);
+```
+
+## Customizing Type annotations/descriptions
+
+Please refer to the [react-docgen-typescript-loader](https://github.com/strothj/react-docgen-typescript-loader) docs for writing prop descriptions and other annotations to your Typescript interfaces.
+
+Additional annotation can be achieved by creating a `wInfo` higher order component:
+
+```js
+import { withInfo } from "@storybook/addon-info";
+const wInfoStyle = {
+ header: {
+ h1: {
+ marginRight: "20px",
+ fontSize: "25px",
+ display: "inline"
+ },
+ body: {
+ paddingTop: 0,
+ paddingBottom: 0
+ },
+ h2: {
+ display: "inline",
+ color: "#999"
+ }
+ },
+ infoBody: {
+ backgroundColor: "#eee",
+ padding: "0px 5px",
+ lineHeight: "2"
+ }
+};
+export const wInfo = text => withInfo({ inline: true, source: false, styles: wInfoStyle, text: text });
+```
+
+This can be used like so:
+
+```js
+import React from "react";
+
+import { storiesOf } from "@storybook/react";
+import { PrimaryButton } from "./Button";
+import { wInfo } from "../../utils";
+import { text, select, boolean } from "@storybook/addon-knobs/react";
+
+storiesOf("Components/Button", module).addWithJSX(
+ "basic PrimaryButton",
+ wInfo(`
+
+ ### Notes
+
+ light button seen on
+
+ ### Usage
+ ~~~js
+ alert('hello there')}
+ />
+ ~~~
+
+`)(() => (
+ alert("hello there")}
+ />
+ ))
+);
+```
+
+And this is how it looks:
+
+![image](https://user-images.githubusercontent.com/35976578/38376038-ac02b432-38c5-11e8-9aed-f4fa2e258f60.png)
+
+Note: Component docgen information can not be generated for components that are only exported as default. You can work around the issue by exporting the component using a named export.
+
+## Setting up Jest tests
+
+The ts-jest [README](https://github.com/kulshekhar/ts-jest) explains pretty clearly how to get Jest to recognize TypeScript code.
+
+This is an example package.json config for jest:
+
+```json
+"jest": {
+ "transform": {
+ ".(ts|tsx)": "/node_modules/ts-jest/preprocessor.js"
+ },
+ "mapCoverage": true,
+ "testPathIgnorePatterns": [
+ "/node_modules/",
+ "/lib/"
+ ],
+ "testRegex": "(/test/.*|\\.(test|spec))\\.(ts|tsx|js)$",
+ "moduleFileExtensions": [
+ "ts",
+ "tsx",
+ "js",
+ "json"
+ ]
+}
+```
+
+## Building your Typescript Storybook
+
+You will need to set up some scripts - these may help:
+
+```json
+ "scripts": {
+ "start": "react-scripts-ts start",
+ "build": "npm run lint && npm run build-lib && build-storybook",
+ "build-lib-watch": "tsc -w",
+ "build-lib": "tsc && npm run copy-css-to-lib && npm run copy-svg-to-lib && npm run copy-png-to-lib && npm run copy-woff2-to-lib",
+ "test": "react-scripts-ts test --env=jsdom",
+ "test:coverage": "npm test -- --coverage",
+ "eject": "react-scripts-ts eject",
+ "storybook": "start-storybook -p 6006",
+ "build-storybook": "build-storybook",
+ "copy-css-to-lib": "cpx \"./src/**/*.css\" ./build/lib",
+ "copy-woff2-to-lib": "cpx \"./src/**/*.woff2\" ./build/lib",
+ "copy-svg-to-lib": "cpx \"./src/**/*.svg\" ./build/lib",
+ "copy-png-to-lib": "cpx \"./src/**/*.png\" ./build/lib",
+ "lint": "tslint -c tslint.json 'src/**/*.{ts,tsx}'"
+ },
+```
+
+## Related Issues and Helpful Resources
+
+* [Storybook, React, TypeScript and Jest](https://medium.com/@mtiller/storybook-react-typescript-and-jest-c9059ea06fa7)
+* [React, Storybook & TypeScript](http://www.joshschreuder.me/react-storybooks-with-typescript/)