Storybook: How to add button on main toolbar?

2.4k Views Asked by At

I am actually trying to add a button(icon) on the main storybook toolbar. Currently the toolbar has few actions as shown below,

Storybook-toolbar

Similar I want to append a button with some actions like below,

https://style.monday.com/?path=/docs/buttons-icon-button--overview&globals=memoryStats:yes

I see different examples online with latest versions of storybook but couldn't find something that works for my use case. Currently in our project we are using config.js(which is preview.js in new versions) file in which there is a configuration related to themes using addParameter api. But when I tried adding the same to create a button on the toolbar, nothing seems to be working.

// config.js
// Below is the existing configuration

import { configure, addDecorator, addParameters } from '@storybook/react';
// other code

addParameters({
  options: {
    theme: myTheme
  },
  backgrounds: [
    { name: 'white', value: '#fff', default: true },
    { name: 'inverse', value: '#16325c' }
  ]
});

Is there a way to add one more action to the main toolbar and perform action based on click event?

Storybook version which I am currently using: v5

References:

2

There are 2 best solutions below

2
On

in case the button you want to add will trigger some custom action, the best way to go (in storybook 6) is to write a very small addon:

  1. Create your plugin file, e.g. .storybook/addons-myButtonAddon/register.js:
import React from 'react';

import { addons, types } from '@storybook/addons';
import { IconButton } from '@storybook/components';

const ADDON_ID = 'myAddonId';

addons.register(ADDON_ID, () => {
  addons.add(ADDON_ID, {
    title: "My button title",
    type: types.TOOL,
    match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)),
    render: ({ active }) => {
      return (
        <IconButton
          active={active}
          title="Do Something"
          onClick={() => {
            // ... do something
          }
        }>
          Click Me!
        </IconButton>
      )},
  });
});

Please note that React is used here for Storybook only, since Storybook is build in React. This is independent of the actual framework you are building your components with.

  1. Add the addon to your config by adding this line to .storybook/main.js:
module.exports = {
  managerEntries: ['./.storybook/addons-myButtonAddon/register'],
  1. and finally you might need to add @storybook/manager-webpack5 to your package.json. file via npm i -D @storybook/manager-webpack5

Then the button should appear in the toolbar, executing the action defined in the click listener.

Instead of the button text you might add an SVG to have a nice icon on the button. <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> ... </svg>

0
On

You can use the storybook globals. By default the toolbar addon is installed.

Enable it:

export default {
  addons: ['@storybook/addon-toolbars'],
};

Add your toolbar items to globalTypes. Here's an example

const preview: Preview = {
  globalTypes: {
    elementsHighlight: {
    name: 'Highlight elements',
    description: 'Highlight different types of elements',
    toolbar: {
      icon: 'location',
      items: [
// icons https://storybook.js.org/docs/react/faq#what-icons-are-available-for-my-toolbar-or-my-addon
        { value: 'testids', title: 'Highlight data-testids', icon: 'beaker' },
        { value: false, title: 'No highlight', type: 'reset', icon: 'cross' },
      ],
    }, // as TooltipItem https://github.com/storybookjs/storybook/blob/5bd426472aa3d6d715f0ee6478eff5574c43d4fe/code/addons/toolbars/src/types.ts#L15
  },
}

Now in the decorators:

const preview: Preview = {
  decorators: [
    (storyFn, context) => {
       if (context.globals.elementsHighlight === 'testids') {}
    }
  ]
}

More info