Skip to content

Latest commit

 

History

History
2151 lines (1497 loc) · 92 KB

MIGRATION.md

File metadata and controls

2151 lines (1497 loc) · 92 KB

Migration

From version 6.1.x to 6.2.0

MDX pattern tweaked

In 6.2 files ending in stories.mdx or story.mdx are now processed with Storybook's MDX compiler. Previously it only applied to files ending in .stories.mdx or .story.mdx. See more here: #13996.

6.2 Angular overhaul

New Angular storyshots format

We've updated the Angular storyshots format in 6.2, which is technically a breaking change. Apologies to semver purists: if you're using storyshots, you'll need to update your snapshots.

The new format hides the implementation details of @storybook/angular so that we can evolve its renderer without breaking your snapshots in the future.

Deprecated Angular story component

Storybook 6.2 for Angular uses parameters.component as the preferred way to specify your stories' components. The previous method, in which the component was a return value of the story, has been deprecated.

Consider the existing story from 6.1 or earlier:

export default { title: 'Button' };
export const Basic = () => ({
  component: Button,
  props: { label: 'Label' },
});

From 6.2 this should be rewritten as:

export default { title: 'Button', component: Button };
export const Basic = () => ({
  props: { label: 'Label' },
});

The new convention is consistent with how other frameworks and addons work in Storybook. The old way will be supported until 7.0. For a full discussion see #8673.

New Angular renderer

We've rewritten the Angular renderer in Storybook 6.2. It's meant to be entirely backwards compatible, but if you need to use the legacy renderer it's still available via a parameter. To opt out of the new renderer, add the following to .storybook/preview.ts:

export const parameters = {
  angularLegacyRendering: true,
};

Please also file an issue if you need to opt out. We plan to remove the legacy renderer in 7.0.

Components Without Selectors

When the new Angular renderer is used, all Angular Story components must either have a selector, or be added to the entryComponents array of the story's moduleMetadata. If the component has any Inputs or Outputs to be controlled with args, a selector should be added.

Packages now available as ESModules

Many Storybook packages are now available as ESModules in addition to CommonJS. If your jest tests stop working, this is likely why. To fix, you can configure jest to transform the packages like so (more info):

// In your jest config
transformIgnorePatterns: ['/node_modules/(?!@storybook)']

6.2 Deprecations

Deprecated implicit PostCSS loader

Previously, @storybook/core would automatically add the postcss-loader to your preview. This caused issues for consumers when PostCSS upgraded to v8 and tools, like Autoprefixer and Tailwind, starting requiring the new version. Implictly adding postcss-loader will be removed in Storybook 7.0.

Instead of continuing to include PostCSS inside the core library, it has been moved to @storybook/addon-postcss. This addon provides more fine-grained customization and will be upgraded more flexibly to track PostCSS upgrades.

If you require PostCSS support, please install @storybook/addon-postcss in your project, add it to your list of addons inside .storybook/main.js, and configure a postcss.config.js file.

Further information is available at #12668 and #13669.

If you're not using Postcss and you don't want to see the warning, you can disable it by adding the following to your .storybook/main.js:

module.exports = {
  features: {
    postcss: false,
  },
};

Deprecated default PostCSS plugins

When relying on the implicit PostCSS loader, it would also add autoprefixer v9 and postcss-flexbugs-fixes v4 plugins to the postcss-loader configuration when you didn't have a PostCSS config file (such as postcss.config.js) within your project.

They will no longer be applied when switching to @storybook/addon-postcss and the implicit PostCSS features will be removed in Storybook 7.0.

If you depend upon these plugins being applied, install them and create a postcss.config.js file within your project that contains:

module.exports = {
  plugins: [
    require('postcss-flexbugs-fixes'),
    require('autoprefixer')({
      flexbox: 'no-2009',
    }),
  ],
};

Deprecated showRoots config option

Config options for the sidebar are now under the sidebar namespace. The showRoots option should be set as follows:

addons.setConfig({
  sidebar: {
    showRoots: false,
  },
  // showRoots: false   <- this is deprecated
});

The top-level showRoots option will be removed in Storybook 7.0.

Deprecated control.options

Possible options for a radio/check/select controls has been moved up to the argType level, and no longer accepts an object. Instead, you should specify options as an array. You can use control.labels to customize labels. Additionally, you can use a mapping to deal with complex values.

argTypes: {
  answer:
    options: ['yes', 'no'],
    mapping: {
      yes: <Check />,
      no: <Cross />,
    },
    control: {
      type: 'radio',
      labels: {
        yes: 'да',
        no: 'нет',
      }
    }
  }
}

Keys in control.labels as well as in mapping should match the values in options. Neither object has to be exhaustive, in case of a missing property, the option value will be used directly.

If you are currently using an object as value for control.options, be aware that the key and value are reversed in control.labels.

Deprecated storybook components html entry point

