Never Post Memes

    storybook-include
    TypeScript icon, indicating that this package has built-in type declarations

    1.1.1 • Public • Published

    Storybook Include


    storybook include logo

    Controlling decorators in monorepo environments


    npm downloads

    Idea

    Storybook decorators are very powerful, but with great power comes great responsibility.

    In the beginning it is ok to define global decorators. But as the project grows, different paths might require different management or decorators.

    Adding these decorators to the every story does not scale from a maintanance point of view.

    So, what about defining decorators on a folder level?

    😎 think about it as .eslintrc or .babelrc configuration you can have globally defined as well as "per folder"

    Setup

    Install this addon by adding the storybook-include dependency:

    yarn add -D storybook-include
    

    within .storybook/main.js:

    module.exports = {
      addons: [
        'storybook-include',
        // or
        require.resolve('storybook-include/preset'),
      ],
    };

    Usage

    • no changes has to be made to stories, everything can be configured externaly

    • create a storybook.include.js, or .ts or .jsx/.tsx in a folder. It can be any folder, including your home folder

    • configure which decorators has to be included

    • it works

    Configuration

    Example file

    // storybook.include.js
    import { addStoryDecorators } from 'storybook-include';
    
    // decorators are defined via default export
    export default () => {
      addStoryDecorators((story, { storyName, fileName }) => {
        // you can mutate story
        story.args = { decorated: true };
        // you can add decorators
        story.decorators.push(myDecorator);
        // you can return an array of decorators to add
        return storyName.includes('dark') ? [darkModeDecorator] : undefined;
      });
    
      // another set
      addStoryDecorators((story, { fileName }) => {
        return fileName.includes('page') ? [ReactRouterDecorator, StaticRouterDecorator] : undefined;
      });
    
      // another set
      addStoryDecorators((story) => {
        return [CSSInJS, Theme, AndSomethingElse];
      });
    };

    Reusing configuration

    In rare cases you might consider sharing the same configuration between two configuration files. While simple duplication is usually preferred, there is a simpler way to do it

    // storybook.include
    import another from '../../other/storybook.include';
    // ^ it's from another "branch", all explit parents will be "included" in any case
    
    export default () => {
      // do you thing
      another();
    };

    Using for not .stories.*

    Sometimes a non-standard file names for stories can be used - .story.*, example.* and so on. In this case default preset will not work, and a custom one will be required

    // your custom preset
    /* eslint-disable no-param-reassign */
    export function babel(options) {
      options.overrides = options.overrides || [];
      options.overrides.push({
        test: /\.stories\.tsx?/, // <-- pattern matching your stories
        plugins: [require.resolve('storybook-include/babel')],
      });
      return options;
    }

    Note on caching

    While storybook does not enforce build caching this plugin is built with it in mind. As a result every file " autoconfigures" all "include files" above it, and every other file can "reconfigure" that list.

    Theoretically that affects performance for non cached systems.

    ⛔️ removing-renaming include file might require cache update.

    See also

    • storybook-csf-title - a plugin with close semantic - creates title for a storybook basing on the location of a story file.

    License

    MIT

    Install

    npm i storybook-include

    DownloadsWeekly Downloads

    294

    Version

    1.1.1

    License

    MIT

    Unpacked Size

    35.5 kB

    Total Files

    37

    Last publish

    Collaborators

    • kashey