Storybook is an open source tool for building UI components and pages in isolation. It streamlines UI development, testing, and documentation.
Storybook for React offers functionality to control props from a very pretty ui.
We will explore these things in this post:
- Knobs vs Controls
- The good - React-docgen
- The bad - More words to type
- The solution
- Bonus - Snippets
In Storybook v6, the team released Essentials addons:
This was in alignment with Storybook's Zero-config initiative (which included out-of-box TS support, essentials addons, and extended support of more frameworks).
Knobs vs Controls
With this storybook migrated from Knobs in v5 to Controls in v5
Knobs
export const withAButton = () => (
<button disabled={boolean('Disabled', false)}>{text('Label', 'Hello Storybook')}</button>
);
Controls
export default {
title: 'Button',
component: Button,
argTypes: {
variant: {
options: ['primary', 'secondary'],
control: { type: 'radio' }
}
}
};
The good
With the controls, storybook can automatically detect props using react doc-gen, and can automatically generate all the controls for you.
The bad
For me, some of the controls were not automatically generated due to some of HOCs that we were using (I know, fixing HOCs can fix react docgen as well).
Also, in-case I want to add custom controls, or want to define controls on my own, then the syntax is a little bit more typing over Knobs syntax.
The Solution
Given the new controls syntax, and the ease of use of old Knobs functions, I ended up creating my own wrappers over new controls.
Wrappers
The approach looks like this:
export const select = <T extends any>(options: T[], defaultValue?: T, props: Partial<ArgProps> = {}) => {
const allProps: Partial<ReturnedArg<T>> = createControlFromProps<T>(props);
const type = props.type || 'select';
allProps.defaultValue = defaultValue || options[0];
allProps.control = { type, options };
return allProps;
};
So basically, I took input in knobs format, and returned in controls format.
Here is the full file with these controls:
- select
- boolean
- text
- number
- obj
- action
Usage
With this, the usage looks like:
const argTypes = getArgs<InputProps>({
label: text('Name'),
size: select(['small', 'medium', 'large']),
fullWidth: boolean (false),
onChange: action('change'),
});
Here is the full code with Input Stories:
Bonus - Snippets
An added bonus will be, create a snippet for a story, and next time have a story ready to be served with few key-strokes.
Top comments (0)