Storybook HTML components are now exported directly from '@storybook/components' for better ESM and Typescript compatibility. The old entry point will be removed in SB 7.0.

// before
import { components } from '@storybook/components/html';

// after
import { components } from '@storybook/components';

From version 6.0.x to 6.1.0

Addon-backgrounds preset

In 6.1 we introduced an unintentional breaking change to addon-backgrounds.

The addon uses decorators which are set up automatically by a preset. The required preset is ignored if you register the addon in main.js with the /register entry point. This used to be valid in v6.0.x and earlier:

module.exports = {
  stories: ['../**/*.stories.js'],
  addons: ['@storybook/addon-backgrounds/register'],
};

To fix it, just replace @storybook/addon-backgrounds/register with @storybook/addon-backgrounds:

module.exports = {
  stories: ['../**/*.stories.js'],
  addons: ['@storybook/addon-backgrounds'],
};

Single story hoisting

Stories which have no siblings (i.e. the component has only one story) and which name exactly matches the component name will now be hoisted up to replace their parent component in the sidebar. This means you can have a hierarchy like this:

DESIGN SYSTEM   [root]
- Atoms         [group]
  - Button      [component]
    - Button    [story]
  - Checkbox    [component]
    - Checkbox  [story]

This will then be visually presented in the sidebar like this:

DESIGN SYSTEM   [root]
- Atoms         [group]
  - Button      [story]
  - Checkbox    [story]

See Naming components and hierarchy for details.

React peer dependencies

Starting in 6.1, react and react-dom are required peer dependencies of @storybook/react, meaning that if your React project does not have dependencies on them, you need to add them as devDependencies. If you don't you'll see errors like this:

Error: Cannot find module 'react-dom/package.json'

They were also peer dependencies in earlier versions, but due to the package structure they would be installed by Storybook if they were not required by the user's project. For more discussion: #13269

6.1 deprecations

Deprecated DLL flags

Earlier versions of Storybook used Webpack DLLs as a performance crutch. In 6.1, we've removed Storybook's built-in DLLs and have deprecated the command-line parameters --no-dll and --ui-dll. They will be removed in 7.0.

Deprecated storyFn

Each item in the story store contains a field called storyFn, which is a fully decorated story that's applied to the denormalized story parameters. Starting in 6.0 we've stopped using this API internally, and have replaced it with a new field called unboundStoryFn which, unlike storyFn, must passed a story context, typically produced by applyLoaders;

Before:

const { storyFn } = store.fromId('some--id');
console.log(storyFn());

After:

const { unboundStoryFn, applyLoaders } = store.fromId('some--id');
const context = await applyLoaders();
console.log(unboundStoryFn(context));

If you're not using loaders, storyFn will work as before. If you are, you'll need to use the new approach.

NOTE: If you're using @storybook/addon-docs, this deprecation warning is triggered by the Docs tab in 6.1. It's safe to ignore and we will be providing a proper fix in 6.2. You can track the issue at #13074.

Deprecated onBeforeRender

The @storybook/addon-docs previously accepted a jsx option called onBeforeRender, which was unfortunately named as it was called after the render.

We've renamed it transformSource and also allowed it to receive the StoryContext in case source rendering requires additional information.

Deprecated grid parameter

Previously when using @storybook/addon-backgrounds if you wanted to customize the grid, you would define a parameter like this:

export const Basic = () => <Button />
Basic.parameters: {
  grid: {
    cellSize: 10
  }
},

As grid is not an addon, but rather backgrounds is, the grid configuration was moved to be inside backgrounds parameter instead. Also, there are new properties that can be used to further customize the grid. Here's an example with the default values:

export const Basic = () => <Button />
Basic.parameters: {
  backgrounds: {
    grid: {
      disable: false,
      cellSize: 20,
      opacity: 0.5,
      cellAmount: 5,
      offsetX: 16, // default is 0 if story has 'fullscreen' layout, 16 if layout is 'padded'
      offsetY: 16, // default is 0 if story has 'fullscreen' layout, 16 if layout is 'padded'
    }
  }
},

Deprecated package-composition disabled parameter

Like Deprecated disabled parameter. The disabled parameter has been deprecated, please use disable instead.

For more information, see the the related documentation.

From version 5.3.x to 6.0.x

Hoisted CSF annotations

Storybook 6 introduces hoisted CSF annotations and deprecates the StoryFn.story object-style annotation.

In 5.x CSF, you would annotate a story like this:

export const Basic = () => <Button />
Basic.story = {
  name: 'foo',
  parameters: { ... },
  decorators: [ ... ],
};

In 6.0 CSF this becomes:

export const Basic = () => <Button />
Basic.storyName = 'foo';
Basic.parameters = { ... };
Basic.decorators = [ ... ];
  1. The new syntax is slightly more compact/ergonomic compared the the old one
  2. Similar to React's displayName, propTypes, defaultProps annotations
  3. We're introducing a new feature, Storybook Args, where the new syntax will be significantly more ergonomic

