-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addon-docs: Exclude decorators in dynamic source snippets #14652
Addon-docs: Exclude decorators in dynamic source snippets #14652
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @lauracarballo, thanks for the fix! However, I'm a little unclear on how it will work when the component needs contexts provided by the decorators, such as i18n or theme.
One more wrinkle. A story function can contain arbitrary JSX, but this only shows the |
Hi @shilman, thanks for reviewing the PR. I've updated the cra-kitchen-sink with an example including decorators to showcase what's being solved in this PR in a better way. Currently decorators are being included inside the code snippet. To my understanding decorators should not be appearing inside the source code snippet since they are something "external" to the original component. For example: With the fix provided, the This way we end up rendering a story that includes decorators in the Canvas and Doc Blocks but does not include them in the source code snippet. |
Hi @ndelangen, thanks for your reply and for having a look at my PR. The 2 stories added in export const Basic = () => <Button onClick={action('clicked', { depth: 1 })}>Basic</Button>; Args story: export const WithArgs = (args) => <Button {...args} />;
WithArgs.args = { onClick: action('clicked', { depth: 1 }), children: 'With args' }; According to DocsPage documentation when
And otherwise, if not an Args story it will render using This is why the What I'm attempting to fix in this PR is that currently the Args stories code snippets are broken when adding decorators as mentioned in this issue (#12022). Thanks again for reviewing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following up on my previous comment, I did a little testing on this branch. This is a fantastic start, but the solution will be a little more involved.
From what I can tell, if a StoryFn relies some context, such as themes provided by a decorator:
ReactDOM.render(<StoryFn />)
needs decorators/context<StoryFn />
doesn't need them
This means that we can render JSX for the component without decorators even when we can't render the component, which is great news!
However, this PR as it stands is only accurate when the user's story function is:
const Template = (args) => <Component {...args} />
This is the most common case, but there are plenty of times when this is not the case. For example, it's also common to show compositions of components in a story:
export const Empty = (args) => <List {...args} />;
export const ManyItems = (args) => (
<List {...args}>
<ListItem />
<ListItem />
<ListItem />
</List>
);
The first story would render correctly with the changes in this PR but the second story wouldn't.
I think the solution is to render the undecorated story function, which we happen to keep around in the story store. Unfortunately, it's currently not available in the StoryContext at render time.
So I'd like to see a few changes to this:
- Make the undecorated story function available in the story context
- Render JSX from the undecorated story function instead of from the synthetic
<Component {...args />
function - Make this feature either opt-in or opt-out using a story parameter, because I think there are cases where people WANT to see the decorated story. For example, if my story needs a React.Context to work, I might want to show that in the code sample.
I'm happy to help make these changes. What do you think?
Thanks a lot for reviewing. Your solution seems great, I was hesitant to add extra data to the context but having your feedback it seems like the best place to access the original story. I'm looking into this, I'll get back to you if I need any extra help. Thanks for the detailed write up and tasks. |
Awesome @lauracarballo 💯 -- please ask any q's here or feel free to grab me or any of the maintainers (@ndelangen @tmeasday etc.) on Discord https://discord.gg/storybook. This is going to be really great. |
Hey, I’m also looking into issue #12022 and from what I gather So I don’t understand why re-ordering |
96cafbc
to
cda9cb9
Compare
Nx Cloud ReportCI ran the following commands for commit a5c667f. Click to see the status, the terminal output, and the build insights. 📂 See all runs for this branch
Sent with 💌 from NxCloud. |
Hi @shilman, sorry for the delay in the response. I've made updated on the PR based on your previous feedback :) I have added the Thanks for your patience and guidance |
Hi @lauracarballo thanks so much for following up, this is looking great! How about making it opt-out just to be on the safe side, with
Since parameters cascade, you could opt-in to this feature globally with one line in What do you think? Storybook 6.3 is going into beta tomorrow, so it would be great if we could wrap this up this week. Happy to do whatever it takes to help get this over the line! |
Hi @shilman, thanks for the quick response :) I have updated the PR to make it opt-in and opt-out using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome!!! 💯 x 💯
@lauracarballo one additional thing if you're ok with it. If you could jump into our Discord server and message me (same username), I wanted to follow up with you on this pull request. |
Hi @jonniebigodes, I messaged you on Discord already. Thanks :) |
Hi @shilman sorry to revive this thread, but I was curious if this |
Issues: #12022 #11542
What I did
The dynamic code snippet is generated by a decorator called
jsxDecorator
which is included inkindMetadata.decorators
.This decorator runs after the story decorators provided by the developer, which normally include i18n providers, data fetching or visual styling that shouldn't be shown in the code snippet.
The order of the decorators can be seen here:
https://github.com/storybookjs/storybook/blob/next/lib/client-api/src/story_store.ts#L379
Re-ordering the decorators would be the easiest solution, but that seems like it would be breaking change to library due to some addons possibly expecting the output of story decorators.
So, to bypass the story decorators, the solution myself and @jamesb3ll came up with is to use the
component
from the story context. If the developer has provided a component we can construct the JSX element usingReact.createElement
together with theargs
as the props. That component is then converted to readable code string using thereact-element-to-jsx-string
library.We've updated the tests to reflect this, any feedback on this solution would be great.