mirror of
https://github.com/storybookjs/storybook.git
synced 2025-03-19 05:02:40 +08:00
Merge pull request #11685 from storybookjs/migrate_configure_6_0
Migrate configure section to 6 0
This commit is contained in:
commit
b03dce3baf
BIN
docs/configure/addon-locations.jpg
Normal file
BIN
docs/configure/addon-locations.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
307
docs/configure/integration.md
Normal file
307
docs/configure/integration.md
Normal file
@ -0,0 +1,307 @@
|
||||
---
|
||||
title: 'Integration'
|
||||
---
|
||||
|
||||
### Webpack
|
||||
|
||||
Storybook displays your components in a custom web application built using [webpack](https://webpack.js.org/). Webpack is a complex tool but our default configuration is intended to cover off the majority of use cases. There are also [addons](/addons) available that extend the configuration for other common use cases.
|
||||
|
||||
You can customize Storybook's webpack setup by providing a `webpackFinal` field in [`.storybook/main.js`](./overview#configure-your-storybook-project) file.
|
||||
|
||||
The value should be an async function that receives a webpack config and eventually returns a webpack config.
|
||||
|
||||
#### Default configuration
|
||||
|
||||
By default, Storybook's webpack configuration will allow you to:
|
||||
|
||||
- Import Images and other static files
|
||||
|
||||
You can import images and other local files and have them built into the Storybook:
|
||||
|
||||
```js
|
||||
// This will include './static/image.png' in the bundle and return a path to be included in a src attribute
|
||||
import imageFile from './static/image.png';
|
||||
```
|
||||
|
||||
- Import JSON as JavaScript
|
||||
|
||||
You can import `.json` files and have them expanded to a JavaScript object:
|
||||
|
||||
```js
|
||||
// This will automatically be parsed to the contents of `data.json`
|
||||
import data from './data.json';
|
||||
```
|
||||
|
||||
If you want to know the exact details of the webpack config, the best way is to run:
|
||||
|
||||
```sh
|
||||
yarn storybook --debug-webpack
|
||||
```
|
||||
|
||||
#### Extending Storybook’s webpack config
|
||||
|
||||
To extend the above configuration, use the `webpackFinal` field of [`.storybook/main.js`](./overview#configure-story-rendering).
|
||||
|
||||
The value should export a `function`, which will receive the default config as its first argument. The second argument is an options object from Storybook, this will have information about where config came from, whether we're in production of development mode etc.
|
||||
|
||||
For example, here's a `.storybook/main.js` to add [Sass](https://sass-lang.com/) support:
|
||||
|
||||
```js
|
||||
// .storybook/main.js
|
||||
|
||||
const path = require('path');
|
||||
|
||||
// Export a function. Accept the base config as the only param.
|
||||
module.exports = {
|
||||
webpackFinal: async (config, { configType }) => {
|
||||
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
|
||||
// You can change the configuration based on that.
|
||||
// 'PRODUCTION' is used when building the static version of storybook.
|
||||
|
||||
// Make whatever fine-grained changes you need
|
||||
config.module.rules.push({
|
||||
test: /\.scss$/,
|
||||
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||
include: path.resolve(__dirname, '../'),
|
||||
});
|
||||
|
||||
// Return the altered config
|
||||
return config;
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Storybook uses the config returned from the above function to render your components in Storybook's "preview" iframe. Note that Storybook has a completely separate webpack config for its own UI (also referred to as the "manager"), so the customizations you make only applies to the rendering of your stories, i.e. you can completely replace `config.module.rules` if you want.
|
||||
|
||||
Nevertheless, edit `config` with care. Make sure to preserve the following config options:
|
||||
|
||||
- **entry**
|
||||
- **output**
|
||||
|
||||
Furthermore, `config` requires the `HtmlWebpackplugin` to generate the preview page, so rather than overwriting `config.plugins` you should probably append to it (or overwrite it with care), see [the following issue](https://github.com/storybookjs/storybook/issues/6020) for examples on how to handle this:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
webpackFinal: (config) => {
|
||||
config.plugins.push(...);
|
||||
return config;
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Finally, 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.
|
||||
|
||||
If you're using a non-standard Storybook config directory, you should put `main.js` there instead of `.storybook` and update the `include` path to make sure that it resolves to your project root.
|
||||
|
||||
#### Using your existing config
|
||||
|
||||
If you have an existing webpack config for your project and want to reuse this app's configuration, you can import your main webpack config into Storybook's [`.storybook/main.js`](./overview#configure-story-rendering) and merge both:
|
||||
|
||||
The following code snippet shows how you can replace the loaders from Storybook with the ones from your app's `webpack.config.js`:
|
||||
|
||||
```js
|
||||
// .storybook/main.js
|
||||
const path = require('path');
|
||||
|
||||
// your app's webpack.config.js
|
||||
const custom = require('../webpack.config.js');
|
||||
|
||||
module.exports = {
|
||||
webpackFinal: (config) => {
|
||||
return { ...config, module: { ...config.module, rules: custom.module.rules } };
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Babel
|
||||
|
||||
Storybook’s webpack config by [default](#default-configuration) sets up [Babel](https://babeljs.io/) for ES6 transpiling. Storybook works with evergreen browsers and IE11 by default.
|
||||
|
||||
Here are some key features of Storybook's Babel configurations.
|
||||
|
||||
#### Default configuration
|
||||
|
||||
We have added ES2016 support with Babel for transpiling your JS code.
|
||||
|
||||
In addition to that, we've added a few additional features, like object spreading and async await.
|
||||
|
||||
Check out our [source](https://github.com/storybookjs/storybook/blob/master/lib/core/src/server/common/babel.js) to learn more about these plugins.
|
||||
|
||||
#### Custom configuration
|
||||
|
||||
If your project has a `.babelrc` file, we'll use that instead of the default config file.
|
||||
|
||||
You can also place a `.storybook/.babelrc` file to use a special configuration for Storybook only.
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
Storybook has built-in Typescript support, so your Typescript project should work with zero configuration needed.
|
||||
|
||||
#### Default configuration
|
||||
|
||||
The base Typescript configuration uses [`babel-loader`](https://webpack.js.org/loaders/babel-loader/) for Typescript transpilation, and optionally [`fork-ts-checker-webpack-plugin`](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin) for checking.
|
||||
|
||||
Each framework uses the base configuration unless otherwise specified:
|
||||
|
||||
- Angular ignores the base and uses `ts-loader` and `ngx-template-loader`.
|
||||
- Vue ignores the base and uses `ts-loader` and applies it to both `.tsx` and `.vue` files.
|
||||
- React adds `react-docgen-typescript-plugin` to the base.
|
||||
|
||||
|
||||
#### Main.js configuration
|
||||
|
||||
To make it easier to configure Typescript handling, use the `typescript` field in your [`.storybook/main.js`](./overview#configure-story-rendering).
|
||||
|
||||
The following code snippets shows the fields for you to use with TypeScript:
|
||||
|
||||
```js
|
||||
// .storybook/main.js
|
||||
module.exports = {
|
||||
typescript: {
|
||||
check: false,
|
||||
checkOptions: {},
|
||||
reactDocgen: 'react-docgen-typescript',
|
||||
reactDocgenTypescriptOptions: {
|
||||
shouldExtractLiteralValuesFromEnum: true,
|
||||
propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
|Field |Framework |Description |Type |
|
||||
|:-------------------------------|:------------:|:---------------------------------------------------------------------------------------:|:--------:|
|
||||
|**check** |All |optionally run fork-ts-checker-webpack-plugin |boolean |
|
||||
|**checkOptions** |All |Options to pass to fork-ts-checker-webpack-plugin if it's enabled |[See docs](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin) |
|
||||
|**reactDocgen** |React |which variant docgen processor to run `'react-docgen-typescript' |N/A |
|
||||
|**reactDocgenTypescriptOptions**|React |Options to pass to react-docgen-typescript-plugin if react-docgen-typescript is enabled. |[See docs](https://github.com/hipstersmoothie/react-docgen-typescript-plugin) |
|
||||
|
||||
|
||||
|
||||
### Styling and CSS
|
||||
|
||||
There are many ways to include CSS in a web application, and correspondingly there are many ways to include CSS in Storybook. Usually it is best to try and replicate what your application does with styling in Storybook’s configuration.
|
||||
|
||||
#### CSS-in-JS
|
||||
|
||||
CSS-in-JS libraries are designed to use basic JavaScript. They often work in Storybook without any extra configuration. Some libraries expect components to be rendered in a specific rendering “context” (for example, to provide themes) and you may need to add a [global decorator](../writing-stories/decorators#global-decorators) to supply it.
|
||||
|
||||
#### Importing CSS files
|
||||
|
||||
If your component files import their own CSS, Storybook’s webpack config will work unmodified with some exceptions:
|
||||
|
||||
- If you are using a CSS precompiler, you may need to add a preset (such as the [SCSS preset](https://github.com/storybookjs/presets/tree/master/packages/preset-scss), or add a loader to Storybook’s webpack config).
|
||||
- In Angular, you'll need to take special care how you handle CSS:
|
||||
- Either [customize your webpack config](#extending-storybooks-webpack-config)
|
||||
- Or use syntax to use a inline loader:
|
||||
```js
|
||||
import '!style-loader!css-loader!./styles.css';
|
||||
```
|
||||
|
||||
|
||||
To use your CSS in all stories, you simply import it in [`.storybook/preview.js`](./overview#configure-story-rendering)
|
||||
|
||||
#### Adding webfonts
|
||||
|
||||
If you need webfonts to be available, you may need to add some code to the [`.storybook/preview-head.html`](./story-rendering#adding-to-head) file. We recommend including any assets with your Storybook if possible, in which case you likely want to configure the [static file location](#serving-static-files-via-storybook).
|
||||
|
||||
### Images and assets
|
||||
|
||||
Components often rely on images, videos, and other assets to render as the user expects. There are many ways to use these assets in your story files.
|
||||
|
||||
#### Import assets into stories
|
||||
|
||||
You can import any media assets by importing (or requiring) them. This works out of the box with our default config. But, if you are using a custom webpack config, you’ll need to add the file-loader to handle the required files.
|
||||
|
||||
Afterwards you can use any asset in your stories:
|
||||
|
||||
```js
|
||||
// your-story-with-assets.story.js
|
||||
|
||||
import React from 'react';
|
||||
import imageFile from './static/image.png';
|
||||
|
||||
export default {
|
||||
title: 'img',
|
||||
};
|
||||
|
||||
const image = {
|
||||
src: imageFile,
|
||||
alt: 'my image',
|
||||
};
|
||||
|
||||
export const withAnImage = () => (
|
||||
<img src={image.src} alt={image.alt} />
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
#### Serving static files via Storybook
|
||||
|
||||
We recommend serving static files via Storybook to ensure that your components always have the assets they need to load.
|
||||
|
||||
Configure a directory (or a list of directories) where your assets live when starting Storybook. Use the` -s` flag in your npm script like so:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"start-storybook": "start-storybook -s ./public -p 9001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here `./public` is your static directory. Now use it in a component or story like this.
|
||||
|
||||
```js
|
||||
// your-story-with-asset.story.js
|
||||
import React from 'react';
|
||||
|
||||
export default {
|
||||
title: 'img',
|
||||
};
|
||||
|
||||
// assume image.png is located in the "public" directory.
|
||||
export const withAnImage = () => (
|
||||
<img src="/image.png" alt="my image" />
|
||||
);
|
||||
```
|
||||
|
||||
You can also pass a list of directories separated by commas without spaces instead of a single directory.
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"start-storybook": "start-storybook -s ./public,./static -p 9001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Reference assets from a CDN
|
||||
|
||||
Upload your files to an online CDN and reference them. In this example we’re using a placeholder image service.
|
||||
|
||||
```js
|
||||
// your-story-with-CDN-asset.story.js
|
||||
import React from 'react';
|
||||
|
||||
export default {
|
||||
title: 'img',
|
||||
};
|
||||
|
||||
// assume image.png is located in the "public" directory.
|
||||
export const withAnImage = () => (
|
||||
<img src="https://placehold.it/350x150" alt="My CDN placeholder" />
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
#### Absolute versus relative paths
|
||||
|
||||
Sometimes, you may want to deploy your storybook into a subpath, like `https://example.com/storybook`.
|
||||
|
||||
In this case, you need to have all your images and media files with relative paths. Otherwise, the browser cannot locate those files.
|
||||
|
||||
If you load static content via importing, this is automatic and you do not have to do anything.
|
||||
|
||||
If you are serving assets in a [static directory](#serving-static-files-via-storybook) along with your Storybook, then you need to use relative paths to load images or use the base element.
|
73
docs/configure/overview.md
Normal file
73
docs/configure/overview.md
Normal file
@ -0,0 +1,73 @@
|
||||
---
|
||||
title: 'Overview'
|
||||
---
|
||||
|
||||
Storybook is configured via a folder, called `.storybook` which contains various configuration files.
|
||||
|
||||
<div class="aside">
|
||||
|
||||
Note you can change the folder that Storybook uses by setting the `-c` flag to your `start-storybook` and `build-storybook` scripts.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### Configure your Storybook project
|
||||
|
||||
The main configuration file is `main.js`. This file controls the behaviour of the Storybook server, and so you must restart Storybook’s process when you change it. It contains the following:
|
||||
|
||||
```js
|
||||
// .storybook/main.js
|
||||
|
||||
module.exports = {
|
||||
stories: ['../src/**/*.stories.(js|mdx)'],
|
||||
addons: ['@storybook/addon-essentials']
|
||||
}
|
||||
```
|
||||
|
||||
The `main.js` configuration file is a [preset](../api/addons#addon-presets) and as such has a powerful interface, but the key fields within it are:
|
||||
|
||||
- `stories` - a array of globs that indicates the [location of your story files](#configure-story-loading), relative to `main.js`.
|
||||
- `addons` - a list of the [addons](/addons) you are using.
|
||||
- `webpackFinal` - custom [webpack configuration](./integration#extending-storybooks-webpack-config).
|
||||
- `babel` - custom [babel configuration](./integration#babel).
|
||||
|
||||
### Configure story loading
|
||||
|
||||
By default, Storybook will load stories from your project based on a glob (pattern matching string) in `.storybook/main.js` that matches all files in your project with extension `.stories.js`. The intention is you colocate a story file with the component it documents.
|
||||
|
||||
```
|
||||
•
|
||||
└── components
|
||||
├── Button.js
|
||||
└── Button.stories.js
|
||||
```
|
||||
|
||||
If you want to use a different naming convention, you can alter the glob, using the syntax supported by [micromatch](https://github.com/micromatch/micromatch#extended-globbing).
|
||||
|
||||
For example if you wanted to pull both `.md` and `.js` files from the `my-project/src/components` directory, you could write:
|
||||
|
||||
```js
|
||||
// .storybook/main.js
|
||||
|
||||
module.exports = {
|
||||
stories: ['../my-project/src/components/*.@(js|md)'],
|
||||
};
|
||||
```
|
||||
|
||||
### Configure story rendering
|
||||
|
||||
To control the way stories are rendered and add global [decorators](../writing-stories/decorators#global-decorators) and [parameters](..writing-stories/parameters#global-parameters), create a `.storybook/preview.js` file. This is loaded in the Canvas tab, the “preview” iframe that renders your components in isolation. Use `preview.js` for global code (such as [CSS imports](../get-started/setup#render-component-styles) or JavaScript mocks) that applies to all stories.
|
||||
|
||||
The `preview.js` file can be an ES module and export the following keys:
|
||||
|
||||
- `decorators` - an array of global [decorators](../writing-stories/decorators#global-decorators)
|
||||
- `parameters` - an object of global [parameters](..writing-stories/parameters#global-parameters)
|
||||
- `globalTypes` - definition of [globalTypes](../essentials/toolbars-and-globals#global-types-and-the-toolbar-annotation)
|
||||
|
||||
If you’re looking to change how your stories are ordered, read about [sorting stories](../writing-stories/naming-components-and-hierarchy#sorting-stories).
|
||||
|
||||
### Configure Storybook’s UI
|
||||
|
||||
To control the behaviour of Storybook’s UI (the **“manager”**), you can create a `.storybook/manager.js` file.
|
||||
|
||||
This file does not have a specific API but is the place to set [UI options](./user-interface) and to configure Storybook’s [theme](./user-interface#theming).
|
BIN
docs/configure/sidebar-anatomy.jpg
Normal file
BIN
docs/configure/sidebar-anatomy.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
docs/configure/sidebar-roots.jpg
Normal file
BIN
docs/configure/sidebar-roots.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
54
docs/configure/story-rendering.md
Normal file
54
docs/configure/story-rendering.md
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
title: 'Story rendering'
|
||||
---
|
||||
|
||||
In Storybook, your stories render in a special “preview” iframe (Canvas tab) inside the larger Storybook web application. The JavaScript build configuration of the preview is controlled by a [webpack](./integration#default-configuration) config, but you also may want to directly control the HTML that is rendered to help your stories render correctly.
|
||||
|
||||
|
||||
### Adding to <head>
|
||||
|
||||
If you need to add extra elements to the `head` of the preview iframe, for instance to load static stylesheets, font files, or similar, you can create a file called [`.storybook/preview-head.html`](./overview#configure-story-rendering) and add tags like this:
|
||||
|
||||
```html
|
||||
<!-- .storybook/preview-head.html -->
|
||||
|
||||
<!-- Pull in static files served from your Static director or the internet -->
|
||||
<link rel=”preload” href=”your/font” />
|
||||
<!-- Or you can load custom head-tag JavaScript: -->
|
||||
<script src="https://use.typekit.net/xxxyyy.js"></script>
|
||||
<script>try{ Typekit.load(); } catch(e){ }</script>
|
||||
```
|
||||
|
||||
<div class="aside">
|
||||
|
||||
Storybook will inject these tags into the _preview iframe_ where your components are rendered not the Storybook application UI.
|
||||
|
||||
</div>
|
||||
|
||||
### Adding to <body>
|
||||
|
||||
Sometimes, you may need to add different tags to the `<body>`. This is useful for adding some custom content roots.
|
||||
|
||||
You can accomplish this by creating a file called `preview-body.html` inside your `.storybook` directory and add tags like this:
|
||||
|
||||
```html
|
||||
<!-- .storybook/preview-body.html -->
|
||||
<div id="custom-root"></div>
|
||||
```
|
||||
|
||||
If using relative sizing in your project (like `rem` or `em`), you may update the base `font-size` by adding a `style` tag to `preview-body.html`:
|
||||
|
||||
```html
|
||||
<style>
|
||||
body {
|
||||
font-size: 15px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
<div class="aside">
|
||||
|
||||
Storybook will inject these tags into the _preview iframe_ where your components are rendered not the Storybook application UI.
|
||||
|
||||
</div>
|
||||
|
396
docs/configure/user-interface.md
Normal file
396
docs/configure/user-interface.md
Normal file
@ -0,0 +1,396 @@
|
||||
---
|
||||
title: 'User interface'
|
||||
---
|
||||
|
||||
### Features and behavior
|
||||
|
||||
To control the layout of Storybook’s UI you can use the `setConfig` addons API in your [`.storybook/manager.js`](overview#configure-story-rendering):
|
||||
|
||||
```js
|
||||
import { addons } from '@storybook/addons';
|
||||
|
||||
addons.setConfig({
|
||||
isFullscreen: false,
|
||||
showNav: true,
|
||||
showPanel: true,
|
||||
panelPosition: 'bottom',
|
||||
sidebarAnimations: true,
|
||||
enableShortcuts: true,
|
||||
isToolshown: true,
|
||||
theme: undefined,
|
||||
selectedPanel: undefined,
|
||||
initialActive: 'sidebar',
|
||||
showRoots: false,
|
||||
});
|
||||
```
|
||||
The following table details how to use the API values:
|
||||
|
||||
| Name | Type | Description | Example Value |
|
||||
| ----------------------|:-------------:|:-------------------------------------------------------------:|:----------------------------------------------:|
|
||||
| **isFullscreen** | Boolean |Show story component as full screen |`false` |
|
||||
| **showNav** | Boolean |Display panel that shows a list of stories |`true` |
|
||||
| **showPanel** | Boolean |Display panel that shows addon configurations |`true` |
|
||||
| **panelPosition** | String/Object |Where to show the addon panel |`bottom` or `{('bottom'|'right')}` |
|
||||
| **sidebarAnimations** | Boolean |Sidebar tree animations |`true` |
|
||||
| **enableShortcuts** | Boolean |Enable/disable shortcuts |`true` |
|
||||
| **isToolshown** | String |Show/hide tool bar |`true` |
|
||||
| **theme** | Object |Storybook Theme, see next section |`undefined` |
|
||||
| **selectedPanel** | String |Id to select an addon panel |`my-panel` |
|
||||
| **initialActive** | String |Select the default active tab on Mobile. |`'sidebar'` or `{('sidebar'|'canvas'|'addons')}`|
|
||||
| **showRoots** | Boolean |Display the top-level grouping as a "root" in the sidebar |`false` |
|
||||
|
||||
### Theming
|
||||
|
||||
Storybook is theme-able using a lightweight theming API.
|
||||
|
||||
#### Global theming
|
||||
|
||||
It's possible to theme Storybook globally.
|
||||
|
||||
Storybook includes two themes that look good out of the box: "normal" (a light theme) and "dark" (a dark theme). Unless you've set your preferred color scheme as dark, Storybook will use the light theme as default.
|
||||
|
||||
Make sure you have installed [`@storybook/addons`](https://www.npmjs.com/package/@storybook/addons) and [`@storybook/theming`](https://www.npmjs.com/package/@storybook/theming) packages.
|
||||
|
||||
```sh
|
||||
npm install @storybook/addons --save-dev
|
||||
npm install @storybook/theming --save-dev
|
||||
```
|
||||
|
||||
As an example, you can tell Storybook to use the "dark" theme by modifying [`.storybook/manager.js`](./overview#configure-story-rendering):
|
||||
|
||||
```js
|
||||
// .storybook/manager.js
|
||||
import { addons } from '@storybook/addons';
|
||||
import { themes } from '@storybook/theming';
|
||||
|
||||
addons.setConfig({
|
||||
theme: themes.dark,
|
||||
});
|
||||
```
|
||||
|
||||
When setting a theme, set a full theme object. The theme is replaced, not combined.
|
||||
|
||||
### Theming docs
|
||||
|
||||
[Storybook Docs](../writing-docs) uses the same theme system as Storybook’s UI, but is themed independently from the main UI.
|
||||
|
||||
Supposing you have a Storybook theme defined for the main UI in [`.storybook/manager.js`](./overview#configure-story-rendering):
|
||||
|
||||
```js
|
||||
// .storybook/manager.js
|
||||
import { addons } from '@storybook/addons';
|
||||
// or a custom theme
|
||||
import { themes } from '@storybook/theming';
|
||||
|
||||
addons.setConfig({
|
||||
theme: themes.dark,
|
||||
});
|
||||
```
|
||||
|
||||
Here's how you'd specify the same theme for docs in [`.storybook/preview.js`](./overview#configure-story-rendering):
|
||||
|
||||
```js
|
||||
// .storybook/preview.js
|
||||
import { themes } from '@storybook/theming';
|
||||
|
||||
// or global addParameters
|
||||
export const parameters = {
|
||||
docs: {
|
||||
theme: themes.dark,
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Continue to read if you want to learn how to create your theme.
|
||||
|
||||
### Create a theme quickstart
|
||||
|
||||
The easiest way to customize Storybook is to generate a new theme using the `create()` function from `storybook/theming`. This function includes shorthands for the most common theme variables. Here's how to use it:
|
||||
|
||||
First create a new file in `.storybook` called `yourTheme.js`.
|
||||
|
||||
Next paste the code below and tweak the variables.
|
||||
|
||||
```js
|
||||
// yourTheme.js
|
||||
import { create } from '@storybook/theming/create';
|
||||
|
||||
export default create({
|
||||
base: 'light',
|
||||
|
||||
colorPrimary: 'hotpink',
|
||||
colorSecondary: 'deepskyblue',
|
||||
|
||||
// UI
|
||||
appBg: 'white',
|
||||
appContentBg: 'silver',
|
||||
appBorderColor: 'grey',
|
||||
appBorderRadius: 4,
|
||||
|
||||
// Typography
|
||||
fontBase: '"Open Sans", sans-serif',
|
||||
fontCode: 'monospace',
|
||||
|
||||
// Text colors
|
||||
textColor: 'black',
|
||||
textInverseColor: 'rgba(255,255,255,0.9)',
|
||||
|
||||
// Toolbar default and active colors
|
||||
barTextColor: 'silver',
|
||||
barSelectedColor: 'black',
|
||||
barBg: 'hotpink',
|
||||
|
||||
// Form colors
|
||||
inputBg: 'white',
|
||||
inputBorder: 'silver',
|
||||
inputTextColor: 'black',
|
||||
inputBorderRadius: 4,
|
||||
|
||||
brandTitle: 'My custom storybook',
|
||||
brandUrl: 'https://example.com',
|
||||
brandImage: 'https://placehold.it/350x150',
|
||||
});
|
||||
```
|
||||
|
||||
Finally, import your theme into [`.storybook/manager.js`](./overview#configure-story-rendering) and add it to your Storybook parameters.
|
||||
|
||||
```js
|
||||
// .storybook/manager.js
|
||||
import { addons } from '@storybook/addons';
|
||||
import yourTheme from './yourTheme';
|
||||
|
||||
addons.setConfig({
|
||||
theme: yourTheme,
|
||||
});
|
||||
```
|
||||
|
||||
The `@storybook/theming` package is built using TypeScript, so this should help create a valid theme for TypeScript users. The types are part of the package itself.
|
||||
|
||||
Many theme variables are optional, the `base` property is NOT. This is a perfectly valid theme:
|
||||
|
||||
```ts
|
||||
import { create } from '@storybook/theming/create';
|
||||
|
||||
export default create({
|
||||
base: 'light',
|
||||
brandTitle: 'My custom storybook',
|
||||
brandUrl: 'https://example.com',
|
||||
brandImage: 'https://placehold.it/350x150',
|
||||
});
|
||||
```
|
||||
|
||||
### CSS escape hatches
|
||||
|
||||
The Storybook theme API is narrow by design. If you want to have fine-grained control over the CSS, all of the UI and Docs components are tagged with class names to make this possible. This is advanced usage: **use at your own risk**.
|
||||
|
||||
To style these elements, insert style tags into:
|
||||
|
||||
- For Storybook’s UI, use `.storybook/manager-head.html`
|
||||
- For Storybook Docs, use `.storybook/preview-head.html`
|
||||
|
||||
<div class="aside">
|
||||
|
||||
Similar to changing the preview’s head tag, `.storybook/manager-head.html` allows you to inject code into the manager side, which can be useful to adding styles for your theme that target Storybook’s HTML.
|
||||
|
||||
WARNING: we don’t make any guarantees about the structure of Storybook’s HTML and it could change at any time. Consider yourself warned!
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### MDX component overrides
|
||||
|
||||
If you're using MDX for docs, there's one more level of themability. MDX allows you to completely override the components that are rendered from Markdown using a components parameter. This is an advanced usage that we don't officially support in Storybook, but it's a powerful mechanism if you need it.
|
||||
|
||||
Here's how you might insert a custom code renderer for `code` blocks on the page, in [`.storybook/preview.js`](./overview#configure-story-rendering):
|
||||
|
||||
```js
|
||||
// .storybook/preview.js
|
||||
import { CodeBlock } from './CodeBlock';
|
||||
|
||||
export const parameters = {
|
||||
docs: {
|
||||
components: {
|
||||
code: CodeBlock,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
You can even override a Storybook block component.
|
||||
|
||||
Here's how you might insert a custom `<Preview />` block:
|
||||
|
||||
```js
|
||||
// .storybook/preview.js
|
||||
|
||||
import { MyPreview } from './MyPreview';
|
||||
|
||||
export const parameters = {
|
||||
docs: {
|
||||
components: {
|
||||
Preview: MyPreview,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Addons and theme creation
|
||||
|
||||
Some addons require specific theme variables that a Storybook user must add. If you share your theme with the community, make sure to support the official API and other popular addons so your users have a consistent experience.
|
||||
|
||||
For example, the popular Actions addon uses [react-inspector](https://github.com/xyc/react-inspector/blob/master/src/styles/themes/chromeLight.js) which has themes of its own. Supply additional theme variables to style it like so:
|
||||
|
||||
```js
|
||||
|
||||
addonActionsTheme: {
|
||||
...chromeLight,
|
||||
BASE_FONT_FAMILY: typography.fonts.mono,
|
||||
BASE_BACKGROUND_COLOR: 'transparent',
|
||||
}
|
||||
```
|
||||
|
||||
### Using the theme for addon authors
|
||||
|
||||
Reuse the theme variables above for a native Storybook developer experience. The theming engine relies on [emotion](https://emotion.sh/), a CSS-in-JS library.
|
||||
|
||||
```js
|
||||
import { styled } from '@storybook/theming';
|
||||
```
|
||||
|
||||
Use the theme variables in object notation:
|
||||
|
||||
```js
|
||||
const Component = styled.div(({ theme }) => ({
|
||||
background: theme.background.app,
|
||||
width: 0,
|
||||
}));
|
||||
```
|
||||
|
||||
Or with template literals:
|
||||
|
||||
```js
|
||||
const Component = styled.div`
|
||||
background: `${props => props.theme.background.app}`
|
||||
width: 0;
|
||||
`;
|
||||
```
|
||||
|
||||
### Storybook addons
|
||||
|
||||
A key strength of Storybook is its extensibility. Use addons to extend and customize Storybook to fit your team’s development workflow.
|
||||
|
||||
Addons are integral to the way Storybook works. Many of Storybook's core features are implemented as addons! These addons are installed out of the box with [essentials](../essentials).
|
||||
|
||||
#### Addon features
|
||||
|
||||
The most obvious thing addons affect in Storybook is the UI of Storybook itself. Within the UI the **toolbar** and **addons panel** are the two chief places addons will appear.
|
||||
|
||||

|
||||
|
||||
Addons can also hook into the rendering of your story in the preview pane via injecting their own [decorators](../writing-stories/decorators).
|
||||
|
||||
Finally, addons can affect the build setup of Storybook by injecting their own webpack configuration to allow the use of other tools in Storybook. Addons that do only this are often referred to as [presets](../presets/introduction).
|
||||
|
||||
### Essential, core and community addons
|
||||
|
||||
There are many, many Storybook addons, but they can be roughly categorized into three areas:
|
||||
|
||||
- **Essential** addons are core-team developed addons that are considered a part of the out-of-the-box user experience. These ship by default with new Storybook installations.
|
||||
- **Core** addons are developed by the core team. They are kept in sync with the development of Storybook itself and written in idiomatic ways as templates for other addons. They can be found within the [Storybook monorepo](https://github.com/storybookjs/storybook/tree/next/addons).
|
||||
|
||||
- Community addons are addons written by the massive Storybook community. They can be found on our [website](/addons), [GitHub](https://github.com/), and [npm](https://www.npmjs.com/).
|
||||
|
||||
### Sidebar & URLs
|
||||
|
||||
Storybook’s sidebar lists all your stories grouped by component. When you have a lot of components you may wish to also group those components also. To do so, you can add the `/` separator to the `title` of your CSF file and Storybook will group the stories into groups based on common prefixes:
|
||||
|
||||

|
||||
|
||||
We recommend using a nesting scheme that mirrors the filesystem path of the components. For example, if you have a file `components/modals/Alert.js` name the CSF file `components/modals/Alert.stories.js` and title it `Components/Modals/Alert`.
|
||||
|
||||
#### Roots
|
||||
|
||||
By default, Storybook will treat your highest level of groups as “roots”--which are displayed in the UI as “sections” of the hierarchy. Lower level groups are displayed as expandable items in the hierarchy:
|
||||
|
||||

|
||||
|
||||
If you’d prefer all groups to be expandable, you can set the `showRoots` option to `false` in [`./storybook/manager.js`](./overview#configure-story-rendering):
|
||||
|
||||
```js
|
||||
// ./storybook/manager.js
|
||||
|
||||
import { addons } from `@storybook/addons`;
|
||||
addons.setConfig({ showRoots: false });
|
||||
```
|
||||
|
||||
#### Generating titles based on `__dirname`
|
||||
|
||||
As a CSF file is a JavaScript file, the exports (including the default export) can be generated dynamically. In particular you can use the `__dirname` variable to generate the title based on the path name (this example uses the paths.macro):
|
||||
|
||||
```js
|
||||
import base from 'paths.macro';
|
||||
export default {
|
||||
title: `${base}/Component`
|
||||
}
|
||||
```
|
||||
|
||||
#### Permalinking to stories
|
||||
|
||||
By default, Storybook generates an `id` for each story based on the component title and the story name. This `id` in particular is used in the URL for each story and that URL can serve as a permalink (especially when you [publish](../workflows/publish-storybook) your Storybook).
|
||||
|
||||
Consider the following story:
|
||||
|
||||
```js
|
||||
// your-story.story.js
|
||||
export default {
|
||||
title: 'Foo/Bar',
|
||||
};
|
||||
|
||||
export const Baz = BarStory.bind({});
|
||||
```
|
||||
|
||||
Storybook's ID-generation logic will give this the `id` `foo-bar--baz`, so the link would be `?path=/story/foo-bar--baz`.
|
||||
|
||||
It is possible to manually set the id of a story, which in particular is useful if you want to rename stories without breaking permalinks. Suppose you want to change the position in the hierarchy to `OtherFoo/Bar` and the story name to `Moo`. Here's how to do that:
|
||||
|
||||
```js
|
||||
// your-story.story.js
|
||||
|
||||
export default {
|
||||
title: 'OtherFoo/Bar',
|
||||
id: 'Foo/Bar', // or 'foo-bar' if you prefer
|
||||
};
|
||||
|
||||
export const Baz = () => BarStory.bind({});
|
||||
Baz.storyName = 'Moo';
|
||||
```
|
||||
|
||||
Storybook will prioritize the `id` over the title for ID generation, if provided, and will prioritize the `story.name` over the export key for display.
|
||||
|
||||
|
||||
### Environment variables
|
||||
|
||||
You can use environment variables in Storybook to change its behaviour in different “modes”.
|
||||
If you supply an environment variable prefixed with `STORYBOOK_`, it will be available in `process.env`:
|
||||
|
||||
```sh
|
||||
STORYBOOK_THEME=red STORYBOOK_DATA_KEY=12345 npm run storybook
|
||||
```
|
||||
|
||||
Then we can access these environment variables anywhere inside our preview JavaScript code like below:
|
||||
|
||||
```js
|
||||
console.log(process.env.STORYBOOK_THEME);
|
||||
console.log(process.env.STORYBOOK_DATA_KEY);
|
||||
```
|
||||
|
||||
You can also access these variables in your custom `<head>`/`<body>` (see below) using the substitution `%STORYBOOK_X%`, for example: `%STORYBOOK_THEME%` will become `red`.
|
||||
|
||||
<div class="aside">
|
||||
|
||||
If using the environment variables as attributes or values in JavaScript, you may need to add quotes, as the value will be inserted directly. e.g. `<link rel="stylesheet" href="%STORYBOOK_STYLE_URL%" />`
|
||||
|
||||
</div>
|
||||
|
||||
You can also pass these environment variables when you are [building your Storybook](/basics/exporting-storybook) with `build-storybook`.
|
||||
Then they'll be hard coded to the static version of your Storybook.
|
@ -22,6 +22,10 @@ module.exports = {
|
||||
pages: ['introduction', 'docs-page', 'mdx', 'doc-blocks'],
|
||||
},
|
||||
{
|
||||
title: 'Configure',
|
||||
prefix: 'configure',
|
||||
pages: ['overview', 'integration', 'story-rendering', 'user-interface'],
|
||||
|
||||
|
||||
title: 'Essentials',
|
||||
prefix:'essentials',
|
||||
|
Loading…
x
Reference in New Issue
Block a user