To help you upgrade your stories, we've created a codemod:

npx @storybook/cli@next migrate csf-hoist-story-annotations --glob="**/*.stories.js"

For more information, see the documentation.

Zero config typescript

Storybook has built-in Typescript support in 6.0. That means you should remove your complex Typescript configurations from your .storybook config. We've tried to pick sensible defaults that work out of the box, especially for nice prop table generation in @storybook/addon-docs.

To migrate from an old setup, we recommend deleting any typescript-specific webpack/babel configurations in your project. You should also remove @storybook/preset-typescript, which is superceded by the built-in configuration.

If you want to override the defaults, see the typescript configuration docs.

Correct globs in main.js

In 5.3 we introduced the main.js file with a stories property. This property was documented as a "glob" pattern. This was our intention, however the implementation allowed for non valid globs to be specified and work. In fact, we promoted invalid globs in our documentation and CLI templates.

We've corrected this, the CLI templates have been changed to use valid globs.

We've also changed the code that resolves these globs, so that invalid globs will log a warning. They will break in the future, so if you see this warning, please ensure you're specifying a valid glob.

Example of an invalid glob:

stories: ['./**/*.stories.(ts|js)']

Example of a valid glob:

stories: ['./**/*.stories.@(ts|js)']

CRA preset removed

The built-in create-react-app preset, which was previously deprecated, has been fully removed.

If you're using CRA and migrating from an earlier Storybook version, please install @storybook/preset-create-react-app if you haven't already.

Core-JS dependency errors

Some users have experienced core-js dependency errors when upgrading to 6.0, such as:

Module not found: Error: Can't resolve 'core-js/modules/web.dom-collections.iterator'

We think this comes from having multiple versions of core-js installed, but haven't isolated a good solution (see #11255 for discussion).

For now, the workaround is to install core-js directly in your project as a dev dependency:

npm install core-js@^3.0.1 --save-dev

Args passed as first argument to story

Starting in 6.0, the first argument to a story function is an Args object. In 5.3 and earlier, the first argument was a StoryContext, and that context is now passed as the second argument by default.

This breaking change only affects you if your stories actually use the context, which is not common. If you have any stories that use the context, you can either (1) update your stories, or (2) set a flag to opt-out of new behavior.

Consider the following story that uses the context:

export const Dummy = ({ parameters }) => <div>{JSON.stringify(parameters)}</div>;

Here's an updated story for 6.0 that ignores the args object:

export const Dummy = (_args, { parameters }) => <div>{JSON.stringify(parameters)}</div>;

Alternatively, if you want to opt out of the new behavior, you can add the following to your .storybook/preview.js config:

export const parameters = {
  passArgsFirst: false,
};

6.0 Docs breaking changes

Remove framework-specific docs presets

In SB 5.2, each framework had its own preset, e.g. @storybook/addon-docs/react/preset. In 5.3 we unified this into a single preset: @storybook/addon-docs/preset. In 6.0 we've removed the deprecated preset.

Preview/Props renamed

In 6.0 we renamed Preview to Canvas, Props to ArgsTable. The change should be otherwise backwards-compatible.

Docs theme separated

In 6.0, you should theme Storybook Docs with the docs.theme parameter.

In 5.x, the Storybook UI and Storybook Docs were themed using the same theme object. However, in 5.3 we introduced a new API, addons.setConfig, which improved UI theming but broke Docs theming. Rather than trying to keep the two unified, we introduced a separate theming mechanism for docs, docs.theme. Read about Docs theming here.

DocsPage slots removed

In SB5.2, we introduced the concept of DocsPage slots for customizing the DocsPage.

In 5.3, we introduced docs.x story parameters like docs.prepareForInline which get filled in by frameworks and can also be overwritten by users, which is a more natural/convenient way to make global customizations.

We also introduced Custom DocsPage, which makes it possible to add/remove/update DocBlocks on the page.

These mechanisms are superior to slots, so we've removed slots in 6.0. For each slot, we provide a migration path here:

Slot Slot function Replacement
Title titleSlot Custom DocsPage
Subtitle subtitleSlot Custom DocsPage
Description descriptionSlot docs.extractComponentDescription parameter
Primary primarySlot Custom DocsPage
Props propsSlot docs.extractProps parameter
Stories storiesSlot Custom DocsPage

React prop tables with Typescript

Props handling in React has changed in 6.0 and should be much less error-prone. This is not a breaking change per se, but documenting the change here since this is an area that has a lot of issues and we've gone back and forth on it.

Starting in 6.0, we have zero-config typescript support. The out-of-box experience should be much better now, since the default configuration is designed to work well with addon-docs.

There are also two typescript handling options that can be set in .storybook/main.js. react-docgen-typescript (default) and react-docgen. This is discussed in detail in the docs.

