storybook
storybook copied to clipboard
Addon-controls: Add custom user-defined controls
We are currently documenting our React components in Storybook, and decided to go straight to version 6.0 to make use of the new Args and Controls addons. During that work, we realised that the choice of controls is very limited.
Here are some examples:
- We want users to select from a pre-defined list of colors. The
"select"
control can only display text but we want to preview the color next to it. - We want users to select from a list of icons. The control should display a list of all icons and clicking on an icon selects it.
- One prop may allow for
string[]
, so we want to allow the user to add strings to the list, or remove existing strings.
Any chance to allow users to specify custom controls in argTypes
that are not built into addon-controls
?
Here's how this could look like in React code, where ColorPicker
is a custom control we'd build:
const ColorPicker = ({ value, setValue }) => {
return (
<select value={value} onChange={setValue}>
<option>red</option>
<option>blue</option>
</select>
);
}
export default {
title: "ExampleComponent",
component: ExampleComponent,
argTypes: {
color: {
control: ColorPicker,
},
},
};
I'd be happy to start working on this. I'd like to add a gradient editor and rich text editor to my Storybook's controls without having to modify the core controls package.
One generic thing that would be good is nested controls. For arrays and tuples it is relatively simple (a tuple is a fixed length array) - in my use case I'd like to be able to have a [number, number]
that can get the normal range options on it. Object types would likely be a bit more complicated - though the current way of pasting some JSON is pretty good for most situations.
I've not looked at the source, but I feel that making the recognition and control both generic, so certain ones can try to identify then including user-defined controls that support it (the aforementioned array type might be useful etc)
Copying @ndelangen 's suggestion from another thread to make these user-defined controls lazy-loaded:
https://github.com/storybookjs/storybook/pull/12685#issuecomment-711761883
@stefanhamburger @hydrosquall @Rycochet @ryaninvents super excited to see ya'll helping 🙇
@shilman I'm concerned about:
export default {
title: "ExampleComponent",
component: ExampleComponent,
argTypes: {
color: {
control: ColorPicker,
},
},
};
If the actual control component is specified in the story (preview), but the control component itself is displayed in an addon (manager) aren't we opening ourselves up to a world of hurt?
Should we not do this instead:
// story
export default {
title: "ExampleComponent",
component: ExampleComponent,
argTypes: {
color: {
control: 'ControlColorPicker',
},
},
};
// some addon
addons.register('AddonControlsColorPicker', api => {
addons.add('AddonControlsColorPicker', {
type: addons.types.CONTROL,
render: ColorPicker,
}
})
@ndelangen I'm with you there - it's not so much a security thing, but being able to keep the definition and usage separate makes it easier to debug things. I do feel that it might be a little bit much for simple uses - but given a suitably "powerful" api for registering and using them it could probably reduce the need for actually doing things like that. Definitely needs a nice and simple example however it gets added so that people don't get confused over what to do, and what it can achieve ;-)
@ndelangen Yep, the user/addon needs to register a mapping from string to React component in both the preview and the manager, since the control will be rendered in both the addons panel AND in the docs page. The user would then reference that control by string in the argTypes annotation.
Strawman spec:
- [ ] Add control registration to addons API (both manager & preview)
- [ ] Convert built-in controls to use registration mechanism (then they can be overridden!)
- [ ] Create a sample custom control in
official-storybook
- [ ] Add to controls documentation
I'd be happy to assist in the creation of this
I'd love to see OTB support for this as well.
For objects rather than editing a json string what about some kind of recursive docgen driven form. The UX would be hard to fathom admittedly. My immediate thought is you could click an edit CTA (where the json string is today) and the whole form is replaced by the child object's fields, breadcrumbs could allow for navigating back to parent.
There are sophisticated form generation tools, like uniforms. For most of my needs, I'd like to be able to simply pass a configured Schema in for particular properties with deep data structures, and have that form open in a dialog or something similar.
One generic thing that would be good is nested controls.
I would also be interested in adding controls for args with nested properties.
@nathanielks yes, that has come up a few time in discussions!
In particular in combination with args being composed from other stories!
It would be really great to have custom control types. For example, I'd like to create a color control type for tailwindcss classes, specifically for color classes, so you can use a color-picker-style control type, but use tailwindcss classes.
What is holding this up? How can I help?
It sounds like a very nice feature to have, I'd love to help make this happen :)
We could use this too!
is there any update on this? Thank you
I'm keen for this too! Any new update?
I would love this as well1 +1
I would love to use it.
@shilman @ndelangen can y'all confirm if this is anywhere on the roadmap?
@adamlohner we'd love to add this but only after things are a lot more stable -- perhaps 7.x-8.0 timeframe.
It's been more than two years, and this is a very common need... How long is it gonna take?
I'd appreciate this feature, I think you should just open this up for us.
just let us straight register components to be used as controls, I'm writing a Vue app, but I'd gladly do some react like it's 2018 if that was supported 😛
Give me this! We have a big component library now with models of varying complexity and the simple controls just don't cut it.
I'm surprised it's not yet something you can do in storybook! Definitely worth bumping priority up on.
What is it with the entitledness in the comments? If you want this functionality, create a PR that adds it or create your own custom controls addon.
@i-am-the-slime idk about you but my company is def not paying me to build out storybook
@i-am-the-slime with all due respect, some people don't want to have to learn how addons work, then understand how the controls addon works internally, then change it to allow for custom controls, then go through the process of a PR
I've gathered a dirty workaround while #21566 is on the way.
This just injects invokable button to the controls.
I might be able to generalize the implementation to add any custom controls and publish proper addon package if there is enough demand.