storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.55k stars 9.3k forks source link

[Feature Request]: Make it possible to disable `forceInitialArgs` in autodocs to make all stories fully interactive #22195

Open JReinhold opened 1 year ago

JReinhold commented 1 year ago

Context

In 7.0 we made the list of stories in default autodocs not react to changes to args, for a couple of reasons:

  1. autodocs now show the primary story twice, above the controls, and in the list below. If they are all dynamic with args, changing the controls will mean that both instances of the primary story changes, which can cause confusion and is probably not what you want.
  2. making changes to stories in canvas mode will affect the stories in docs mode too.

overall, the intended experience of autodocs is to show off stories in their default/initial state, which requires that we always force args to stay at the initial state.

The Problem

This has the unfortunate consequence, that if your story state is completely controlled by args (via useArgs in render), then the story will be completely non-interactive. This is a common pattern for controlled components where the consumer of the component is in charge of managing the state. In such a case it's a nice experience to make the state controlled/synced with args, so they are easy to manipulate with controls. However if you do that, the state becomes immutable in autodocs.

Another simpler problem, is that if you want a docs page where Controls controls another story than the primary, you can't just use a custom <Controls of={StoryToControl} />, because the stories in Stories won't react to that. You'd also have to re-implement <Stories />, to unset forceInitialArgs.

Describe the solution you'd like

I suggest we:

  1. Make the forceInitialArgs property public, by:
    1. renaming it from __forceInitialArgs to forceInitialArgs in all the blocks that use it
    2. document it
  2. Add the property to the Stories block, so you can more easily override the default DocsPage. Currently a user would have to both override the DocsPage and re-implement Stories to disable it.

Additionally we could also make it a property on docs parameters, so users don't even need to override docs page, but just to set the parameter. It seems good for a DX perspective, but I'm also afraid of bloating the API with a fairly limited use case. I would suggest it to be parameters.docs.stories.forceInitialArgs = Boolean

We should be sure to describe the pitfalls of disabling forceInitialArgs in documentation, and describe why it might not be desirable.

Are you able to assist to bring the feature to reality?

yes, I can

Additional context

Two Discord discussions on the topic:

https://discord.com/channels/486522875931656193/1096279480504434881/1096279480504434881

https://discord.com/channels/486522875931656193/1098422563417379007/1098422563417379007

tmeasday commented 1 year ago

OK, yes, I think making it overrideable by a prop, and thus a parameter makes sense.

Keep in mind that you can only have one set of args values for any story, even if you render it more than once, which I suspect means that when you render a dynamic story that uses useArgs twice, weird things are likely to happen.

nitin-pandita commented 1 year ago

@JReinhold I am up for it ,can you assign