ConfigureJSX true by default in React

In SB 6.0, the Storybook Docs preset option configureJSX is now set to true for all React projects. It was previously false by default for React only in 5.x). This configureJSX option adds @babel/plugin-transform-react-jsx, to process the output of the MDX compiler, which should be a safe change for all projects.

If you need to restore the old JSX handling behavior, you can configure .storybook/main.js:

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

User babelrc disabled by default in MDX

In SB 6.0, the Storybook Docs no longer applies the user's babelrc by default when processing MDX files. It caused lots of hard-to-diagnose bugs.

To restore the old behavior, or pass any MDX-specific babel options, you can configure .storybook/main.js:

module.exports = {
  addons: [
    {
      name: '@storybook/addon-docs',
      options: { mdxBabelOptions: { babelrc: true, configFile: true } },
    },
  ],
};

Docs description parameter

In 6.0, you can customize a component description using the docs.description.component parameter, and a story description using docs.description.story parameter.

Example:

import { Button } from './Button';

export default {
  title: 'Button'
  parameters: { docs: { description: { component: 'some component **markdown**' }}}
}

export const Basic = () => <Button />
Basic.parameters = { docs: { description: { story: 'some story **markdown**' }}}

In 5.3 you customized a story description with the docs.storyDescription parameter. This has been deprecated, and support will be removed in 7.0.

6.0 Inline stories

The following frameworks now render stories inline on the Docs tab by default, rather than in an iframe: react, vue, web-components, html.

To disable inline rendering, set the docs.inlineStories parameter to false.

New addon presets

In Storybook 5.3 we introduced a declarative main.js configuration, which is now the recommended way to configure Storybook. Part of the change is a simplified syntax for registering addons, which in 6.0 automatically registers many addons using a preset, which is a slightly different behavior than in earlier versions.

This breaking change currently applies to: addon-a11y, addon-actions, addon-knobs, addon-links, addon-queryparams.

Consider the following main.js config for addon-knobs:

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

In earlier versions of Storybook, this would automatically call @storybook/addon-knobs/register, which adds the the knobs panel to the Storybook UI. As a user you would also add a decorator:

import { withKnobs } from '../index';

addDecorator(withKnobs);

Now in 6.0, addon-knobs comes with a preset, @storybook/addon-knobs/preset, that does this automatically for you. This change simplifies configuration, since now you don't need to add that decorator.

If you wish to disable this new behavior, you can modify your main.js to force it to use the register logic rather than the preset:

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

If you wish to selectively disable knobs checks for a subset of stories, you can control this with story parameters:

export const MyNonCheckedStory = () => <SomeComponent />;
MyNonCheckedStory.story = {
  parameters: {
    knobs: { disable: true },
  },
};

Removed babel-preset-vue from Vue preset

babel-preset-vue is not included by default anymore when using Storybook with Vue. This preset is outdated and caused problems with more modern setups.

If you have an older Vue setup that relied on this preset, make sure it is included in your babel config (install babel-preset-vue and add it to the presets).

{
  "presets": ["babel-preset-vue"]
}

However, please take a moment to review why this preset is necessary in your setup. One usecase used to be to enable JSX in your stories. For this case, we recommend to use @vue/babel-preset-jsx instead.

Removed Deprecated APIs

In 6.0 we removed a number of APIs that were previously deprecated.

See the migration guides for further details:

New setStories event

The setStories/SET_STORIES event has changed and now denormalizes global and kind-level parameters. The new format of the event data is:

{
  globalParameters: { p: 'q' },
  kindParameters: { kind: { p: 'q' } },
  stories: /* as before but with only story-level parameters */
}

If you want the full denormalized parameters for a story, you can do something like:

import { combineParameters } from '@storybook/api';

const story = data.stories[storyId];
const parameters = combineParameters(
  data.globalParameters,
  data.kindParameters[story.kind],
  story.parameters
);

Removed renderCurrentStory event

The story store no longer emits renderCurrentStory/RENDER_CURRENT_STORY to tell the renderer to render the story. Instead it emits a new declarative CURRENT_STORY_WAS_SET (in response to the existing SET_CURRENT_STORY) which is used to decide to render.

Removed hierarchy separators

We've removed the ability to specify the hierarchy separators (how you control the grouping of story kinds in the sidebar). From Storybook 6.0 we have a single separator /, which cannot be configured.

If you are currently using custom separators, we encourage you to migrate to using / as the sole separator. If you are using | or . as a separator currently, we provide a codemod, upgrade-hierarchy-separators, that can be used to rename your components. Note: the codemod will not work for .mdx components, you will need to make the changes by hand.

npx sb@next migrate upgrade-hierarchy-separators --glob="*/**/*.stories.@(tsx|jsx|ts|js)"

