Categories
Storybook for React

Storybook for React — Globals and Addons and Stories

Spread the love

Storybook lets us prototype components easily with various parameters.

In this article, we’ll look at how to work with globals with Storybook.

Consuming Globals within a Story

We can consume globals inside a story.

To do that, we get the globals property from the story function.

For example, we can write:

.storybook/preview.js

export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'locale',
    defaultValue: 'en',
    toolbar: {
      icon: 'globe',
      items: [
        { value: 'en', right: '??', title: 'English' },
        { value: 'fr', right: '??', title: 'Français' },
        { value: 'zh', right: '??', title: '中文' },
      ],
    },
  },
};

src/stories/Button.stories.js

import React from 'react';

import { Button } from './Button';

export default {
  title: 'Example/Button',
  component: Button,
  argTypes: {
    backgroundColor: { control: 'color' },
  },
};

const getCaptionForLocale = (locale) => {
  switch (locale) {
    case 'en': return 'Hello';
    case 'fr': return 'Bonjour';
    case 'zh': return '你好';
    default:
      return 'Hello'
  }
}

const Template = (args, { globals: { locale } }) => <Button {...{ ...args, label: getCaptionForLocale(locale) }} />;

We defined the locale global variable with the .storybook/preview.js file.

Then in the src/stories/Button.stories.js file, we get the locale global property with the globals.locale property of the parameter.

The right property is the text that’s displayed on the right side in the toolbar menu when we connect it to a decorator.

Consuming Globals within an Addon

We can consume globals within an addon file.

For example, we can write:

import React from 'react';
import { useGlobals } from '@storybook/api';
import { addons, types } from '@storybook/addons';
import { AddonPanel, Spaced, Title } from '@storybook/components';

const LocalePanel = props => {
  const [{ locale }] = useGlobals();

  return (
    <>
      <style>
        {`
        #panel-tab-content > div > div[hidden] {
          display: flex !important
        }
      `}
      </style>
      <AddonPanel {...props}>
        <Spaced row={3} outer={1}>
          <Title>{locale}</Title>
        </Spaced>
      </AddonPanel>
    </>
  );
};

const ADDON_ID = 'locale-panel';
const PANEL_ID = `${ADDON_ID}/panel`;

addons.register(ADDON_ID, (api) => {
  addons.add(PANEL_ID, {
    type: types.PANEL,
    title: 'Locale',
    render: ({ active, key }) => {
      return <AddonPanel active={active} key={key}>
        <LocalePanel />
      </AddonPanel>
    },
  });
});

to add an addon and get the global property with the useGlobal hook.

We use the AddonPanel , Spaced , and Title properties to show the content inside the addon panel.

The addons.register method register the addon so that it’ll be shown in the Storybook’s addon panel.

Also, we have the AddonPanel to render the panel.

We make it show when we display the panel with the style tag.

Story Rendering

We can change how our stories are rendered.

To add to the head tag, we add HTML code to the .storybook/preview-head.html file:

<link rel="stylesheet"
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
    integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
    crossorigin="anonymous">

Then they’ll be shown in the head tag inside the iframe.

Conclusion

We can add our own addons panel with Storybook.

Also, we can add tags inside the head tag in the iframe.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *