## File: README.md

## Table of contents

- 🚀 [Getting Started](#getting-started)
- 📒 [Projects](#projects)
  - 🛠 [Supported Frameworks & Examples](#supported-frameworks)
  - 🔗[Addons](#addons)
- 🏅 [Badges & Presentation materials](#badges--presentation-materials)
- 👥 [Community](#community)
- 👏 [Contributing](#contributing)
  - 👨‍💻 [Development scripts](#development-scripts)
  - 💸 [Sponsors](#sponsors)
  - 💵 [Backers](#backers)
- :memo: [License](#license)

## Getting Started

Visit [Storybook's website](https://storybook.js.org/?ref=readme) to learn more about Storybook and to get started.

### Documentation

Documentation can be found on [Storybook's docs site](https://storybook.js.org/docs?ref=readme).

### Examples

View [Component Encyclopedia](https://storybook.js.org/showcase?ref=readme) to see how leading teams use Storybook.

Use [storybook.new](https://storybook.new) to quickly create an example project in Stackblitz.

Storybook comes with a lot of [addons](https://storybook.js.org/docs/configure/user-interface/storybook-addons?ref=readme) for component design, documentation, testing, interactivity, and so on. Storybook's API makes it possible to configure and extend in various ways. It has even been extended to support React Native, Android, iOS, and Flutter development for mobile.

### Community

For additional help, share your issue in [the repo's GitHub Discussions](https://github.com/storybookjs/storybook/discussions/new?category=help).

## Projects

### Supported Frameworks

| Renderer                                                       | Demo                                                                                                                                                                         |                                                                                                                                                       |
| -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| [React](code/renderers/react)                                  | [](https://next--630511d655df72125520f051.chromatic.com/)          | [](code/renderers/react)                                          |
| [Angular](code/frameworks/angular/)                            | [](https://next--6322ce6af69825592bbb28fc.chromatic.com/)        | [](code/frameworks/angular/)                                  |
| [Vue 3](code/renderers/vue3)                                   | [](https://next--630513346a8e284ae244d415.chromatic.com/)           | [](code/renderers/vue3/)                                           |
| [Web components](code/renderers/web-components)                | [](https://next--638db5bf49adfdfe8cf545e0.chromatic.com/) | [](code/renderers/web-components)                       |
| [React Native](https://github.com/storybookjs/react-native)    | [](/)                                                                     | [](https://github.com/storybookjs/react-native)     |
| [HTML](code/renderers/html)                                    | [](https://next--63dd39a158cf6fc05199b4bb.chromatic.com/)           | [](code/renderers/html)                                             |
| [Ember](code/frameworks/ember/)                                | [](/)                                                                            | [](code/frameworks/ember/)                                        |
| [Svelte](code/renderers/svelte)                                | [](https://next--630873996e4e3557791c069c.chromatic.com/)         | [](code/renderers/svelte)                                       |
| [Preact](code/renderers/preact)                                | [](https://next--63b588a512565bfaace15e7c.chromatic.com/)         | [](code/renderers/preact)                                       |
| [Qwik](https://github.com/literalpie/storybook-framework-qwik) | [](/)                                                                    | [](https://github.com/literalpie/storybook-framework-qwik) |
| [SolidJS](https://github.com/solidjs-community/storybook)      | [](/)                                                                      | [](https://github.com/solidjs-community/storybook)        |
| [Android, iOS, Flutter](https://github.com/storybookjs/native) | [](/)                                                                           | [](https://github.com/storybookjs/native)                       |

### Addons

| Addons                                                                    |                                                                            |
| ------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| [a11y](code/addons/a11y/)                                                 | Test components for user accessibility in Storybook                        |
| [actions](code/core/src/actions/)                                         | Log actions as users interact with components in the Storybook UI          |
| [backgrounds](code/core/src/backgrounds)                                  | Let users choose backgrounds in the Storybook UI                           |
| [cssresources](https://github.com/storybookjs/addon-cssresources)         | Dynamically add/remove CSS resources to the component iframe               |
| [design assets](https://github.com/storybookjs/addon-design-assets)       | View images, videos, and weblinks alongside your story                     |
| [docs](code/addons/docs/)                                                 | Add high quality documentation to your components                          |
| [events](https://github.com/storybookjs/addon-events)                     | Interactively fire events to components that respond to EventEmitter       |
| [google-analytics](https://github.com/storybookjs/addon-google-analytics) | Reports google analytics on stories                                        |
| [graphql](https://github.com/storybookjs/addon-graphql)                   | Query a GraphQL server within Storybook stories                            |
| [jest](https://github.com/storybookjs/addon-jest)                         | View the results of components' unit tests in Storybook                    |
| [links](code/addons/links/)                                               | Create links between stories                                               |
| [measure](code/core/src/measure/)                                         | Visually inspect the layout and box model within the Storybook UI          |
| [outline](code/core/src/outline/)                                         | Visually debug the CSS layout and alignment within the Storybook UI        |
| [query params](https://github.com/storybookjs/addon-queryparams)          | Mock query params                                                          |
| [viewport](code/core/src/viewport/)                                       | Change display sizes and layouts for responsive components using Storybook |

See [Addon / Framework Support Table](https://storybook.js.org/docs/configure/integration/frameworks-feature-support?ref=readme)

To continue improving your experience, we have to eventually deprecate or remove certain addons in favor of new and better tools.

If you're using info/notes, we highly recommend you migrate to [docs](code/addons/docs/) instead, and [here is a guide](code/addons/docs/docs/recipes.md#migrating-from-notesinfo-addons) to help you.

If you're using contexts, we highly recommend you migrate to [toolbars](https://github.com/storybookjs/storybook/tree/next/code/addons/toolbars) and [here is a guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-addon-contexts) to help you.

If you're using addon-storyshots, we highly recommend you migrate to the Storybook [test-runner](https://github.com/storybookjs/test-runner) and [here is a guide](https://storybook.js.org/docs/writing-tests/storyshots-migration-guide?ref=readme) to help you.

## Badges & Presentation materials

We have a badge! Link it to your live Storybook example.



```md
[](link to site)
```

If you're looking for material to use in your Storybook presentation, such as logos, video material, and the colors we use, you can find it all on our [brand repo](https://github.com/storybookjs/brand).

## Community

- Tweeting via [@storybookjs](https://x.com/storybookjs)
- Blogging at [storybook.js.org](https://storybook.js.org/blog/?ref=readme) and [Medium](https://medium.com/storybookjs)
- Chatting on [Discord](https://discord.gg/storybook)
- Videos and streams at [YouTube](https://www.youtube.com/channel/UCr7Quur3eIyA_oe8FNYexfg)

## Contributing

Contributions to Storybook are always welcome!

- 📥 Pull requests and 🌟 Stars are always welcome.
- Read our [contributing guide](CONTRIBUTING.md) to get started,
  or find us on [Discord](https://discord.gg/storybook), we will take the time to guide you.

Looking for a first issue to tackle?

- We tag issues with [](https://github.com/storybookjs/storybook/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) when we think they are well suited for people who are new to the codebase or OSS in general.
- [Talk to us](https://discord.gg/storybook), we'll find something that suits your skills and learning interests.

### Development scripts

Storybook is organized as a monorepo. Useful scripts include:

#### `yarn start`

> Runs a sandbox template storybook with test stories

#### `yarn task`

> As above, but gives you options to customize the sandbox (e.g. selecting other frameworks)

#### `yarn lint`

> boolean check if code conforms to linting rules - uses remark & eslint

- `yarn lint:js` - will check js
- `yarn lint:md` - will check markdown + code samples
- `yarn lint:js --fix` - will automatically fix js

#### `yarn test`

> boolean check if unit tests all pass - uses jest

- `yarn run test --core --watch` - will run core tests in watch-mode

### Sponsors

Become a sponsor to have your logo and website URL on our README on Github. \[[Become a sponsor](https://opencollective.com/storybook#sponsor)]

[](https://opencollective.com/storybook/tiers/sponsors/0/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/1/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/2/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/3/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/4/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/5/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/6/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/7/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/8/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/9/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/10/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/11/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/12/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/13/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/14/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/15/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/16/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/17/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/18/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/19/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/20/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/21/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/22/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/23/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/24/website?requireActive=true)
[](https://opencollective.com/storybook/tiers/sponsors/25/website?requireActive=true)

### Backers

By making a recurring donation, you can support us and our work. \[[Become a backer](https://opencollective.com/storybook#backer)]

[](https://opencollective.com/storybook)

## License

[MIT](https://github.com/storybookjs/storybook/blob/main/LICENSE)

-the end-

---

## File: addons/viewport/README.md

# Storybook Viewport Addon

Storybook Viewport Addon allows your stories to be displayed in different sizes and layouts in [Storybook](https://storybook.js.org). This helps build responsive components inside of Storybook.

[Framework Support](https://storybook.js.org/docs/react/api/frameworks-feature-support)



## Installation

Viewport is part of [essentials](https://storybook.js.org/docs/react/essentials/introduction) and so is installed in all new Storybooks by default. If you need to add it to your Storybook, you can run:

```sh
npm i -D @storybook/addon-viewport
```

Then, add following content to [`.storybook/main.js`](https://storybook.js.org/docs/react/configure/overview#configure-your-storybook-project):

```js
module.exports = {
  addons: ['@storybook/addon-viewport'],
};
```

You should now be able to see the viewport addon icon in the the toolbar at the top of the screen.

## Usage

The usage is documented in the [documentation](https://storybook.js.org/docs/react/essentials/viewport).

---

## File: addons/toolbars/README.md

# Storybook Toolbars Addon

The Toolbars addon controls global story rendering options from [Storybook's](https://storybook.js.org) toolbar UI. It's a general purpose addon that can be used to:

- set a theme for your components
- set your components' internationalization (i18n) locale
- configure just about anything in Storybook that makes use of a global variable

[Framework Support](https://storybook.js.org/docs/react/api/frameworks-feature-support)



## Installation

Toolbars is part of [essentials](https://storybook.js.org/docs/react/essentials/introduction) and so is installed in all new Storybooks by default. If you need to add it to your Storybook, you can run:

```sh
npm i -D @storybook/addon-toolbars
```

Then, add following content to [`.storybook/main.js`](https://storybook.js.org/docs/react/configure/overview#configure-your-storybook-project):

```js
module.exports = {
  addons: ['@storybook/addon-toolbars'],
};
```

## Usage

The usage is documented in the [documentation](https://storybook.js.org/docs/react/essentials/toolbars-and-globals).

## FAQs

### How does this compare to `addon-contexts`?

`Addon-toolbars` is the successor to `addon-contexts`, which provided convenient global toolbars in Storybook's toolbar.

The primary difference between the two packages is that `addon-toolbars` makes use of Storybook's new **Story Args** feature, which has the following advantages:

- **Standardization**. Args are built into Storybook in 6.x. Since `addon-toolbars` is based on args, you don't need to learn any addon-specific APIs to use it.

- **Ergonomics**. Global args are easy to consume [in stories](https://storybook.js.org/docs/react/essentials/toolbars-and-globals#consuming-globals-from-within-a-story), in [Storybook Docs](https://github.com/storybookjs/storybook/tree/master/addons/docs), or even in other addons.

* **Framework compatibility**. Args are completely framework-independent, so `addon-toolbars` is compatible with React, Vue, Angular, etc. out of the box with no framework logic needed in the addon.

---

## File: addons/storysource/README.md

<h1>Storybook Storysource Addon</h1>

This addon is used to show stories source in the addon panel.

[Framework Support](https://github.com/storybookjs/storybook/blob/master/ADDONS_SUPPORT.md)



- [Getting Started](#getting-started)
  - [Install using preset](#install-using-preset)
- [Theming](#theming)
- [Displaying full source](#displaying-full-source)

## Getting Started

First, install the addon

```sh
yarn add @storybook/addon-storysource --dev
```

You can add configuration for this addon by using a preset or by using the addon config with webpack

### Install using preset

Add the following to your `.storybook/main.js` exports:

```js
module.exports = {
  addons: ['@storybook/addon-storysource'],
};
```

You can pass configurations into the addon-storysource loader in your `.storybook/main.js` file, e.g.:

```js
module.exports = {
  addons: [
    {
      name: '@storybook/addon-storysource',
      options: {
        rule: {
          // test: [/\.stories\.jsx?$/], This is default
          include: [path.resolve(__dirname, '../src')], // You can specify directories
        },
        loaderOptions: {
          prettierConfig: { printWidth: 80, singleQuote: false },
        },
      },
    },
  ],
};
```

To customize the `source-loader`, pass `loaderOptions`. Valid configurations are documented in the [`source-loader` README](../../lib/source-loader/README.md#options).

## Theming

Storysource will automatically use the light or dark syntax theme based on your storybook theme. See [Theming Storybook](https://storybook.js.org/docs/react/configure/theming) for more information.


## Displaying full source

Storybook 6.0 introduced an unintentional change to `source-loader`, in which only the source of the selected story is shown in the addon. To restore the old behavior, pass the`injectStoryParameters: false` option.

If you're using `addon-docs`:

```js
module.exports = {
  addons: [
    {
      name: '@storybook/addon-docs',
      options: {
        sourceLoaderOptions: {
          injectStoryParameters: false,
        },
      },
    },
  ],
};
```

If not:

```js
module.exports = {
  addons: [
    {
      name: '@storybook/addon-storysource',
      options: {
        loaderOptions: {
          injectStoryParameters: false,
        },
      },
    },
  ],
};
```

This bug will be resolved in a future version of the addon.

---

## File: addons/storyshots/storyshots-core/README.md

# StoryShots

StoryShots adds automatic Jest Snapshot Testing for [Storybook](https://storybook.js.org/).

[Framework Support](https://github.com/storybookjs/storybook/blob/master/ADDONS_SUPPORT.md)



To use StoryShots, you must use your existing Storybook stories as the input for Jest Snapshot Testing.

## Getting Started

Add the following module into your app.

```sh
yarn add @storybook/addon-storyshots --dev
```

## Configure Storyshots for HTML snapshots

Create a new test file with the name `Storyshots.test.js`. (Or whatever the name you prefer, as long as it matches Jest's config [`testMatch`](http://facebook.github.io/jest/docs/en/configuration.html#testmatch-array-string)).
Then add following content to it:

```js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots();
```

That's all.

Now run your Jest test command. (Usually, `npm test`.) Then you can see all of your stories are converted as Jest snapshot tests.



### Testing stories that rely on addon-added decorators

If you have stories in your Storybook that can only render inside a decorator (for instance the [`apollo-storybook-decorator`](https://github.com/abhiaiyer91/apollo-storybook-decorator)), you'll need to ensure those decorators are applied in Storyshots.

If you export those decorators from your `.storybook/preview.js` then Storyshots will apply those decorators for you in the same way that Storybook does. However if the addon _automatically_ adds the decorator for you (which is a new feature in Storybook 6.0), you will find the decorator does not get added in Storyshots. This is a limitation in Storyshots currently.

To ensure such decorators get added, export them from `.storybook/preview.js`:

```js
import addonDecorator from 'some-addon';

export const decorators = [addonDecorator];
```

## Configure your app for Jest

In many cases, for example Create React App, it's already configured for Jest. You need to create a filename with the extension `.test.js`.

If you still need to configure jest you can use the resources mentioned below:

- [Getting Started - Jest Official Documentation](https://facebook.github.io/jest/docs/en/getting-started.html)
- [Javascript Testing with Jest - Egghead](https://egghead.io/lessons/javascript-test-javascript-with-jest). **_paid content_**

> Note: If you use React 16, you'll need to follow [these additional instructions](https://github.com/facebook/react/issues/9102#issuecomment-283873039).
>
> Note: Make sure you have added the `json` extension to `moduleFileExtensions` in `jest.config.json`. If this is missing it leads to the [following error](https://github.com/storybookjs/storybook/issues/3728): `Cannot find module 'spdx-license-ids' from 'scan.js'`.
>
> Note: Please make sure you are using `jsdom` as the testEnvironment on your jest config file.

### Configure Jest to work with Webpack's [require.context()](https://webpack.js.org/guides/dependency-management/#require-context)

**NOTE**: if you are using Storybook 5.3's `main.js` to list story files, this is no longer needed.

Sometimes it's useful to configure Storybook with Webpack's require.context feature. You could be loading stories [one of two ways](https://storybook.js.org/docs/react/writing-stories/loading-stories).

1. If you're using the `storiesOf` API, you can integrate it this way:

```js
import { configure } from '@storybook/react';

const req = require.context('../stories', true, /\.stories\.js$/); // <- import all the stories at once

function loadStories() {
  req.keys().forEach((filename) => req(filename));
}

configure(loadStories, module);
```

2. If you're using Component Story Format (CSF), you'll integrate it like so:

```js
import { configure } from '@storybook/react';

const req = require.context('../stories', true, /\.stories\.js$/); // <- import all the stories at once

configure(req, module);
```

The problem here is that it will work only during the build with webpack,
other tools may lack this feature. Since Storyshot is running under Jest,
we need to polyfill this functionality to work with Jest. The easiest
way is to integrate it to babel.

You can do this with a Babel [plugin](https://github.com/smrq/babel-plugin-require-context-hook) or [macro](https://github.com/storybookjs/require-context.macro). If you're using `create-react-app` (v2 or above), use the macro.

#### Option 1: Plugin

First, install it:

```sh
yarn add babel-plugin-require-context-hook --dev
```

Next, it needs to be registered and loaded before each test. To register it, create a file with the following register function `.jest/register-context.js`:

```js
import registerRequireContextHook from 'babel-plugin-require-context-hook/register';
registerRequireContextHook();
```

That file needs to be added as a setup file for Jest. To do that, add (or create) a property in Jest's config called [`setupFiles`](https://jestjs.io/docs/en/configuration.html#setupfiles-array). Add the file name and path to this array.

```json
setupFiles: ['<rootDir>/.jest/register-context.js']
```

Finally, add the plugin to `.babelrc`:

```json
{
  "presets": ["..."],
  "plugins": ["..."],
  "env": {
    "test": {
      "plugins": ["require-context-hook"]
    }
  }
}
```

The plugin is only added to the test environment otherwise it could replace webpack's version of it.

#### Option 2: Macro

First, install it:

```sh
yarn add require-context.macro --dev
```

Now, inside of your Storybook config file, import the macro and run it in place of `require.context`, like so:

```javascript
import requireContext from 'require-context.macro';

// const req = require.context('../stories', true, /\.stories\.js$/); <-- replaced
const req = requireContext('../stories', true, /\.stories\.js$/);
```

### Configure Jest for React

StoryShots addon for React is dependent on [react-test-renderer](https://github.com/facebook/react/tree/master/packages/react-test-renderer), but
[doesn't](#deps-issue) install it, so you need to install it separately.

```sh
yarn add react-test-renderer --dev
```

### Configure Jest for Angular

StoryShots addon for Angular is dependent on [jest-preset-angular](https://github.com/thymikee/jest-preset-angular), but
[doesn't](#deps-issue) install it, so you need to install it separately.

```sh
yarn add jest-preset-angular
```

If you already use Jest for testing your angular app - probably you already have the needed jest configuration.
Anyway you can add these lines to your jest config:

```js
module.exports = {
  globals: {
    __TRANSFORM_HTML__: true,
  },
  transform: {
    '^.+\\.jsx?$': 'babel-jest',
    '^.+\\.(ts|html)$': '<rootDir>/node_modules/jest-preset-angular/preprocessor.js',
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node', '.html'],
};
```

### Configure Jest for Vue

StoryShots addon for Vue is dependent on [jest-vue-preprocessor](https://github.com/vire/jest-vue-preprocessor), but
[doesn't](#deps-issue) install it, so you need to install it separately.

```sh
yarn add jest-vue-preprocessor
```

If you already use Jest for testing your vue app - probably you already have the needed jest configuration.
Anyway you can add these lines to your jest config:

```js
module.exports = {
  transform: {
    '^.+\\.jsx?$': 'babel-jest',
    '.*\\.(vue)$': '<rootDir>/node_modules/jest-vue-preprocessor',
  },
  transformIgnorePatterns: ['/node_modules/(?!(@storybook/.*\\.vue$))'],
  moduleFileExtensions: ['vue', 'js', 'jsx', 'json', 'node'],
};
```

### Configure Jest for Vue 3

StoryShots addon for Vue is dependent on [vue-jest v5](https://www.npmjs.com/package/vue-jest/v/5.0.0-alpha.8), but
[doesn't](#deps-issue) install it, so you need to install it separately.

```sh
yarn add vue-jest@5.0.0-alpha.8
```

If you already use Jest for testing your vue app - probably you already have the needed jest configuration.
Anyway you can add these lines to your jest config:

```js
module.exports = {
  transform: {
    '^.+\\.jsx?$': 'babel-jest',
    '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest',
  },
  transformIgnorePatterns: ['/node_modules/(?!(@storybook/.*\\.vue$))'],
  moduleFileExtensions: ['vue', 'js', 'jsx', 'json', 'node'],
};
```

### Configure Jest for Preact

StoryShots addon for Preact is dependent on [preact-render-to-json](https://github.com/nathancahill/preact-render-to-json), but
[doesn't](#deps-issue) install it, so you need to install it separately.

```sh
yarn add preact-render-to-json --dev
```

### Configure Jest for Web Components

StoryShots addon for Web Components requires [jsdom](https://github.com/jsdom/jsdom) 16 or later to fully support the
web component shadow dom. To use jsdom 16 or later you can set the Jest `testEnvironment` configuration key to
`jest-environment-jsdom-sixteen`. This should work back to Jest 24 and is the default in Jest 26 and later.

### Configure Jest for MDX Docs Add-On Stories

If using the [Docs add-on](../../docs/README.md) with
[MDX stories](../../docs/docs/mdx.md) you will need
to configure Jest to transform MDX stories into something Storyshots can understand:

Add the following to your Jest configuration:

```json
{
  "transform": {
    "^.+\\.[tj]sx?$": "babel-jest",
    "^.+\\.mdx?$": "@storybook/addon-docs/jest-transform-mdx"
  }
}
```

### <a name="deps-issue"></a>Why don't we install dependencies of each framework ?

Storyshots addon is currently supporting React, Angular and Vue. Each framework needs its own packages to be integrated with Jest. We don't want people that use only React will need to bring other dependencies that do not make sense for them.

`dependencies` - will installed an exact version of the particular dep - Storyshots can work with different versions of the same framework (let's say React v16 and React v15), that have to be compatible with a version of its plugin (react-test-renderer).

`optionalDependencies` - behaves like a regular dependency, but do not fail the installation in case there is a problem to bring the dep.

`peerDependencies` - listing all the deps in peer will trigger warnings during the installation - we don't want users to install unneeded deps by hand.

`optionalPeerDependencies` - unfortunately there is nothing like this =(

For more information read npm [docs](https://docs.npmjs.com/files/package.json#dependencies)

### Using `createNodeMock` to mock refs

`react-test-renderer` doesn't provide refs for rendered components. By
default, it returns null when the refs are referenced. In order to mock
out elements that rely on refs, you will have to use the
`createNodeMock` option [added to React](https://reactjs.org/blog/2016/11/16/react-v15.4.0.html#mocking-refs-for-snapshot-testing) starting with version 15.4.0.

Here is an example of how to specify the `createNodeMock` option in Storyshots:

```js
import initStoryshots, { snapshotWithOptions } from '@storybook/addon-storyshots';
import TextareaThatUsesRefs from '../component/TextareaThatUsesRefs';

initStoryshots({
  test: snapshotWithOptions({
    createNodeMock: (element) => {
      if (element.type === TextareaThatUsesRefs) {
        return document.createElement('textarea');
      }
    },
  }),
});
```

Provide a function to have story-specific options:

```js
initStoryshots({
  test: snapshotWithOptions((story) => ({
    createNodeMock: (element) => {
      if (story.name == 'foobar') {
        return null;
      }
      return element;
    },
  })),
});
```

### Using a custom renderer

By design, [`react-test-renderer` doesn't use a browser environment or JSDOM](https://github.com/facebook/react/issues/20589). Because of this difference, some stories might render in your browser, but not in Storyshots. If you encounter this problem, you may want to switch for an higher level renderer such as `mount` from Enzyme or `render` from React Testing Library.

#### Example with React Testing Library

```js
import initStoryshots from "@storybook/addon-storyshots";
import { render } from "@testing-library/react";

const reactTestingLibrarySerializer = {
  print: (val, serialize, indent) => serialize(val.container.firstChild),
  test: val => val && val.hasOwnProperty("container")
};

initStoryshots({
  renderer: render,
  snapshotSerializers: [reactTestingLibrarySerializer]
});

```

#### Example with Enzyme

```js
import initStoryshots from '@storybook/addon-storyshots';
import { mount } from 'enzyme';

initStoryshots({
  renderer: mount,
});
```

If you are using enzyme, you need to make sure jest knows how to serialize rendered components.
For that, you can pass an enzyme-compatible snapshotSerializer (like [enzyme-to-json](https://github.com/adriantoine/enzyme-to-json), [jest-serializer-enzyme](https://github.com/rogeliog/jest-serializer-enzyme) etc.) with the `snapshotSerializer` option (see below).

### StoryShots for async rendered components

You can make use of [Jest done callback](https://jestjs.io/docs/en/asynchronous) to test components that render asynchronously. This callback is passed as param to test method passed to `initStoryshots(...)` when the `asyncJest` option is given as true.

#### Example

The following example shows how we can use the **done callback** to take StoryShots of a [Relay](http://facebook.github.io/relay/) component. Each kind of story is written into its own snapshot file with the use of `getSnapshotFileName`.

Add _stories of UserForm_ in the file: UserForm.story.jsx

```
/* Detailed source-code truncated for AI context efficiency. */
```

Then, init Storyshots for async component in the file: StoryShots.test.js

```jsx
import initStoryshots, { Stories2SnapsConverter } from '@storybook/addon-storyshots';
import { mount } from 'enzyme';
import toJson from 'enzyme-to-json';

// Runner
initStoryshots({
  asyncJest: true, // this is the option that activates the async behaviour
  test: ({
    story,
    context,
    done, // --> callback passed to test method when asyncJest option is true
  }) => {
    const converter = new Stories2SnapsConverter();
    const snapshotFilename = converter.getSnapshotFileName(context);
    const storyElement = story.render();

    // mount the story
    const tree = mount(storyElement);

    // wait until the mount is updated, in our app mostly by Relay
    // but maybe something else updating the state of the component
    // somewhere
    const waitTime = 1;
    setTimeout(() => {
      if (snapshotFilename) {
        expect(toJson(tree.update())).toMatchSpecificSnapshot(snapshotFilename);
      }

      done();
    }, waitTime);
  },
  // other options here
});
```

NOTICE that When using the `asyncJest: true` option, you also must specify a `test` method that calls the `done()` callback.

This is a really powerful technique to write stories of Relay components because it integrates data fetching with component rendering. So instead of passing data props manually, we can let Relay do the job for us as it does in our application.

Whenever you change your data requirements by adding (and rendering) or (accidentally) deleting fields in your graphql query fragments, you'll get a different snapshot and thus an error in the StoryShot test.

## Using a custom directory

Depending on your project's needs, you can configure the `@storybook/addon-storyshots` to use a custom directory for the snapshots. You can read more about it in the [official docs](https://storybook.js.org/docs/react/workflows/snapshot-testing).

## Options

### `config`

The `config` parameter must be a function that helps to configure storybook like the `preview.js` does.
If it's not specified, storyshots will try to use [configPath](#configPath) parameter.

```js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({
  config: ({ configure }) =>
    configure(() => {
      require('../stories/Button.story.js');
    }, module),
});
```

### `configPath`

By default, Storyshots assumes the config directory path for your project as below:

- Storybook for React: `.storybook`
- Storybook for React Native: `storybook`

If you are using a different config directory path, you could change it like this:

```js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({
  configPath: '.my-storybook-config-dir',
});
```

Or, as a more complex example, if we have a package in our `lerna` project called `app` with the path `./packages/app/src/__tests__/storyshots.js` and the storybook config directory `./packages/app/.storybook`:

```js
import path from 'path';
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({ configPath: path.resolve(__dirname, '../../.storybook') });
```

`configPath` can also specify path to the `preview.js` itself. In this case, config directory will be
a base directory of the `configPath`. It may be useful when the `preview.js` for test should differ from the
original one. It also may be useful for separating tests to different test configs:

```js
initStoryshots({
  configPath: '.my-storybook-config-dir/testConfig1.js',
});

initStoryshots({
  configPath: '.my-storybook-config-dir/testConfig2.js',
});
```

### `suite`

By default, Storyshots groups stories inside a Jest test suite called "Storyshots". You could change it like this:

```js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({
  suite: 'MyStoryshots',
});
```

### `storyKindRegex`

If you'd like to only run a subset of the stories for your snapshot tests based on the story's kind:

```js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({
  storyKindRegex: /^MyComponent$/,
});
```

This can be useful if you want to separate the snapshots in directories next to each component. See an example [here](https://github.com/storybookjs/storybook/issues/892).

If you want to run all stories except stories of a specific kind, you can write an inverse regex which is true for all kinds except those with a specific word such as `DontTest`

```js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({
  storyKindRegex: /^((?!.*?DontTest).)*$/,
});
```

This can be useful while testing react components which make use of the findDomNode API since they always fail with snapshot testing
while using react-test-renderer see [here](https://github.com/facebook/react/issues/8324)

### `storyNameRegex`

If you'd like to only run a subset of the stories for your snapshot tests based on the story's name:

```js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({
  storyNameRegex: /buttons/,
});
```

### `framework`

If you are running tests from outside of your app's directory, storyshots' detection of which framework you are using may fail. Pass `"react"` or `"react-native"` to short-circuit this. 

For example:
```js
// storybook.test.js

import path from 'path';
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({
  framework: 'react', // Manually specify the project's framework
  configPath: path.join(__dirname, '.storybook'),
  integrityOptions: { cwd: path.join(__dirname, 'src', 'stories') },
  // Other configurations
});
```

Use this table as a reference for manually specifying the framework.

| angular        | html | preact       |
|----------------|------|--------------|
| react          | riot | react-native |
| svelte         | vue  | vue3         |
| web-components | rax  |              |


### `test`

Run a custom test function for each story, rather than the default (a vanilla snapshot test).
Setting `test` will take precedence over the `renderer` option.
You can still overwrite what renderer is used for the test function:

```js
import initStoryshots, { renderWithOptions } from '@storybook/addon-storyshots';
import { mount } from 'enzyme';

initStoryshots({
  test: renderWithOptions({
    renderer: mount,
  }),
});
```

### `renderer`

Pass a custom renderer (such as enzymes `mount`) to record snapshots.
This may be necessary if you want to use React features that are not supported by the default test renderer,
such as **ref** or **Portals**.
Note that setting `test` overrides `renderer`.


### `snapshotSerializers`

Pass an array of snapshotSerializers to the jest runtime that serializes your story (such as enzyme-to-json).

```js
import initStoryshots from '@storybook/addon-storyshots';
import { createSerializer } from 'enzyme-to-json';

initStoryshots({
  renderer: mount,
  snapshotSerializers: [createSerializer()],
});
```

This option needs to be set if either:

- the multiSnapshot function is used to create multiple snapshot files (i.e. one per story), since it ignores any serializers specified in your jest config.
- serializers not specified in your jest config should be used when snapshotting stories.

### `serializer` (deprecated)

Pass a custom serializer (such as enzyme-to-json) to serialize components to snapshot-comparable data. The functionality of this option is completely covered by [snapshotSerializers](`snapshotSerializers`) which should be used instead.

```js
import initStoryshots from '@storybook/addon-storyshots';
import toJSON from 'enzyme-to-json';

initStoryshots({
  renderer: mount,
  serializer: toJSON,
});
```

This option only needs to be set if the default `snapshotSerializers` is not set in your jest config.

### `stories2snapsConverter`

This parameter should be an instance of the [`Stories2SnapsConverter`](src/Stories2SnapsConverter.js) (or a derived from it) Class that is used to convert story-file name to snapshot-file name and vice versa.

By default, the instance of this class is created with these default options:

```js
{
  snapshotsDirName: '__snapshots__',
  snapshotExtension: '.storyshot',
  storiesExtensions: ['.js', '.jsx', '.ts', '.tsx'],
}
```

This class might be overridden to extend the existing conversion functionality or instantiated to provide different options:

```js
import initStoryshots, { Stories2SnapsConverter } from '@storybook/addon-storyshots';

initStoryshots({
  stories2snapsConverter: new Stories2SnapsConverter({
    snapshotExtension: '.storypuke',
    storiesExtensions: ['.foo'],
  }),
});
```

## Exports

Apart from the default export (`initStoryshots`), Storyshots also exports some named test functions (see the `test` option above):

### `snapshot`

The default, render the story as normal and take a Jest snapshot.

### `renderOnly`

Just render the story, don't check the output at all. This is useful as a low-effort way of smoke testing your
components to ensure they do not error.

### `snapshotWithOptions(options)`

Like the default, but allows you to specify a set of options for the test renderer. [See for example here](https://github.com/storybookjs/storybook/blob/b915b5439786e0edb17d7f5ab404bba9f7919381/examples/test-cra/src/storyshots.test.js#L14-L16).

### `renderWithOptions(options)`

Like the default, but allows you to specify a set of options for the renderer, just like `snapshotWithOptions`.

### `multiSnapshotWithOptions(options)`

Like `snapshotWithOptions`, but generate a separate snapshot file for each stories file rather than a single monolithic file (as is the convention in Jest). This makes it dramatically easier to review changes. If you'd like the benefit of separate snapshot files, but don't have custom options to pass, you can pass an empty object.
If you use [Component Story Format](https://storybook.js.org/docs/react/api/csf), you may also need to add an additional Jest transform to automate detecting story file names:

```js
// jest.config.js
module.exports = {
  transform: {
    '^.+\\.stories\\.jsx?$': '@storybook/addon-storyshots/injectFileName',
    '^.+\\.jsx?$': 'babel-jest',
  },
};
```

#### integrityOptions

This option is useful when running test with `multiSnapshotWithOptions(options)` in order to track snapshots are matching the stories. (disabled by default).
The value is a [settings](https://github.com/isaacs/node-glob#options) to a `glob` object, that searches for the snapshot files.

```js
initStoryshots({
  integrityOptions: { cwd: __dirname }, // it will start searching from the current directory
  test: multiSnapshotWithOptions(),
});
```

### `shallowSnapshot`

Take a snapshot of a shallow-rendered version of the component. Note that this option will be overridden if you pass a `renderer` option.

### `Stories2SnapsConverter`

This is a class that generates snapshot's name based on the story (kind, story & filename) and vice versa.

###### Example:

Let's say we wanted to create a test function for shallow && multi-file snapshots:

```js
import initStoryshots, { Stories2SnapsConverter } from '@storybook/addon-storyshots';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';

const converter = new Stories2SnapsConverter();

initStoryshots({
  test: ({ story, context }) => {
    const snapshotFileName = converter.getSnapshotFileName(context);
    const storyElement = story.render();
    const shallowTree = shallow(storyElement);

    if (snapshotFileName) {
      expect(toJson(shallowTree)).toMatchSpecificSnapshot(snapshotFileName);
    }
  },
});
```

### `asyncJest`

Enables Jest `done()` callback in the StoryShots tests for async testing. See [StoryShots for async rendered components](#storyshots-for-async-rendered-components) for more info.

## Story Parameters

### `disable`

Some stories are difficult or impossible to snapshot, such as those covering components that use external DOM-modifying libraries, and those that deliberately throw errors. It is possible to skip stories like these by giving them a parameter of `storyshots: {disable: true}`. There is also a shorthand for this, `storyshots: false`.

```js
export const Exception = () => {
  throw new Error('storyFn threw an error! WHOOPS');
};
Exception.storyName = 'story throws exception';
Exception.parameters = {
  storyshots: { disable: true },
};
```

---

## File: addons/storyshots/storyshots-puppeteer/README.md

# StoryShots + [Puppeteer](https://github.com/GoogleChrome/puppeteer)

## Getting Started

Add the following modules into your app.

```sh
npm install @storybook/addon-storyshots-puppeteer puppeteer --save-dev
```

⚠️ As of Storybook 5.3 `puppeteer` is no more included in addon dependencies and must be added to your project directly.

## Configure Storyshots for Puppeteer tests

⚠️ **React-native** is **not supported** by this test function.

When willing to run Puppeteer tests for your stories, you have two options:

- Have a storybook running (ie. accessible via http(s), for instance using `npm run storybook`)
- Have a static build of the storybook (for instance, using `npm run build-storybook`)

Then you will need to reference the storybook URL (`file://...` if local, `http(s)://...` if served)

## _puppeteerTest_

Allows to define arbitrary Puppeteer tests as `story.parameters.puppeteerTest` function.

You can either create a new Storyshots instance or edit the one you previously used:

```js
import initStoryshots from '@storybook/addon-storyshots';
import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer';

initStoryshots({ suite: 'Puppeteer storyshots', test: puppeteerTest() });
```

Then, in your stories:

```js
export const myExample = () => {
  ...
};
myExample.parameters = {
  async puppeteerTest(page) {
    const element = await page.$('<some-selector>');
    await element.click();
    expect(something).toBe(something);
  },
};
```

This will assume you have a storybook running on at _<http://localhost:6006>_.
Internally here are the steps:

- Launches a Chrome headless using [puppeteer](https://github.com/GoogleChrome/puppeteer)
- Browses each stories (calling _<http://localhost:6006/iframe.html?...>_ URL),
- Runs the `parameters.puppeteerTest` function if it's defined.

### Specifying the storybook URL

If you want to set specific storybook URL, you can specify via the `storybookUrl` parameter, see below:

```js
import initStoryshots from '@storybook/addon-storyshots';
import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer';

initStoryshots({
  suite: 'Puppeteer storyshots',
  test: puppeteerTest({ storybookUrl: 'http://my-specific-domain.com:9010' }),
});
```

The above config will use _<https://my-specific-domain.com:9010>_ for tests. You can also use query parameters in your URL (e.g. for setting a different background for your storyshots, if you use `@storybook/addon-backgrounds`).

You may also use a local static build of storybook if you do not want to run the webpack dev-server:

```js
import initStoryshots from '@storybook/addon-storyshots';
import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer';

initStoryshots({
  suite: 'Puppeteer storyshots',
  test: puppeteerTest({
    storybookUrl: 'file:///path/to/my/storybook-static',
    // storybookUrl: 'file://${path.resolve(__dirname, '../storybook-static')}'
  }),
});
```

### Specifying options to _goto()_ (Puppeteer API)

You might use `getGotoOptions` to specify options when the storybook is navigating to a story (using the `goto` method). Will be passed to [Puppeteer .goto() fn](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagegotourl-options)

```js
import initStoryshots from '@storybook/addon-storyshots';
import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer';

const getGotoOptions = ({ context, url }) => {
  return {
    waitUntil: 'networkidle0',
  };
};

initStoryshots({
  suite: 'Puppeteer storyshots',
  test: puppeteerTest({ storybookUrl: 'http://localhost:6006', getGotoOptions }),
});
```

### Specifying custom Chrome executable path (Puppeteer API)

You might use `chromeExecutablePath` to specify the path to a different version of Chrome, without downloading Chromium. Will be passed to [Runs a bundled version of Chromium](https://github.com/GoogleChrome/puppeteer#default-runtime-settings)

```js
import initStoryshots from '@storybook/addon-storyshots';
import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer';

const chromeExecutablePath = '/usr/local/bin/chrome';

initStoryshots({
  suite: 'Puppeteer storyshots',
  test: puppeteerTest({ storybookUrl: 'http://localhost:6006', chromeExecutablePath }),
});
```

### Specifying a custom Puppeteer `browser` instance

You might use the async `getCustomBrowser` function to obtain a custom instance of a Puppeteer `browser` object. This will prevent `storyshots-puppeteer` from creating its own `browser`. It will create and close pages within the `browser`, and it is your responsibility to manage the lifecycle of the `browser` itself.

```js
import initStoryshots from '@storybook/addon-storyshots';
import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer';
import puppeteer from 'puppeteer';

(async function () {
  initStoryshots({
    suite: 'Puppeteer storyshots',
    test: puppeteerTest({
      storybookUrl: 'http://localhost:6006',
      getCustomBrowser: () => puppeteer.connect({ browserWSEndpoint: 'ws://yourUrl' }),
    }),
  });
})();
```

### Customizing a `page` instance

Sometimes, there is a need to customize a page before it calls the `goto` api.

An example of device emulation:

```js
import initStoryshots from '@storybook/addon-storyshots';
import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer';
const devices = require('puppeteer/DeviceDescriptors');

const iPhone = devices['iPhone 6'];

function customizePage(page) {
  return page.emulate(iPhone);
}

initStoryshots({
  suite: 'Puppeteer storyshots',
  test: puppeteerTest({
    storybookUrl: 'http://localhost:6006',
    customizePage,
  }),
});
```

### Specifying setup and tests timeout

By default, `@storybook/addon-storyshots-puppeteer` uses 15 second timeouts for browser setup and test functions.
Those can be customized with `setupTimeout` and `testTimeout` parameters.

### Integrate Puppeteer storyshots with regular app

You may want to use another Jest project to run your Puppeteer storyshots as they require more resources: Chrome and Storybook built/served.
You can find a working example of this in the [official-storybook](https://github.com/storybookjs/storybook/tree/master/examples/official-storybook) example.

### Integrate Puppeteer storyshots with [Create React App](https://github.com/facebookincubator/create-react-app)

You have two options here, you can either:

- Add the storyshots configuration inside any of your `test.js` file. You must ensure you have either a running storybook or a static build available.

- Create a custom test file using Jest outside of the CRA scope:

  A more robust approach would be to separate existing test files ran by create-react-app (anything `(test|spec).js` suffixed files) from the test files to run Puppeteer storyshots.
  This use case can be achieved by using a custom name for the test file, ie something like `puppeteer-storyshots.runner.js`. This file will contain the `initStoryshots` call with Puppeteer storyshots configuration.
  Then you will create a separate script entry in your package.json, for instance

  ```json
  {
    "scripts": {
      "puppeteer-storyshots": "jest puppeteer-storyshots.runner.js --config path/to/custom/jest.config.json"
    }
  }
  ```

  Note that you will certainly need a custom config file for Jest as you run it outside of the CRA scope and thus you do not have the built-in config.

  Once that's setup, you can run `npm run puppeteer-storyshots`.

### Reminder

Puppeteer launches a web browser (Chrome) internally.

The browser opens a page (either using the static build of storybook or a running instance of Storybook)

If you run your test without either the static build or a running instance, this wont work.

To make sure your tests run against the latest changes of your Storybook, you must keep your static build or running Storybook up-to-date.
This can be achieved by adding a step before running the test ie: `npm run build-storybook && npm run image-snapshots`.
If you run the Puppeteer storyshots against a running Storybook in dev mode, you don't have to worry about the stories being up-to-date because the dev-server is watching changes and rebuilds automatically.

## _axeTest_

Runs [Axe](https://www.deque.com/axe/) accessibility checks and verifies that they pass using [jest-puppeteer-axe](https://github.com/WordPress/gutenberg/tree/master/packages/jest-puppeteer-axe).

```js
import initStoryshots from '@storybook/addon-storyshots';
import { axeTest } from '@storybook/addon-storyshots-puppeteer';

initStoryshots({ suite: 'A11y checks', test: axeTest() });
```

For configuration, it uses the same `story.parameters.a11y` parameter as [`@storybook/addon-a11y`](https://github.com/storybookjs/storybook/tree/next/addons/a11y#parameters)

## _imageSnapshots_

Generates and compares screenshots of your stories using [jest-image-snapshot](https://github.com/americanexpress/jest-image-snapshot).

```js
import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';

initStoryshots({ suite: 'Image storyshots', test: imageSnapshot() });
```

It saves all images under \_\_image_snapshots\_\_ folder.

### Specifying options to _jest-image-snapshots_

If you wish to customize [jest-image-snapshot](https://github.com/americanexpress/jest-image-snapshot), then you can provide a `getMatchOptions` parameter that should return the options config object. Additionally, you can provide `beforeScreenshot` which is called before the screenshot is captured and a `afterScreenshot` handler which is called after the screenshot and receives the just created image.

```js
import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';
const getMatchOptions = ({ context: { kind, story }, url }) => {
  return {
    failureThreshold: 0.2,
    failureThresholdType: 'percent',
  };
};
const beforeScreenshot = (page, { context: { kind, story }, url }) => {
  return new Promise((resolve) =>
    setTimeout(() => {
      resolve();
    }, 600)
  );
};
const afterScreenshot = ({ image, context }) => {
  return new Promise((resolve) =>
    setTimeout(() => {
      resolve();
    }, 600)
  );
};
initStoryshots({
  suite: 'Image storyshots',
  test: imageSnapshot({
    storybookUrl: 'http://localhost:6006',
    getMatchOptions,
    beforeScreenshot,
    afterScreenshot,
  }),
});
```

`getMatchOptions` receives an object: `{ context: {kind, story}, url}`. _kind_ is the kind of the story and the _story_ its name. _url_ is the URL the browser will use to screenshot.

`beforeScreenshot` receives the [Puppeteer page instance](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-page) and an object: `{ context: {kind, story}, url}`. _kind_ is the kind of the story and the _story_ its name. _url_ is the URL the browser will use to screenshot. `beforeScreenshot` is part of the promise chain and is called after the browser navigation is completed but before the screenshot is taken. It allows for triggering events on the page elements and delaying the screenshot and can be used avoid regressions due to mounting animations.

`afterScreenshot` receives the created image from puppeteer.

### Specifying options to _screenshot()_ (Puppeteer API)

You might use `getScreenshotOptions` to specify options for screenshot. Will be passed to [Puppeteer .screenshot() fn](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagescreenshotoptions)

```js
import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';
const getScreenshotOptions = ({ context, url }) => {
  return {
    encoding: 'base64', // encoding: 'base64' is a property required by puppeteer
    fullPage: false, // Do not take the full page screenshot. Default is 'true' in Storyshots.,
  };
};
initStoryshots({
  suite: 'Image storyshots',
  test: imageSnapshot({ storybookUrl: 'http://localhost:6006', getScreenshotOptions }),
});
```

`getScreenshotOptions` receives an object `{ context: {kind, story}, url}`. _kind_ is the kind of the story and the _story_ its name. _url_ is the URL the browser will use to screenshot.

To create a screenshot of just a single element (with its children), rather than the page or current viewport, an ElementHandle can be returned from `beforeScreenshot`:
```js
import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';

const beforeScreenshot = (page) => page.$('#root > *');

initStoryshots({
  suite: 'Image storyshots',
  test: imageSnapshot({ storybookUrl: 'http://localhost:6006', beforeScreenshot }),
});
```

---

## File: addons/storyshots/README.md

# StoryShots

- [addon-storyshots](storyshots-core) - Basic StoryShots api
- [addon-storyshots-puppeteer](storyshots-puppeteer) - Integration of StoryShots with [puppeteer](https://github.com/GoogleChrome/puppeteer)

---

## File: addons/queryparams/README.md

# storybook-addon-queryparams

This storybook addon can be helpful if your components need special query parameters to work the way you want them to. It allows you to mock query params per story so that you can easily reproduce different states of your component.

## Getting started

First, install the addon.

```sh
$ yarn add @storybook/addon-queryparams --dev
```

Register it by adding it in the addons attribute in your `main.js` file (create this file inside your storybook config directory if needed).

```js
module.exports = {
  addons: ['@storybook/addon-queryparams'],
};
```

In your story, add the `withQuery` decorator and define the query parameters you want to mock:

```js
import React from 'react';
import { Button } from '@storybook/react/demo';
import { withQuery } from '@storybook/addon-queryparams';

export default {
  title: 'Button',
  component: Button,
  decorators: [withQuery],
  parameters: {
    query: {
      mock: 'Hello world!',
    },
  },
};

export const WithMockedSearch = () => {
  const urlParams = new URLSearchParams(document.location.search);
  const mockedParam = urlParams.get('mock');
  return Mocked value: {mockedParam};
};
```


  Example with storiesOf API

```js
import React from 'react';
import { storiesOf } from '@storybook/react';

storiesOf('button', module)
  .addParameters({
    query: {
      mock: 'Hello World!',
    },
  })
  .add('Prints the mocked parameter', () => {
    const urlParams = new URLSearchParams(document.location.search);
    const mockedParam = urlParams.get('mock');
    return Mocked value: {mockedParam};
  });
```

---

## File: addons/links/README.md

# Story Links Addon

The Storybook Links addon can be used to create links that navigate between stories in [Storybook](https://storybook.js.org).

[Framework Support](https://github.com/storybookjs/storybook/blob/master/ADDONS_SUPPORT.md)

## Getting Started

Install this addon by adding the `@storybook/addon-links` dependency:

```sh
yarn add -D @storybook/addon-links
```

within `.storybook/main.js`:

```js
module.exports = {
  addons: ['@storybook/addon-links']
}
```

Then you can import `linkTo` in your stories and use like this:

```js
import { linkTo } from '@storybook/addon-links'

export default {
  title: 'Button',
};

export const first = () => (
  Go to "Second"
);
export const second = () => (
  Go to "First"
);
```

Have a look at the linkTo function:

```js
import { linkTo } from '@storybook/addon-links'

linkTo('Toggle', 'off')
linkTo(() => 'Toggle', () => 'off')
linkTo('Toggle') // Links to the first story in the 'Toggle' kind
```

With that, you can link an event in a component to any story in the Storybook.

- First parameter is the story kind name (what you named with `title`).
- Second (optional) parameter is the story name (what you named with `exported name`). 
  If the second parameter is omitted, the link will point to the first story in the given kind.

You can also pass a function instead for any of above parameter. That function accepts arguments emitted by the event and it should return a string:

```js
import { LinkTo, linkTo } from '@storybook/addon-links';

export default {
  title: 'Select',
};

export const index = () => (
  <select value="Index" onChange={linkTo('Select', e => e.currentTarget.value)}>
    <option>index</option>
    <option>first</option>
    <option>second</option>
    <option>third</option>
  </select>  
);
export const first = () => (
  <LinkTo story="index">Go back</LinkTo>
);
export const second = () => (
  <LinkTo story="index">Go back</LinkTo>
);
export const third = () => (
  <LinkTo story="index">Go back</LinkTo>
);
```

## hrefTo function

If you want to get an URL for a particular story, you may use `hrefTo` function. It returns a promise, which resolves to string containing a relative URL:

```js
import { hrefTo } from '@storybook/addon-links';
import { action } from '@storybook/addon-actions';

export default {
  title: 'Href',
};

export const log = () => {
  hrefTo('Href', 'log').then(action('URL of this story'));

  return See action logger;
};
```

## withLinks decorator

`withLinks` decorator enables a declarative way of defining story links, using data attributes.
Here is an example in React, but it works with any framework:

```js
import { withLinks } from '@storybook/addon-links'

export default {
  title: 'Button',
  decorators: [withLinks],
};

export const first = () => (
  Go to "OtherStory"
);
```

## LinkTo component (React only)

One possible way of using `hrefTo` is to create a component that uses native `a` element, but prevents page reloads on plain left click, so that one can still use default browser methods to open link in new tab.
A React implementation of such a component can be imported from `@storybook/addon-links` package:

```js
import LinkTo from '@storybook/addon-links/react';

export default {
  title: 'Link',
};

export const first = () => (
  <LinkTo story="second">Go to Second</LinkTo>
);
export const second = () => (
  <LinkTo story="first">Go to First</LinkTo>
);
```

It accepts all the props the `a` element does, plus `story` and `kind`. It the `kind` prop is omitted, the current kind will be preserved.

```js
<LinkTo
  kind="Toggle"
  story="off"
  target="_blank"
  title="link to second story"
  style={{color: '#1474f3'}}
>Go to Second</LinkTo>
```

To implement such a component for another framework, you need to add special handling for `click` event on native `a` element. See [`RoutedLink` sources](https://github.com/storybookjs/storybook/blob/master/addons/links/src/react/components/RoutedLink.js#L20-L24) for reference.

---

## File: addons/knobs/README.md

# Storybook Addon Knobs

Storybook Addon Knobs allow you to edit props dynamically using the Storybook UI.
You can also use Knobs as a dynamic variable inside stories in [Storybook](https://storybook.js.org).

[Framework Support](https://github.com/storybookjs/storybook/blob/master/ADDONS_SUPPORT.md).

This is what Knobs looks like:

[](https://storybooks-official.netlify.com/?knob-Dollars=12.5&knob-Name=Storyteller&knob-Years%20in%20NY=9&knob-background=%23ffff00&knob-Age=70&knob-Items%5B0%5D=Laptop&knob-Items%5B1%5D=Book&knob-Items%5B2%5D=Whiskey&knob-Other%20Fruit=lime&knob-Birthday=1484870400000&knob-Nice=true&knob-Styles=%7B%22border%22%3A%223px%20solid%20%23ff00ff%22%2C%22padding%22%3A%2210px%22%7D&knob-Fruit=apple&selectedKind=Addons%7CKnobs.withKnobs&selectedStory=tweaks%20static%20values&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybooks%2Fstorybook-addon-knobs)

> Checkout the above [Live Storybook](https://storybooks-official.netlify.com/?knob-Dollars=12.5&knob-Name=Storyteller&knob-Years%20in%20NY=9&knob-background=%23ffff00&knob-Age=70&knob-Items%5B0%5D=Laptop&knob-Items%5B1%5D=Book&knob-Items%5B2%5D=Whiskey&knob-Other%20Fruit=lime&knob-Birthday=1484870400000&knob-Nice=true&knob-Styles=%7B%22border%22%3A%223px%20solid%20%23ff00ff%22%2C%22padding%22%3A%2210px%22%7D&knob-Fruit=apple&selectedKind=Addons%7CKnobs.withKnobs&selectedStory=tweaks%20static%20values&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybooks%2Fstorybook-addon-knobs) or [watch this video](https://www.youtube.com/watch?v=kopW6vzs9dg&feature=youtu.be).

## Getting Started

First of all, you need to install Knobs into your project as a dev dependency.

```sh
yarn add @storybook/addon-knobs --dev
```

within `.storybook/main.js`:

```js
module.exports = {
  addons: ['@storybook/addon-knobs'],
};
```

Now, write your stories with Knobs.

### With React

```js
import React from 'react';
import { withKnobs, text, boolean, number } from '@storybook/addon-knobs';

export default {
  title: 'Storybook Knobs',
  decorators: [withKnobs],
};
// Add the `withKnobs` decorator to add knobs support to your stories.
// You can also configure `withKnobs` as a global decorator.

// Knobs for React props
export const withAButton = () => (
  {text('Label', 'Hello Storybook')}
);

// Knobs as dynamic variables.
export const asDynamicVariables = () => {
  const name = text('Name', 'James');
  const age = number('Age', 35);
  const content = `I am ${name} and I'm ${age} years old.`;

  return {content};
};
```

### With Vue.js

MyButton.story.js:

```js
import { storiesOf } from '@storybook/vue';
import { withKnobs, text, boolean } from '@storybook/addon-knobs';

import MyButton from './MyButton.vue';

export default {
  title: 'Storybook Knobs',
  decorators: [withKnobs],
};

// Assign `props` to the story's component, calling
// knob methods within the `default` property of each prop,
// then pass the story's prop data to the component’s prop in
// the template with `v-bind:` or by placing the prop within
// the component’s slot.
export const exampleWithKnobs = () => ({
  components: { MyButton },
  props: {
    isDisabled: {
      default: boolean('Disabled', false),
    },
    text: {
      default: text('Text', 'Hello Storybook'),
    },
  },
  template: `<MyButton :isDisabled="isDisabled">{{ text }}</MyButton>`,
});
```

MyButton.vue:

```vue
<template>
  
    <slot></slot>
  
</template>

<script>
export default {
  props: {
    isDisabled: {
      type: Boolean,
      default: false,
    },
  },
};
</script>
```

### With Angular

```js
import { storiesOf } from '@storybook/angular';
import { boolean, number, text, withKnobs } from '@storybook/addon-knobs';

import { Button } from '@storybook/angular/demo';

export default {
  title: 'Storybook Knobs',
  decorators: [withKnobs],
};

export const withKnobs = () => ({
  component: Button,
  props: {
    text: text('text', 'Hello Storybook'), // The first param of the knob function has to be exactly the same as the component input.
  },
});
```

### With Ember

```js
import { withKnobs, text, boolean } from '@storybook/addon-knobs';
import { hbs } from 'ember-cli-htmlbars';

export default {
  title: 'StoryBook with Knobs',
  decorators: [withKnobs],
};

export const button = () => ({
  template: hbs`
    {{label}}
  `,
  context: {
    label: text('label', 'Hello Storybook'),
    disabled: boolean('disabled', false),
  },
});
```

## Categorization

Categorize your Knobs by assigning them a `groupId`. When a `groupId` exists, tabs will appear in the Knobs storybook panel to filter between the groups. Knobs without a `groupId` are automatically categorized into the `ALL` group.

```js
export const inGroups = () => {
  const personalGroupId = 'personal info';
  const generalGroupId = 'general info';

  const name = text('Name', 'James', personalGroupId);
  const age = number('Age', 35, { min: 0, max: 99 }, personalGroupId);
  const message = text('Hello!', 35, generalGroupId);
  const content = `
    I am ${name} and I'm ${age} years old.
    ${message}
  `;

  return {content};
};
```

You can see your Knobs in a Storybook panel as shown below.



## Available Knobs

These are the Knobs available for you to use. You can import these Knobs from the `@storybook/addon-knobs` module.
Here's how to import the **text** Knob.

```js
import { text } from '@storybook/addon-knobs';
```

Just like that, you can import any other following Knobs:

### text

Allows you to get some text from the user.

```js
import { text } from '@storybook/addon-knobs';

const label = 'Your Name';
const defaultValue = 'James';
const groupId = 'GROUP-ID1';

const value = text(label, defaultValue, groupId);
```

### boolean

Allows you to get a boolean value from the user.

```js
import { boolean } from '@storybook/addon-knobs';

const label = 'Agree?';
const defaultValue = false;
const groupId = 'GROUP-ID1';

const value = boolean(label, defaultValue, groupId);
```

### number

Allows you to get a number from the user.

```js
import { number } from '@storybook/addon-knobs';

const label = 'Age';
const defaultValue = 78;
const groupId = 'GROUP-ID1';

const value = number(label, defaultValue);
```

For use with `groupId`, pass the default `options` as the third argument.

```js
const value = number(label, defaultValue, {}, groupId);
```

### number bound by range

Allows you to get a number from the user using a range slider.

```js
import { number } from '@storybook/addon-knobs';

const label = 'Temperature';
const defaultValue = 73;
const options = {
  range: true,
  min: 60,
  max: 90,
  step: 1,
};
const groupId = 'GROUP-ID1';

const value = number(label, defaultValue, options, groupId);
```

### color

Allows you to get a colour from the user.

```js
import { color } from '@storybook/addon-knobs';

const label = 'Color';
const defaultValue = '#ff00ff';
const groupId = 'GROUP-ID1';

const value = color(label, defaultValue, groupId);
```

### object

Allows you to get a JSON object or array from the user.

```js
import { object } from '@storybook/addon-knobs';

const label = 'Styles';
const defaultValue = {
  backgroundColor: 'red',
};
const groupId = 'GROUP-ID1';

const value = object(label, defaultValue, groupId);
```

> Make sure to enter valid JSON syntax while editing values inside the knob.

### array

Allows you to get an array of strings from the user.

```js
import { array } from '@storybook/addon-knobs';

const label = 'Styles';
const defaultValue = ['Red'];
const groupId = 'GROUP-ID1';

const value = array(label, defaultValue);
```

> While editing values inside the knob, you will need to use a separator.
> By default it is a comma, but this can be overridden by passing a separator variable.
>
> ```js
> import { array } from '@storybook/addon-knobs';
>
> const label = 'Styles';
> const defaultValue = ['Red'];
> const separator = ':';
> const value = array(label, defaultValue, separator);
> ```

For use with `groupId`, pass the default `separator` as the third argument.

```js
const value = array(label, defaultValue, ',', groupId);
```

### select

It allows you to get a value from a select box from the user.

```js
import { select } from '@storybook/addon-knobs';

const label = 'Colors';
const options = {
  Red: 'red',
  Blue: 'blue',
  Yellow: 'yellow',
  Rainbow: ['red', 'orange', 'etc'],
  None: null,
};
const defaultValue = 'red';
const groupId = 'GROUP-ID1';

const value = select(label, options, defaultValue, groupId);
```

Options can also be an array:

```js
import { select } from '@storybook/addon-knobs';
const label = 'Cats';
const options = ['linus', 'eleanor', 'lover'];
const defaultValue = 'eleanor';
const groupId = 'GROUP-ID2';
const value = select(label, options, defaultValue, groupId);
```

Options can also be an array OF objects:

```js
const label = 'Dogs';
const arrayOfObjects = [
  {
    label: 'Sparky',
    dogParent: 'Matthew',
    location: 'Austin',
  },
  {
    label: 'Juniper',
    dogParent: 'Joshua',
    location: 'Austin',
  },
];
const defaultValue = arrayOfObjects[0];
const groupId = 'GROUP-ID3';
const value = select(label, arrayOfObjects, defaultValue, groupId);
```

### radio buttons

It allows you to get a value from a list of radio buttons from the user.

```js
import { radios } from '@storybook/addon-knobs';

const label = 'Fruits';
const options = {
  Kiwi: 'kiwi',
  Guava: 'guava',
  Watermelon: 'watermelon',
};
const defaultValue = 'kiwi';
const groupId = 'GROUP-ID1';

const value = radios(label, options, defaultValue, groupId);
```

### options

Configurable UI for selecting a value from a set of options.

```js
import { optionsKnob } from '@storybook/addon-knobs';

const label = 'Fruits';
const valuesObj = {
  Kiwi: 'kiwi',
  Guava: 'guava',
  Watermelon: 'watermelon',
};
const defaultValue = 'kiwi';
const optionsObj = {
  display: 'inline-radio',
};
const groupId = 'GROUP-ID1';

const value = optionsKnob(label, valuesObj, defaultValue, optionsObj, groupId);
```

Alternatively you can use this import:
```
import { optionsKnob as options } from '@storybook/addon-knobs';

...

const value = options(label, valuesObj, defaultValue, optionsObj, groupId);
```

> The display property for `optionsObj` accepts:
>
> - `radio`
> - `inline-radio`
> - `check`
> - `inline-check`
> - `select`
> - `multi-select`

### files

It allows you to get a value from a file input from the user.

```js
import { files } from '@storybook/addon-knobs';

const label = 'Images';
const accept = '.xlsx, .pdf';
const defaultValue = [];
const groupId = 'GROUP-ID1';

const value = files(label, accept, defaultValue, groupId);
```

> You can optionally specify a [list of file types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) which the file input should accept.
> Multiple files can be selected, and will be returned as an array of [Data URLs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs).

### date

Allows you to get date (and time) from the user.

```js
import { date } from '@storybook/addon-knobs';

const label = 'Event Date';
const defaultValue = new Date('Jan 20 2017');
const groupId = 'GROUP-ID1';

const value = date(label, defaultValue, groupId);
```

> Note: the default value must not change - e.g., do not do `date('Label', new Date())` or `date('Label')`.

The `date` knob returns the selected date as stringified Unix timestamp (e.g. `"1510913096516"`).
If your component needs the date in a different form you can wrap the `date` function:

```js
function myDateKnob(name, defaultValue) {
  const stringTimestamp = date(name, defaultValue);
  return new Date(stringTimestamp);
}
```

### button

It allows you to include a button and associated handler.

```js
import { button } from '@storybook/addon-knobs';

const label = 'Do Something';
const handler = () => doSomething('foobar');
const groupId = 'GROUP-ID1';

button(label, handler, groupId);
```

Button knobs cause the story to re-render after the handler fires.
You can prevent this by having the handler return `false`.

### withKnobs options

withKnobs also accepts two optional options as story parameters.
Usage:

```js
import { withKnobs } from '@storybook/addon-knobs';

export default {
  title: 'Storybook Knobs',
  decorators: [withKnobs],
};

export const defaultView = () => ;
defaultView.parameters = {
  knobs: {
    // Doesn't emit events while user is typing.
    timestamps: true,

    // Escapes strings to be safe for inserting as innerHTML. This option is true by default. It's safe to set it to `false` with frameworks like React which do escaping on their side.
    // You can still set it to false, but it's strongly discouraged to set to true in cases when you host your storybook on some route of your main site or web app.
    escapeHTML: true,
  },
};
```

## Typescript

If you are using Typescript, make sure you have the type definitions installed for the following libs:

- node
- react

You can install them using: (_assuming you are using Typescript >2.0._)

```sh
yarn add @types/node @types/react --dev
```