We also now default to showing "roots", which are non-expandable groupings in the sidebar for the top-level groups. If you'd like to disable this, set the showRoots option in .storybook/manager.js:

import addons from '@storybook/addons';

addons.setConfig({
  showRoots: false,
});

No longer pass denormalized parameters to storySort

The storySort function (set via the parameters.options.storySort parameter) previously compared two entries [storyId, storeItem], where storeItem included the full "denormalized" set of parameters of the story (i.e. the global, kind and story parameters that applied to that story).

For performance reasons, we now store the parameters uncombined, and so pass the format: [storyId, storeItem, kindParameters, globalParameters].

Client API changes

Removed Legacy Story APIs

In 6.0 we removed a set of APIs from the underlying StoryStore (which wasn't publicly accessible):

  • getStories, getStoryFileName, getStoryAndParameters, getStory, getStoryWithContext, hasStoryKind, hasStory, dumpStoryBook, size, clean

Although these were private APIs, if you were using them, you could probably use the newer APIs (which are still private): getStoriesForKind, getRawStory, removeStoryKind, remove.

Can no longer add decorators/parameters after stories

You can no longer add decorators and parameters globally after you added your first story, and you can no longer add decorators and parameters to a kind after you've added your first story to it.

It's unclear and confusing what would happened if you did. If you want to disable a decorator for certain stories, use a parameter to do so:

export StoryOne = ...;
StoryOne.story = { parameters: { addon: { disable: true } } };

If you want to use a parameter for a subset of stories in a kind, simply use a variable to do so:

const commonParameters = { x: { y: 'z' } };
export StoryOne = ...;
StoryOne.story = { parameters: { ...commonParameters, other: 'things' } };

NOTE: also the use of addParameters and addDecorator at arbitrary points is also deprecated, see the deprecation warning.

Changed Parameter Handling

There have been a few rationalizations of parameter handling in 6.0 to make things more predictable and fit better with the intention of parameters:

All parameters are now merged recursively to arbitrary depth.

In 5.3 we sometimes merged parameters all the way down and sometimes did not depending on where you added them. It was confusing. If you were relying on this behaviour, let us know.

Array parameters are no longer "merged".

If you override an array parameter, the override will be the end product. If you want the old behaviour (appending a new value to an array parameter), export the original and use array spread. This will give you maximum flexibility:

import { allBackgrounds } from './util/allBackgrounds';

export StoryOne = ...;
StoryOne.story = { parameters: { backgrounds: [...allBackgrounds, '#zyx' ] } };

You cannot set parameters from decorators

Parameters are intended to be statically set at story load time. So setting them via a decorator doesn't quite make sense. If you were using this to control the rendering of a story, chances are using the new args feature is a more idiomatic way to do this.

You can only set storySort globally

If you want to change the ordering of stories, use export const parameters = { options: { storySort: ... } } in preview.js.

Simplified Render Context

The RenderContext that is passed to framework rendering layers in order to render a story has been simplified, dropping a few members that were not used by frameworks to render stories. In particular, the following have been removed:

  • selectedKind/selectedStory -- replaced by kind/name
  • configApi
  • storyStore
  • channel
  • clientApi

Story Store immutable outside of configuration

You can no longer change the contents of the StoryStore outside of a configure() call. This is to ensure that any changes are properly published to the manager. If you want to add stories "out of band" you can call store.startConfiguring() and store.finishConfiguring() to ensure that your changes are published.

Improved story source handling

The story source code handling has been improved in both addon-storysource and addon-docs.

In 5.x some users used an undocumented internal API, mdxSource to customize source snippetization in addon-docs. This has been removed in 6.0.

The preferred way to customize source snippets for stories is now:

export const Example = () => <Button />;
Example.story = {
  parameters: {
    storySource: {
      source: 'custom source',
    },
  },
};

The MDX analog:

<Story name="Example" parameters={{ storySource: { source: 'custom source' } }}>
  <Button />
</Story>

6.0 Addon API changes

Consistent local addon paths in main.js

If you use .storybook/main.js config and have locally-defined addons in your project, you need to update your file paths.

In 5.3, addons paths were relative to the project root, which was inconsistent with stories paths, which were relative to the .storybook folder. In 6.0, addon paths are now relative to the config folder.

So, for example, if you had:

module.exports = { addons: ['./.storybook/my-local-addon/register'] };

You'd need to update this to:

module.exports = { addons: ['./my-local-addon/register'] };

Deprecated setAddon

We've deprecated the setAddon method of the storiesOf API and plan to remove it in 7.0.

Since early versions, Storybook shipped with a setAddon API, which allows you to extend storiesOf with arbitrary code. We've removed this from all core addons long ago and recommend writing stories in Component Story Format rather than using the internal Storybook API.

Deprecated disabled parameter

Starting in 6.0.17, we've renamed the disabled parameter to disable to resolve an inconsistency where disabled had been used to hide the addon panel, whereas disable had been used to disable an addon's execution. Since disable was much more widespread in the code, we standardized on that.

So, for example:

Story.parameters = { actions: { disabled: true } }

Should be rewritten as:

Story.parameters = { actions: { disable: true } }

Actions addon uses parameters

Leveraging the new preset @storybook/addon-actions uses parameters to pass action options. If you previously had:

import { withActions } from `@storybook/addon-actions`;

export StoryOne = ...;
StoryOne.story = {
  decorators: [withActions('mouseover', 'click .btn')],
}

You should replace it with:

export StoryOne = ...;
StoryOne.story = {
  parameters: { actions: ['mouseover', 'click .btn'] },
}

Removed action decorator APIs

In 6.0 we removed the actions addon decorate API. Actions handles can be configured globally, for a collection of stories or per story via parameters. The ability to manipulate the data arguments of an event is only relevant in a few frameworks and is not a common enough usecase to be worth the complexity of supporting.

Removed withA11y decorator

In 6.0 we removed the withA11y decorator. The code that runs accessibility checks is now directly injected in the preview.

To configure a11y now, you have to specify configuration using story parameters, e.g. in .storybook/preview.js:

export const parameters = {
  a11y: {
    element: '#root',
    config: {},
    options: {},
    manual: true,
  },
};

Essentials addon disables differently

In 6.0, addon-essentials doesn't configure addons if the user has already configured them in main.js. In 5.3 it previously checked to see whether the package had been installed in package.json to disable configuration. The new setup is preferably because now users' can install essential packages and import from them without disabling their configuration.

Backgrounds addon has a new api

Starting in 6.0, the backgrounds addon now receives an object instead of an array as parameter, with a property to define the default background.

Consider the following example of its usage in Button.stories.js:

// Button.stories.js
export default {
  title: 'Button',
  parameters: {
    backgrounds: [
      { name: 'twitter', value: '#00aced', default: true },
      { name: 'facebook', value: '#3b5998' },
    ],
  },
};

Here's an updated version of the example, using the new api:

// Button.stories.js
export default {
  title: 'Button',
  parameters: {
    backgrounds: {
      default: 'twitter',
      values: [
        { name: 'twitter', value: '#00aced' },
        { name: 'facebook', value: '#3b5998' },
      ],
    },
  },
};

In addition, backgrounds now ships with the following defaults:

  • no selected background (transparent)
  • light/dark options

6.0 Deprecations

We've deprecated the following in 6.0: addon-info, addon-notes, addon-contexts, addon-centered, polymer.

Deprecated addon-info, addon-notes

The info/notes addons have been replaced by addon-docs. We've documented a migration in the docs recipes.

Both addons are still widely used, and their source code is still available in the deprecated-addons repo. We're looking for maintainers for both addons. If you're interested, please get in touch on our Discord.

Deprecated addon-contexts

The contexts addon has been replaced by addon-toolbars, which is simpler, more ergonomic, and compatible with all Storybook frameworks.

The addon's source code is still available in the deprecated-addons repo. If you're interested in maintaining it, please get in touch on our Discord.

Removed addon-centered

In 6.0 we removed the centered addon. Centering is now core feature of storybook, so we no longer need an addon.

Remove the addon-centered decorator and instead add a layout parameter:

export const MyStory = () => <div>my story</div>;
MyStory.story = {
  parameters: { layout: 'centered' },
};

Other possible values are: padded (default) and fullscreen.

Deprecated polymer

We've deprecated @storybook/polymer and are focusing on @storybook/web-components. If you use Polymer and are interested in maintaining it, please get in touch on our Discord.

Deprecated immutable options parameters

The UI options sidebarAnimations, enableShortcuts, theme, showRoots should not be changed on a per-story basis, and as such there is no reason to set them via parameters.

You should use addon.setConfig to set them:

// in .storybook/manager.js
import addons from '@storybook/addons';

addons.setConfig({
  showRoots: false,
});

Deprecated addParameters and addDecorator

The addParameters and addDecorator APIs to add global decorators and parameters, exported by the various frameworks (e.g. @storybook/react) and @storybook/client are now deprecated.

Instead, use export const parameters = {}; and export const decorators = []; in your .storybook/preview.js. Addon authors similarly should use such an export in a preview entry file (see Preview entries).

Deprecated clearDecorators

Similarly, clearDecorators, exported by the various frameworks (e.g. @storybook/react) is deprecated.

Deprecated configure

The configure API to load stories from preview.js, exported by the various frameworks (e.g. @storybook/react) is now deprecated.

To load stories, use the stories field in main.js. You can pass a glob or array of globs to load stories like so:

// in .storybook/main.js
module.exports = {
  stories: ['../src/**/*.stories.js'],
};

You can also pass an array of single file names if you want to be careful about loading files:

// in .storybook/main.js
module.exports = {
  stories: [
    '../src/components/Button.stories.js',
    '../src/components/Table.stories.js',
    '../src/components/Page.stories.js',
  ],
};

Deprecated support for duplicate kinds

In 6.0 we deprecated the ability to split a kind's (component's) stories into multiple files because it was causing issues in hot module reloading (HMR). It will likely be removed completely in 7.0.

