storybook icon indicating copy to clipboard operation
storybook copied to clipboard

Addon-controls: Add custom user-defined controls

Open stefanhamburger opened this issue 4 years ago • 26 comments

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,
    },
  },
};

stefanhamburger avatar Jul 09 '20 17:07 stefanhamburger

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.

ryaninvents avatar Aug 12 '20 15:08 ryaninvents

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)

Rycochet avatar Sep 07 '20 15:09 Rycochet

Copying @ndelangen 's suggestion from another thread to make these user-defined controls lazy-loaded:

https://github.com/storybookjs/storybook/pull/12685#issuecomment-711761883

hydrosquall avatar Oct 19 '20 22:10 hydrosquall

@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 avatar Oct 20 '20 07:10 ndelangen

@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 ;-)

Rycochet avatar Oct 20 '20 08:10 Rycochet

@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.

shilman avatar Oct 20 '20 08:10 shilman

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

shilman avatar Oct 22 '20 01:10 shilman

I'd be happy to assist in the creation of this

ndelangen avatar Oct 22 '20 11:10 ndelangen

I'd love to see OTB support for this as well.

savgrace avatar Jan 06 '21 23:01 savgrace

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.

stubar avatar Jan 07 '21 22:01 stubar

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.

CaptainN avatar Feb 25 '21 22:02 CaptainN

One generic thing that would be good is nested controls.

I would also be interested in adding controls for args with nested properties.

nathanielks avatar Apr 30 '21 20:04 nathanielks

@nathanielks yes, that has come up a few time in discussions!

In particular in combination with args being composed from other stories!

ndelangen avatar May 03 '21 08:05 ndelangen

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?

davidpfahler avatar May 15 '21 16:05 davidpfahler

It sounds like a very nice feature to have, I'd love to help make this happen :)

lvndry avatar Sep 09 '21 09:09 lvndry

We could use this too!

jsduffy avatar Oct 13 '21 15:10 jsduffy

is there any update on this? Thank you

WebTerminator avatar Oct 26 '21 12:10 WebTerminator

I'm keen for this too! Any new update?

harleyharl avatar Dec 16 '21 23:12 harleyharl

I would love this as well1 +1

markrocks avatar Dec 17 '21 04:12 markrocks

I would love to use it.

gereltod-g avatar Mar 09 '22 10:03 gereltod-g

@shilman @ndelangen can y'all confirm if this is anywhere on the roadmap?

adamlohner avatar May 11 '22 16:05 adamlohner

@adamlohner we'd love to add this but only after things are a lot more stable -- perhaps 7.x-8.0 timeframe.

shilman avatar May 18 '22 13:05 shilman

It's been more than two years, and this is a very common need... How long is it gonna take?

franktopel avatar Aug 04 '22 13:08 franktopel

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 😛

Klowes avatar Sep 21 '22 10:09 Klowes

Give me this! We have a big component library now with models of varying complexity and the simple controls just don't cut it.

cmcnicholas avatar Oct 14 '22 15:10 cmcnicholas

I'm surprised it's not yet something you can do in storybook! Definitely worth bumping priority up on.

pseudotsuga-fir avatar Oct 19 '22 00:10 pseudotsuga-fir

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 avatar Nov 05 '22 13:11 i-am-the-slime

@i-am-the-slime idk about you but my company is def not paying me to build out storybook

Klowes avatar Nov 06 '22 03:11 Klowes

@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

GideonMax avatar Jan 08 '23 14:01 GideonMax

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.

zb-sj avatar May 24 '23 01:05 zb-sj