Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
@storybook/addon-contexts
Advanced tools
Storybook Addon Contexts is an addon for driving your components under dynamic contexts in Storybook.
Real world users expects your application being customizable, that is why often your components are polymorphic: they simply need to adapt themselves under different contextual environments. Imagine your components can speak Chinese, English, or even French, and they change their skin tone under dark or light theme. Yeah, you want to make sure a component look great in all scenario.
A good practice to write maintainable components is separate the presentation and its business logic. Storybook is a great place for exercising the visualization and interaction of your components, which may depend on some contexts. Often enough, you will find it become very tedious to wrap each component deeply with its contextual environments before you can really write the main story. You even start to write extra components or factory functions just to make your life easier. How about changing the context of your story dynamically?! There were simply having no good way so you ended up writing stories like an accountant.
That is why you need this. An elegant way to wrap your component stories and change their contextual environment directly and dynamically in Storybook UI! Kind of like a dependency injection, eh! The best bit is you define it once then apply it everywhere.
Make sure the version of your Storybook is above v5. For the full list the current supported framework, see Addon / Framework Support Table.
To get it started, add this package into your project:
yarn add -D @storybook/addon-contexts
Then, register the addon by adding the following line into your addon.js
file (you should be able to find the file
under the storybook config directory of your project):
import '@storybook/addon-contexts/register';
To load your contextual setups for your stories globally, adding the following lines into config.js
file (you should
see it near your addon.js
file):
import { addDecorator } from '@storybook/[framework]';
import { withContexts } from '@storybook/addon-contexts/[framework]';
import { contexts } from './configs/contexts'; // we will define the contextual setups later in API section
addDecorator(withContexts(contexts));
Alternatively, just like other addons, you can use this addon only for a given set of stories:
import { storiesOf } from '@storybook/[framework]';
import { withContexts } from '@storybook/addon-contexts/[framework]';
import { contexts } from './configs/contexts';
const story = storiesOf('Component With Contexts', module).addDecorator(withContexts(contexts)); // use this addon with a default contextual environment setups
Finally, you may want to modify the default setups at per story level. Here is how you can do this:
story.add(
() => {
/* some stories */
},
{
contexts: [
{
/* the modified setup goes here, sharing the same API signatures */
},
],
}
);
It is recommended to have a separate file for managing your contextual environment setups. Let's add a file named
contexts.js
first. Before diving into API details, here is an overview on the landscape. For example (in React),
to inject component theming contexts to both styled-components
and material-ui
theme providers in stories:
export const contexts = [
{
icon: 'box', // a icon displayed in the Storybook toolbar to control contextual props
title: 'Themes', // an unique name of a contextual environment
components: [
// an array of components that is going to be injected to wrap stories
/* Styled-components ThemeProvider, */
/* Material-ui ThemeProvider, */
],
params: [
// an array of params contains a set of predefined `props` for `components`
{ name: 'Light Theme', props: { theme /* : your dark theme */ } },
{ name: 'Dark Theme', props: { theme /* : your light theme */ }, default: true },
],
options: {
deep: true, // pass the `props` deeply into all wrapping components
disable: false, // disable this contextual environment completely
cancelable: false, // allow this contextual environment to be opt-out optionally in toolbar
},
},
/* ... */ // multiple contexts setups are supported
];
withContexts(contexts) : function
A decorating function for wrapping your stories under your predefined contexts
. This means multiple contextual
environments are supported. They are going to be loaded layer by layer and wraped in a descending oder (top -> down
-> story). The contexts
is an array of object that should has the following properties:
icon : string?
(default undefined
)
A icon displayed in the Storybook toolbar to control contextual props. This addon allows you to define an icon for each contextual environment individually. Take a look from what are currently supported icon lists from the official Storybook story. You must define an icon first if you want to take advantage on switching props dynamically in your Storybook toolbar.
title : string
(required)
An unique name of a contextual environment; if duplicated names provided, the later is going to be ignored.
components : (Component|string)[]
(required)
An array of components that is going to be injected to wrap stories. This means this addon allow multiple wrapping
components coexisted. The wrapping sequence is from the left to right (parent -> children -> story). This nested
wrapping behaviour can be useful in some cases; for instance, in the above example, we are wrapping stories under
styled-componnets
and material-ui
theme providers. Also, you can use this addon to wrap any valid HTML tags.
params : object[] | undefined
(default: undefined
)
An array of params contains a set of predefined props
for components
. This object has the following properties:
params.name : string
(required)
An unique name for representing the props.
params.props : object | null:
(required)
The props
that is accepted by the wrapping component(s).
params.defualt : true?
(default: undefined
)
Set to true
if you want to use this param initially. Only the first one marked as default is identified.
options
A set of options offers more granular control over the defined contextual environment. These properties can be overridden at the story level:
options.deep : boolean?
(default: false
)
Pass the props
deeply into all wrapping components. Useful when you want them all to be passed with the same props.
options.disable : boolean?
(default: false
)
Disable this contextual environment completely. Useful when you want to opt-out this context from a given story.
options.cancelable : boolean?
(default: false
)
Allow this contextual environment to be opt-out optionally in toolbar. When set to true
, an Off option will
be shown at first in the toolbar menu in your Storybook.
icon
, and params
can be just optional.{ contexts: [{ /* extra contexts */ }}
.params
can be "appended" into an existed setups at the story level too (make sure it goes with the
correct title
); however, they are never be able to overridden the default setups. So it is important to have
non-collided names.&contexts=[name of contexts]=[name of param]
in the URL under iframe mode. Use ,
to separate multiple contexts (e.g. &contexts=Theme=Forests,Language=Fr
).MIT
FAQs
Storybook Addon Contexts
The npm package @storybook/addon-contexts receives a total of 8,194 weekly downloads. As such, @storybook/addon-contexts popularity was classified as popular.
We found that @storybook/addon-contexts demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 18 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
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.