If you had N stories that contained export default { title: 'foo/bar' } (or the MDX equivalent <Meta title="foo/bar">), Storybook will now raise the warning Duplicate title '${kindName}' used in multiple files.

To split a component's stories into multiple files, e.g. for the foo/bar example above:

  • Create a single file with the export default { title: 'foo/bar' } export, which is the primary file
  • Comment out or delete the default export from the other files
  • Re-export the stories from the other files in the primary file

So the primary example might look like:

export default { title: 'foo/bar' };
export * from './Bar1.stories'
export * from './Bar2.stories'
export * from './Bar3.stories'

export const SomeStory = () => ...;

From version 5.2.x to 5.3.x

To main.js configuration

In storybook 5.3 3 new files for configuration were introduced, that replaced some previous files.

These files are now soft-deprecated, (they still work, but over time we will promote users to migrate):

  • presets.js has been renamed to main.js. main.js is the main point of configuration for storybook.
  • config.js has been renamed to preview.js. preview.js configures the "preview" iframe that renders your components.
  • addons.js has been renamed to manager.js. manager.js configures Storybook's "manager" UI that wraps the preview, and also configures addons panel.

Using main.js

main.js is now the main point of configuration for Storybook. This is what a basic main.js looks like:

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

You remove all "register" import from addons.js and place them inside the array. You can also safely remove the /register suffix from these entries, for a cleaner, more readable configuration. If this means addons.js is now empty for you, it's safe to remove.

