UNPKG

7.82 kBMarkdownView Raw
1# Storybook Controls Addon
2
3[Storybook](https://storybook.js.org) Controls gives you a graphical UI to interact with a component's arguments dynamically, without needing to code. It creates an addon panel next to your component examples ("stories"), so you can edit them live.
4
5[Framework Support](https://storybook.js.org/docs/react/api/frameworks-feature-support)
6
7![Screenshot](https://raw.githubusercontent.com/storybookjs/storybook/next/addons/controls/docs/media/addon-controls-hero.gif)
8
9## Installation
10
11Controls is part of [essentials](https://storybook.js.org/docs/react/essentials/introduction) and so is installed in all new Storybooks by default. If you need to add it to your Storybook, you can run:
12
13```sh
14npm i -D @storybook/addon-controls
15```
16
17Then, add following content to [`.storybook/main.js`](https://storybook.js.org/docs/react/configure/overview#configure-your-storybook-project):
18
19```js
20module.exports = {
21 addons: ['@storybook/addon-controls'],
22};
23```
24
25## Usage
26
27The usage is documented in the [documentation](https://storybook.js.org/docs/react/essentials/controls).
28
29## FAQs
30
31- [Storybook Controls Addon](#storybook-controls-addon)
32 - [Installation](#installation)
33 - [Usage](#usage)
34 - [FAQs](#faqs)
35 - [How will this replace addon-knobs?](#how-will-this-replace-addon-knobs)
36 - [How do I migrate from addon-knobs?](#how-do-i-migrate-from-addon-knobs)
37 - [My controls aren't being auto-generated. What should I do?](#my-controls-arent-being-auto-generated-what-should-i-do)
38 - [How can I disable controls for certain fields on a particular story?](#how-can-i-disable-controls-for-certain-fields-on-a-particular-story)
39 - [How do controls work with MDX?](#how-do-controls-work-with-mdx)
40
41### How will this replace addon-knobs?
42
43Addon-knobs is one of Storybook's most popular addons with over 1M weekly downloads, so we know lots of users will be affected by this change. Knobs is also a mature addon, with various options that are not available in addon-controls.
44
45Therefore, rather than deprecating addon-knobs immediately, we will continue to release knobs with the Storybook core distribution until 7.0. This will give us time to improve Controls based on user feedback, and also give knobs users ample time to migrate.
46
47If you are somehow tied to knobs or prefer the knobs interface, we are happy to take on maintainers for the knobs project. If this interests you, hop on our [Discord](https://discord.gg/storybook).
48
49### How do I migrate from addon-knobs?
50
51If you're already using [Storybook Knobs](https://github.com/storybookjs/addon-knobs) you should consider migrating to Controls.
52
53You're probably using it for something that can be satisfied by one of the cases [described above](#writing-stories).
54
55Let's walk through two examples: migrating [knobs to auto-generated args](#knobs-to-custom-args) and [knobs to custom args](#knobs-to-custom-args).
56
57<h4>Knobs to auto-generated args</h4>
58
59First, let's consider a knobs version of a basic story that fills in the props for a component:
60
61```jsx
62import { text } from '@storybook/addon-knobs';
63import { Button } from './Button';
64
65export const Basic = () => <Button label={text('Label', 'hello')} />;
66```
67
68This fills in the Button's label based on a knob, which is exactly the [auto-generated](#auto-generated-args) use case above. So we can rewrite it using auto-generated args:
69
70```jsx
71export const Basic = (args) => <Button {...args} />;
72Basic.args = { label: 'hello' };
73```
74
75<h4>Knobs to manually-configured args</h4>
76
77Similarly, we can also consider a story that uses knob inputs to change its behavior:
78
79```jsx
80import { number, text } from '@storybook/addon-knobs';
81
82export const Reflow = () => {
83 const count = number('Count', 10, { min: 0, max: 100, range: true });
84 const label = text('Label', 'reflow');
85 return (
86 <>
87 {[...Array(count)].map((_, i) => (
88 <Button key={i} label={`button ${i}`} />
89 ))}
90 </>
91 );
92};
93```
94
95And again, as above, this can be rewritten using [fully custom args](https://storybook.js.org/docs/react/essentials/controls#fully-custom-args):
96
97```jsx
98export const Reflow = ({ count, label, ...args }) => (
99 <>
100 {[...Array(count)].map((_, i) => (
101 <Button key={i} label={`${label} ${i}`} {...args} />
102 ))}
103 </>
104);
105
106Reflow.args = {
107 count: 3,
108 label: 'reflow',
109};
110
111Reflow.argTypes = {
112 count: {
113 control: {
114 type: 'range',
115 min: 0,
116 max: 20,
117 },
118 },
119};
120```
121
122### My controls aren't being auto-generated. What should I do?
123
124There are a few known cases where controls can't be auto-generated:
125
126- You're using a framework for which automatic generation [isn't supported](https://storybook.js.org/docs/react/api/frameworks-feature-support)
127- You're trying to generate controls for a component defined in an external library
128
129With a little manual work you can still use controls in such cases. Consider the following example:
130
131```js
132import { Button } from 'some-external-library';
133
134export default {
135 title: 'Button',
136 argTypes: {
137 label: { control: 'text' },
138 borderWidth: { control: { type: 'number', min: 0, max: 10 } },
139 },
140};
141
142export const Basic = (args) => <Button {...args} />;
143
144Basic.args = {
145 label: 'hello',
146 borderWidth: 1,
147};
148```
149
150The `argTypes` annotation (which can also be applied to individual stories if needed), gives Storybook the hints it needs to generate controls in these unsupported cases. See [control annotations](https://storybook.js.org/docs/react/essentials/controls#annotation) for a full list of control types.
151
152It's also possible that your Storybook is misconfigured. If you think this might be the case, please search through Storybook's [Github issues](https://github.com/storybookjs/storybook/issues), and file a new issue if you don't find one that matches your use case.
153
154### How can I disable controls for certain fields on a particular story?
155
156The `argTypes` annotation can be used to hide controls for a particular row, or even hide rows.
157
158Suppose you have a `Button` component with `borderWidth` and `label` properties (auto-generated or otherwise) and you want to hide the `borderWidth` row completely and disable controls for the `label` row on a specific story. Here's how you'd do that:
159
160```js
161import { Button } from 'button';
162
163export default {
164 title: 'Button',
165 component: Button,
166};
167
168export const CustomControls = (args) => <Button {...args} />;
169CustomControls.argTypes = {
170 borderWidth: { table: { disable: true } },
171 label: { control: { disable: true } },
172};
173```
174
175Like [story parameters](https://storybook.js.org/docs/react/writing-stories/parameters), `args` and `argTypes` annotations are hierarchically merged, so story-level annotations overwrite component-level annotations.
176
177### How do controls work with MDX?
178
179MDX compiles to component story format (CSF) under the hood, so there's a direct mapping for every example above using the `args` and `argTypes` props.
180
181Consider this example in CSF:
182
183```js
184import { Button } from './Button';
185export default {
186 title: 'Button',
187 component: Button,
188 argTypes: {
189 background: { control: 'color' },
190 },
191};
192
193const Template = (args) => <Button {...args} />;
194export const Basic = Template.bind({});
195Basic.args = { label: 'hello', background: '#ff0' };
196```
197
198Here's the MDX equivalent:
199
200```jsx
201import { Meta, Story } from '@storybook/addon-docs';
202import { Button } from './Button';
203
204<Meta title="Button" component={Button} argTypes={{ background: { control: 'color' } }} />
205
206export const Template = (args) => <Button {...args} />
207
208<Story name="Basic" args={{ label: 'hello', background: '#ff0' }}>
209 {Template.bind({})}
210</Story>
211```
212
213For more info, see a full [Controls example in MDX for Vue](https://raw.githubusercontent.com/storybookjs/storybook/next/examples/vue-kitchen-sink/src/stories/addon-controls.stories.mdx).