Merge pull request #11842 from storybookjs/chore_add_configure_snippets

Chore add snippets for configure section for 6.0
This commit is contained in:
Tom Coleman 2020-08-10 10:06:52 +10:00 committed by GitHub
commit e975e25569
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 693 additions and 339 deletions

View File

@ -5,16 +5,27 @@ title: '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
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-set-environment-variables.sh.mdx',
]}
/>
<!-- prettier-ignore-end -->
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);
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-read-environment-variables.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
You can also access these variables in your custom `<head>`/`<body>` using the substitution `%STORYBOOK_X%`, for example: `%STORYBOOK_THEME%` will become `red`.

View File

@ -4,23 +4,16 @@ title: 'Features and behavior'
To control the layout of Storybooks UI you can use the `setConfig` addons API in your [`.storybook/manager.js`](./overview.md#configure-story-rendering):
```js
import { addons } from '@storybook/addons';
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-config-layout.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
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 |

View File

@ -18,25 +18,42 @@ By default, Storybook's webpack configuration will allow you to:
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';
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/my-component-story-import-static-asset.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
- 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';
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/my-component-story-import-json.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
If you want to know the exact details of the webpack config, the best way is to run:
```sh
yarn storybook --debug-webpack
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-run-webpack-config.sh.mdx',
]}
/>
<!-- prettier-ignore-end -->
### Extending Storybooks webpack config
@ -46,30 +63,15 @@ The value should export a `function`, which will receive the default config as i
For example, here's a `.storybook/main.js` to add [Sass](https://sass-lang.com/) support:
```js
// .storybook/main.js
<!-- prettier-ignore-start -->
const path = require('path');
<CodeSnippets
paths={[
'common/storybook-main-add-sass-config.js.mdx',
]}
/>
// 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;
},
};
```
<!-- prettier-ignore-end -->
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.
@ -80,14 +82,15 @@ Nevertheless, edit `config` with care. Make sure to preserve the following confi
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;
},
}
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-main-simplified-config.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
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.
@ -99,19 +102,15 @@ If you have an existing webpack config for your project and want to reuse this a
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');
<!-- prettier-ignore-start -->
// your app's webpack.config.js
const custom = require('../webpack.config.js');
<CodeSnippets
paths={[
'common/storybook-main-using-existing-config.js.mdx',
]}
/>
module.exports = {
webpackFinal: (config) => {
return { ...config, module: { ...config.module, rules: custom.module.rules } };
},
};
```
<!-- prettier-ignore-end -->
## Babel
@ -153,20 +152,15 @@ To make it easier to configure Typescript handling, use the `typescript` field i
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),
},
},
};
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-main-add-ts-config.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
| Field | Framework | Description | Type |
| :------------------------------- | :-------: | :--------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------: |
@ -189,11 +183,19 @@ If your component files import their own CSS, Storybooks webpack config will
- 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 Storybooks 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';
```
- Either [customize your webpack config](#extending-storybooks-webpack-config)
- Or use syntax to use a inline loader:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'angular/storybook-angular-inline-css-loader.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
To use your CSS in all stories, you simply import it in [`.storybook/preview.js`](./overview.md#configure-story-rendering)
@ -211,23 +213,15 @@ You can import any media assets by importing (or requiring) them. This works out
Afterwards you can use any asset in your stories:
```js
// your-story-with-assets.story.js
<!-- prettier-ignore-start -->
import React from 'react';
import imageFile from './static/image.png';
<CodeSnippets
paths={[
'react/component-story-static-asset-with-import.js.mdx',
]}
/>
export default {
title: 'img',
};
const image = {
src: imageFile,
alt: 'my image',
};
export const withAnImage = () => <img src={image.src} alt={image.alt} />;
```
<!-- prettier-ignore-end -->
### Serving static files via Storybook
@ -235,57 +229,54 @@ We recommend serving static files via Storybook to ensure that your components a
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"
}
}
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-serve-static-assets-script.json.mdx',
]}
/>
<!-- prettier-ignore-end -->
Here `./public` is your static directory. Now use it in a component or story like this.
```js
// your-story-with-asset.story.js
<!-- prettier-ignore-start -->
import React from 'react';
<CodeSnippets
paths={[
'react/component-story-static-asset-without-import.js.mdx',
]}
/>
export default {
title: 'img',
};
// assume image.png is located in the "public" directory.
export const withAnImage = () => <img src="/image.png" alt="my image" />;
```
<!-- prettier-ignore-end -->
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"
}
}
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-serve-static-assets-script-multifolder.json.mdx',
]}
/>
<!-- prettier-ignore-end -->
### Reference assets from a CDN
Upload your files to an online CDN and reference them. In this example were using a placeholder image service.
```js
// your-story-with-CDN-asset.story.js
<!-- prettier-ignore-start -->
import React from 'react';
<CodeSnippets
paths={[
'react/component-story-static-asset-cdn.js.mdx',
]}
/>
export default {
title: 'img',
};
<!-- prettier-ignore-end -->
// 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

View File

@ -14,14 +14,15 @@ Note you can change the folder that Storybook uses by setting the `-c` flag to y
The main configuration file is `main.js`. This file controls the behaviour of the Storybook server, and so you must restart Storybooks process when you change it. It contains the following:
```js
// .storybook/main.js
<!-- prettier-ignore-start -->
module.exports = {
stories: ['../src/**/*.stories.(js|mdx)'],
addons: ['@storybook/addon-essentials'],
};
```
<CodeSnippets
paths={[
'common/storybook-main-default-setup.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
The `main.js` configuration file is a [preset](../api/presets.md) and as such has a powerful interface, but the key fields within it are:
@ -45,13 +46,15 @@ If you want to use a different naming convention, you can alter the glob, using
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
<!-- prettier-ignore-start -->
module.exports = {
stories: ['../my-project/src/components/*.@(js|md)'],
};
```
<CodeSnippets
paths={[
'common/storybook-main-js-md-files.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
## Configure story rendering

View File

@ -16,23 +16,31 @@ By default, Storybook will treat your highest level of groups as “roots”--wh
If youd prefer all groups to be expandable, you can set the `showRoots` option to `false` in [`./storybook/manager.js`](./overview.md#configure-story-rendering):
```js
// ./storybook/manager.js
<!-- prettier-ignore-start -->
import { addons } from `@storybook/addons`;
addons.setConfig({ showRoots: false });
```
<CodeSnippets
paths={[
'common/storybook-manager-disable-roots.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
## 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`,
};
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/component-story-dynamic-title.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
## Permalinking to stories
@ -40,30 +48,28 @@ By default, Storybook generates an `id` for each story based on the component ti
Consider the following story:
```js
// your-story.story.js
<!-- prettier-ignore-start -->
export default {
title: 'Foo/Bar',
};
<CodeSnippets
paths={[
'common/foo-bar-baz-story.js.mdx',
]}
/>
export const Baz = BarStory.bind({});
```
<!-- prettier-ignore-end -->
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
<!-- prettier-ignore-start -->
export default {
title: 'OtherFoo/Bar',
id: 'Foo/Bar', // or 'foo-bar' if you prefer
};
<CodeSnippets
paths={[
'common/other-foo-bar-story.js.mdx',
]}
/>
export const Baz = () => BarStory.bind({});
Baz.storyName = 'Moo';
```
<!-- prettier-ignore-end -->
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.

View File

@ -8,19 +8,16 @@ In Storybook, your stories render in a special “preview” iframe (Canvas tab)
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.md#configure-story-rendering) and add tags like this:
```html
<!-- .storybook/preview-head.html -->
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-preview-head-example.html.mdx',
]}
/>
<!-- prettier-ignore-end -->
<!-- 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">
@ -34,20 +31,27 @@ Sometimes, you may need to add different tags to the `<body>`. This is useful fo
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>
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-preview-body-example.html.mdx',
]}
/>
<!-- prettier-ignore-end -->
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>
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-preview-body-font-size.html.mdx',
]}
/>
<!-- prettier-ignore-end -->
<div class="aside">