Next you remove the code that imports/requires all your stories from config.js, and change it to a glob-pattern and place that glob in the stories array. If this means config.js is empty, it's safe to remove.

If you had a presets.js file before you can add the array of presets to the main.js file and remove presets.js like so:

module.exports = {
  stories: ['../**/*.stories.js'],
  addons: [
    '@storybook/preset-create-react-app',
    {
      name: '@storybook/addon-docs',
      options: { configureJSX: true },
    },
  ],
};

By default, adding a package to the addons array will first try to load its preset entry, then its register entry, and finally, it will just assume the package itself is a preset.

If you want to load a specific package entry, for example you want to use @storybook/addon-docs/register, you can also include that in the addons array and Storybook will do the right thing.

Using preview.js

If after migrating the imports/requires of your stories to main.js you're left with some code in config.js it's likely the usage of addParameters & addDecorator.

This is fine, rename config.js to preview.js.

This file can also be used to inject global stylesheets, fonts etc, into the preview bundle.

Using manager.js

If you are setting storybook options in config.js, especially theme, you should migrate it to manager.js:

import { addons } from '@storybook/addons';
import { create } from '@storybook/theming/create';

const theme = create({
  base: 'light',
  brandTitle: 'My custom title',
});

addons.setConfig({
  panelPosition: 'bottom',
  theme,
});

This makes storybook load and use the theme in the manager directly. This allows for richer theming in the future, and has a much better performance!

If you're using addon-docs, you should probably not do this. Docs uses the theme as well, but this change makes the theme inaccessible to addon-docs. We'll address this in 6.0.0.

Create React App preset

You can now move to the new preset for Create React App. The in-built preset for Create React App will be disabled in Storybook 6.0.

Simply install @storybook/preset-create-react-app and it will be used automatically.

Description doc block

In 5.3 we've changed addon-docs's Description doc block's default behavior. Technically this is a breaking change, but MDX was not officially released in 5.2 and we reserved the right to make small breaking changes. The behavior of DocsPage, which was officially released, remains unchanged.

The old behavior of <Description of={Component} /> was to concatenate the info parameter or notes parameter, if available, with the docgen information loaded from source comments. If you depend on the old behavior, it's still available with <Description of={Component} type='legacy-5.2' />. This description type will be removed in Storybook 6.0.

The new default behavior is to use the framework-specific description extractor, which for React/Vue is still docgen, but may come from other places (e.g. a JSON file) for other frameworks.

The description doc block on DocsPage has also been updated. To see how to configure it in 5.3, please see the updated recipe

React Native Async Storage

Starting from version React Native 0.59, Async Storage is deprecated in React Native itself. The new @react-native-community/async-storage module requires native installation, and we don't want to have it as a dependency for React Native Storybook.

To avoid that now you have to manually pass asyncStorage to React Native Storybook with asyncStorage prop. To notify users we are displaying a warning about it.

Solution:

  • Use require('@react-native-community/async-storage').default for React Native v0.59 and above.
  • Use require('react-native').AsyncStorage for React Native v0.58 or below.
  • Use null to disable Async Storage completely.
