Security News
TC39 Advances 10+ ECMAScript Proposals: Key Features to Watch
TC39 is meeting in Tokyo this week and they have approved nearly a dozen proposals to advance to the next stages.
@storybook/addon-toolbars
Advanced tools
The @storybook/addon-toolbars package allows developers to add custom toolbars to their Storybook UI. These toolbars can be used to control various aspects of the stories being displayed, such as themes, locales, or any other context that might need to be adjusted dynamically. It enhances the development experience by providing a more interactive and customizable environment for testing UI components.
Global Toolbars
This feature allows you to add global toolbars that affect all stories. In the code sample, a global 'Theme' toolbar is defined with 'light', 'dark', and 'custom' options.
export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
items: ['light', 'dark', 'custom'],
showName: true,
},
},
};
Story-Specific Toolbars
This feature allows you to use toolbars to control story-specific parameters. The code sample shows a decorator that wraps the story in a ThemeProvider, which uses the global 'theme' parameter set by the toolbar.
export const decorators = [
(Story, context) => (
<ThemeProvider theme={context.globals.theme}>
<Story />
</ThemeProvider>
),
];
The @storybook/addon-knobs package allows developers to add UI controls to tweak the component props in real-time. It is similar to @storybook/addon-toolbars in that it provides a way to dynamically adjust the presentation of components, but it focuses more on component props rather than global contexts.
The @storybook/addon-controls package is a successor to @storybook/addon-knobs. It automatically generates controls based on component properties and provides a more integrated and less manual approach compared to @storybook/addon-toolbars, which is more about setting global contexts.
The @storybook/addon-contexts package allows you to provide contextual data to your stories, such as themes or internationalization. It is similar to @storybook/addon-toolbars in that it can be used to switch contexts, but it does so through a different UI approach, using a panel rather than a toolbar.
The Toolbars addon controls global story rendering options from Storybook's toolbar UI. It's a general purpose addon that can be used to:
Toolbars is built on top of Storybook Args (SB6.0+): dynamic variables that trigger a story re-render when they are set.
To get started with addon-toolbars
:
First, install the package:
npm install @storybook/addon-toolbars -D # or yarn
Then add it to your .storybook/main.js
config:
module.exports = {
addons: ['@storybook/addon-toolbars'],
};
Addon-toolbars has a simple, declarative syntax for configuring toolbar menus. You can add toolbars by adding globalTypes
with a toolbar
annotation, in .storybook/preview.js
:
export const globalTypes = {
theme: {
name: 'Theme'
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
// array of plain string values or MenuItem shape (see below)
items: ['light', 'dark'],
},
},
};
You should see a dropdown in your toolbar with options light
and dark
.
Now, let's wire it up! We can consume our new theme
global arg in a decorator using the context.globals.theme
value.
For example, suppose you are using styled-components
. You can add a theme provider decorator to your .storybook/preview.js
config:
import { ThemeProvider } from 'styled-components';
import { StoryContext, StoryGetter, StoryWrapper } from '@storybook/addons';
const withThemeProvider: StoryWrapper = (Story: StoryGetter, context: StoryContext) => {
// context.globals.theme here will be either 'light' or 'dark'
// getTheme being a function retrieving the actual theme object from that value
const theme = getTheme(context.globals.theme);
return (
<ThemeProvider theme={theme}>
<Story {...context} />
</ThemeProvider>
);
};
export const decorators = [withThemeProvider];
The previous section shows the common case. There are two advanced use cases: (1) advanced menu configurations, (2) consuming global args inside a story.
The default menu configuration is simple: everything's a string! However, the Toolbars addon also support configuration options to tweak the appearance of the menu:
type MenuItem {
/**
* The string value of the menu that gets set in the global args
*/
value: string,
/**
* The main text of the title
*/
title: string,
/**
* A string that gets shown in left side of the menu, if set
*/
left?: string,
/**
* A string that gets shown in right side of the menu, if set
*/
right?: string,
/**
* An icon that gets shown in the toolbar if this item is selected
*/
icon?: icon,
}
Thus if you want to show right-justified flags for an internationalization locale, you might set up the following configuration in .storybook/preview.js
:
export const globalTypes = {
locale: {
name: 'Locale',
description: 'Internationalization locale',
defaultValue: 'en',
toolbar: {
icon: 'globe',
items: [
{ value: 'en', right: '🇺🇸', title: 'English' },
{ value: 'fr', right: '🇫🇷', title: 'Français' },
{ value: 'es', right: '🇪🇸', title: 'Español' },
{ value: 'zh', right: '🇨🇳', title: '中文' },
{ value: 'kr', right: '🇰🇷', title: '한국어' },
],
},
},
};
The recommended usage, as shown in the examples above, is to consume global args from within a decorator and implement a global setting that applies to all stories. But sometimes it's useful to use toolbar options inside individual stories.
Storybook's globals
are available via the story context:
const getCaptionForLocale = (locale) => {
switch(locale) {
case 'es': return 'Hola!';
case 'fr': return 'Bonjour!';
case 'kr': return '안녕하세요!';
case 'zh': return '你好!';
default:
return 'Hello!',
}
}
export const StoryWithLocale = (args, { globals: { locale } }) => {
const caption = getCaptionForLocale(locale);
return <>{caption}</>;
};
NOTE: In Storybook 6.0, if you set the global option passArgsFirst: false
for backwards compatibility, the story context is passes as the second argument:
export const StoryWithLocale = ({ globals: { locale } }) => {
const caption = getCaptionForLocale(locale);
return <>{caption}</>;
};
There is a hook available in @storybook/api
to retrieve the global args: useGlobals()
Following the previous example of the ThemeProvider, if you want for instance to display the current theme inside a Panel:
import { useGlobals } from '@storybook/api';
import { AddonPanel, Placeholder, Separator, Source, Spaced, Title } from '@storybook/components';
const ThemePanel = props => {
const [{ theme: themeName }] = useGlobals();
const theme = getTheme(themeName);
return (
<AddonPanel {...props}>
{theme ? (
<Spaced row={3} outer={1}>
<Title>{theme.name}</Title>
<p>The full theme object/p>
<Source code={JSON.stringify(theme, null, 2)} language="js" copyable padded showLineNumbers />
</Spaced>
) : (
<Placeholder>No theme selected</Placeholder>
)}
</AddonPanel>
);
};
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, in Storybook Docs, or even in other addons.
addon-toolbars
is compatible with React, Vue, Angular, etc. out of the box with no framework logic needed in the addon.FAQs
Create your own toolbar items that control story rendering
We found that @storybook/addon-toolbars demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
TC39 is meeting in Tokyo this week and they have approved nearly a dozen proposals to advance to the next stages.
Security News
Our threat research team breaks down two malicious npm packages designed to exploit developer trust, steal your data, and destroy data on your machine.
Security News
A senior white house official is urging insurers to stop covering ransomware payments, indicating possible stricter regulations to deter cybercrime.