View File

@ -12,22 +12,27 @@ Storybook includes two themes that look good out of the box: "normal" (a light t
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
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-install-theme-packages.sh.mdx',
]}
/>
<!-- prettier-ignore-end -->
As an example, you can tell Storybook to use the "dark" theme by modifying [`.storybook/manager.js`](./overview.md#configure-story-rendering):
```js
// .storybook/manager.js
import { addons } from '@storybook/addons';
import { themes } from '@storybook/theming';
<!-- prettier-ignore-start -->
addons.setConfig({
theme: themes.dark,
});
```
<CodeSnippets
paths={[
'common/storybook-manager-dark-theme.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
When setting a theme, set a full theme object. The theme is replaced, not combined.
@ -37,30 +42,27 @@ When setting a theme, set a full theme object. The theme is replaced, not combin
Supposing you have a Storybook theme defined for the main UI in [`.storybook/manager.js`](./overview.md#configure-story-rendering):
```js
// .storybook/manager.js
import { addons } from '@storybook/addons';
// or a custom theme
import { themes } from '@storybook/theming';
<!-- prettier-ignore-start -->
addons.setConfig({
theme: themes.dark,
});
```
<CodeSnippets
paths={[
'common/storybook-manager-dark-theme.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
Here's how you'd specify the same theme for docs in [`.storybook/preview.js`](./overview.md#configure-story-rendering):
```js
// .storybook/preview.js
import { themes } from '@storybook/theming';
<!-- prettier-ignore-start -->
// or global addParameters
export const parameters = {
docs: {
theme: themes.dark,
},
};
```
<CodeSnippets
paths={[
'common/storybook-preview-docs-dark-theme.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
Continue to read if you want to learn how to create your theme.
@ -72,75 +74,41 @@ First create a new file in `.storybook` called `yourTheme.js`.
Next paste the code below and tweak the variables.
```js
// yourTheme.js
<!-- prettier-ignore-start -->
import { create } from '@storybook/theming/create';
<CodeSnippets
paths={[
'common/your-theme.js.mdx',
]}
/>
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',
});
```
<!-- prettier-ignore-end -->
Finally, import your theme into [`.storybook/manager.js`](./overview.md#configure-story-rendering) and add it to your Storybook parameters.
```js
// .storybook/manager.js
<!-- prettier-ignore-start -->
import { addons } from '@storybook/addons';
import yourTheme from './yourTheme';
<CodeSnippets
paths={[
'common/storybook-manager-custom-theme.js.mdx',
]}
/>
addons.setConfig({
theme: yourTheme,
});
```
<!-- prettier-ignore-end -->
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';
<!-- prettier-ignore-start -->
export default create({
base: 'light',
brandTitle: 'My custom storybook',
brandUrl: 'https://example.com',
brandImage: 'https://placehold.it/350x150',
});
```
<CodeSnippets
paths={[
'common/storybook-theme-example-variables.ts.mdx',
]}
/>
<!-- prettier-ignore-end -->
## CSS escape hatches
@ -165,37 +133,29 @@ If you're using MDX for docs, there's one more level of themability. MDX allows
Here's how you might insert a custom code renderer for `code` blocks on the page, in [`.storybook/preview.js`](./overview.md#configure-story-rendering):
```js
// .storybook/preview.js
<!-- prettier-ignore-start -->
import { CodeBlock } from './CodeBlock';
<CodeSnippets
paths={[
'common/storybook-preview-custom-code-renderer.js.mdx',
]}
/>
export const parameters = {
docs: {
components: {
code: CodeBlock,
},
},
};
```
<!-- prettier-ignore-end -->
You can even override a Storybook block component.
Here's how you might insert a custom `<Preview />` block:
Here's how you might insert a custom `<Canvas />` block:
```js
// .storybook/preview.js
<!-- prettier-ignore-start -->
import { MyPreview } from './MyPreview';
<CodeSnippets
paths={[
'common/storybook-preview-custom-canvas.js.mdx',
]}
/>
export const parameters = {
docs: {
components: {
Preview: MyPreview,
},
},
};
```
<!-- prettier-ignore-end -->
## Addons and theme creation
@ -203,37 +163,50 @@ Some addons require specific theme variables that a Storybook user must add. If
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
<!-- prettier-ignore-start -->
addonActionsTheme: {
...chromeLight,
BASE_FONT_FAMILY: typography.fonts.mono,
BASE_BACKGROUND_COLOR: 'transparent',
}
```
<CodeSnippets
paths={[
'common/storybook-preview-extended-theme-variables.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
## 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';
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/storybook-theming-styled-import.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
Use the theme variables in object notation:
```js
const Component = styled.div(({ theme }) => ({
background: theme.background.app,
width: 0,
}));
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'react/component-styled-variables-object-notation.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
Or with template literals:
```js
const Component = styled.div`
background: `${props => props.theme.background.app}`
width: 0;
`;
```
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'react/component-styled-variables-template-literals.js.mdx',
]}
/>
<!-- prettier-ignore-end -->

View File

@ -0,0 +1,3 @@
```js
import '!style-loader!css-loader!./styles.css';
```

View File

@ -0,0 +1,8 @@
```js
// MyComponent.stories.js
import base from 'paths.macro';
export default {
title: `${base}/Component`
}
```

View File

@ -0,0 +1,9 @@
```js
// Foo-Bar.stories.js
export default {
title: 'Foo/Bar',
};
export const Baz = BarStory.bind({});
```

View File

@ -0,0 +1,4 @@
```js
// This will automatically be parsed to the contents of `data.json`
import data from './data.json';
```

View File

@ -0,0 +1,5 @@
```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';
```

View File

@ -0,0 +1,11 @@
```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';
```

View File

@ -0,0 +1,19 @@
```js
// .storybook/manager.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,
});
```

View File

@ -0,0 +1,3 @@
```sh
npm install @storybook/addons @storybook/theming --save-dev
```

View File

@ -0,0 +1,24 @@
```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;
},
};
```

View File

@ -0,0 +1,15 @@
```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),
},
},
};
```

View File

@ -0,0 +1,8 @@
```js
// .storybook/main.js
module.exports = {
stories: ['../src/**/*.stories.(js|mdx)'],
addons: ['@storybook/addon-essentials']
}
```

View File

@ -0,0 +1,8 @@
```js
// .storybook/main.js
module.exports = {
stories: ['../my-project/src/components/*.@(js|md)'],
};
```

View File

@ -0,0 +1,10 @@
```js
./storybook/main.js
module.exports = {
webpackFinal: (config) => {
config.plugins.push(...);
return config;
},
}
```

View File

@ -0,0 +1,14 @@
```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 } };
},
};
```

View File

@ -0,0 +1,10 @@
```js
// .storybook/manager.js
import { addons } from '@storybook/addons';
import yourTheme from './yourTheme';
addons.setConfig({
theme: yourTheme,
});
```

View File

@ -0,0 +1,10 @@
```js
// .storybook/manager.js
import { addons } from '@storybook/addons';
import { themes } from '@storybook/theming';
addons.setConfig({
theme: themes.dark,
});
```

View File

@ -0,0 +1,6 @@
```js
// ./storybook/manager.js
import { addons } from `@storybook/addons`;
addons.setConfig({ showRoots: false });
```

View File

@ -0,0 +1,4 @@
```html
<!-- .storybook/preview-body.html -->
<div id="custom-root"></div>
```

View File

@ -0,0 +1,8 @@
```html
<!-- .storybook/preview-body.html -->
<style>
body {
font-size: 15px;
}
</style>
```

View File

@ -0,0 +1,13 @@
```js
// .storybook/preview.js
import { MyCanvas } from './MyCanvas';
export const parameters = {
docs: {
components: {
Canvas: MyCanvas,
},
},
};
```

View File

@ -0,0 +1,13 @@
```js
// .storybook/preview.js
import { CodeBlock } from './CodeBlock';
export const parameters = {
docs: {
components: {
code: CodeBlock,
},
},
};
```

View File

@ -0,0 +1,11 @@
```js
// .storybook/preview.js
import { themes } from '@storybook/theming';
// or global addParameters
export const parameters = {
docs: {
theme: themes.dark,
},
};
```

View File

@ -0,0 +1,7 @@
```js
addonActionsTheme: {
...chromeLight,
BASE_FONT_FAMILY: typography.fonts.mono,
BASE_BACKGROUND_COLOR: 'transparent',
}
```

View File

@ -0,0 +1,10 @@
```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>
```

View File

@ -0,0 +1,4 @@
```js
console.log(process.env.STORYBOOK_THEME);
console.log(process.env.STORYBOOK_DATA_KEY);
```

View File

@ -0,0 +1,3 @@
```sh
yarn storybook --debug-webpack
```

View File

@ -0,0 +1,7 @@
```json
{
"scripts": {
"start-storybook": "start-storybook -s ./public,./static -p 9001"
}
}
```

View File

@ -0,0 +1,7 @@
```json
{
"scripts": {
"start-storybook": "start-storybook -s ./public -p 9001"
}
}
```

View File

@ -0,0 +1,3 @@
```sh
STORYBOOK_THEME=red STORYBOOK_DATA_KEY=12345 npm run storybook
```

View File

@ -0,0 +1,11 @@
```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',
});
```

View File

@ -0,0 +1,3 @@
```js
import { styled } from '@storybook/theming';
```

View File

@ -0,0 +1,41 @@
```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',
});
```

View File

@ -0,0 +1,14 @@
```js
// MyComponent.stories.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" />
);
```

View File

@ -0,0 +1,19 @@
```js
// MyComponent.stories.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} />
);
```

View File

@ -0,0 +1,14 @@
```js
// MyComponent.stories.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" />
);
```

View File

@ -0,0 +1,8 @@
```js
// MyComponent.js
const Component = styled.div(({ theme }) => ({
background: theme.background.app,
width: 0,
}));
```

View File

@ -0,0 +1,6 @@
```js
const Component = styled.div`
background: `${props => props.theme.background.app}`
width: 0;
`;
```