getStorybookUI({
  ...
  asyncStorage: require('@react-native-community/async-storage').default || require('react-native').AsyncStorage || null
});

The benefit of using Async Storage is so that when users refresh the app, Storybook can open their last visited story.

Deprecate displayName parameter

In 5.2, the story parameter displayName was introduced as a publicly visible (but internal) API. Storybook's Component Story Format (CSF) loader used it to modify a story's display name independent of the story's name/id (which were coupled).

In 5.3, the CSF loader decouples the story's name/id, which means that displayName is no longer necessary. Unfortunately, this is a breaking change for any code that uses the story name field. Storyshots relies on story name, and the appropriate migration is to simply update your snapshots. Apologies for the inconvenience!

Unified docs preset

Addon-docs configuration gets simpler in 5.3. In 5.2, each framework had its own preset, e.g. @storybook/addon-docs/react/preset. Starting in 5.3, everybody should use @storybook/addon-docs/preset.

Simplified hierarchy separators

We've deprecated the ability to specify the hierarchy separators (how you control the grouping of story kinds in the sidebar). From Storybook 6.0 we will have a single separator /, which cannot be configured.

If you are currently using using custom separators, we encourage you to migrate to using / as the sole separator. If you are using | or . as a separator currently, we provide a codemod, upgrade-hierarchy-separators, that can be used to rename all your components.

yarn sb migrate upgrade-hierarchy-separators --glob="*.stories.js"

If you were using | and wish to keep the "root" behavior, use the showRoots: true option to re-enable roots:

addParameters({
  options: {
    showRoots: true,
  },
});

NOTE: it is no longer possible to have some stories with roots and others without. If you want to keep the old behavior, simply add a root called "Others" to all your previously unrooted stories.

Addon StoryShots Puppeteer uses external puppeteer

To give you more control on the Chrome version used when running StoryShots Puppeteer, puppeteer is no more included in the addon dependencies. So you can now pick the version of puppeteer you want and set it in your project.

If you want the latest version available just run:

yarn add puppeteer --dev
OR
npm install puppeteer --save-dev

From version 5.1.x to 5.2.x

Source-loader

Addon-storysource contains a loader, @storybook/addon-storysource/loader, which has been deprecated in 5.2. If you use it, you'll see the warning:

@storybook/addon-storysource/loader is deprecated, please use @storybook/source-loader instead.

To upgrade to @storybook/source-loader, run npm install -D @storybook/source-loader (or use yarn), and replace every instance of @storybook/addon-storysource/loader with @storybook/source-loader.

Default viewports

The default viewports have been reduced to a smaller set, we think is enough for most use cases. You can get the old default back by adding the following to your config.js:

import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';

addParameters({
  viewport: {
    viewports: INITIAL_VIEWPORTS,
  },
});

Grid toolbar-feature

The grid feature in the toolbar has been relocated to addon-background, follow the setup instructions on that addon to get the feature again.

Docs mode docgen

This isn't a breaking change per se, because addon-docs is a new feature. However it's intended to replace addon-info, so if you're migrating from addon-info there are a few things you should know:

  1. Support for only one prop table
  2. Prop table docgen info should be stored on the component and not in the global variable STORYBOOK_REACT_CLASSES as before.

storySort option

In 5.0.x the global option sortStoriesByKind option was inadvertently removed. In 5.2 we've introduced a new option, storySort, to replace it. storySort takes a comparator function, so it is strictly more powerful than sortStoriesByKind.

For example, here's how to sort by story ID using storySort:

addParameters({
  options: {
    storySort: (a, b) =>
      a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, undefined, { numeric: true }),
  },
});

From version 5.1.x to 5.1.10

babel.config.js support

SB 5.1.0 added support for project root babel.config.js files, which was an unintentional breaking change. 5.1.10 fixes this, but if you relied on project root babel.config.js support, this bugfix is a breaking change. The workaround is to copy the file into your .storybook config directory. We may add back project-level support in 6.0.

From version 5.0.x to 5.1.x

React native server

Storybook 5.1 contains a major overhaul of @storybook/react-native as compared to 4.1 (we didn't ship a version of RN in 5.0 due to timing constraints). Storybook for RN consists of an an UI for browsing stories on-device or in a simulator, and an optional webserver which can also be used to browse stories and web addons.

5.1 refactors both pieces:

  • @storybook/react-native no longer depends on the Storybook UI and only contains on-device functionality
  • @storybook/react-native-server is a new package for those who wish to run a web server alongside their device UI

In addition, both packages share more code with the rest of Storybook, which will reduce bugs and increase compatibility (e.g. with the latest versions of babel, etc.).

As a user with an existing 4.1.x RN setup, no migration should be necessary to your RN app. Upgrading the library should be enough.

If you wish to run the optional web server, you will need to