Skip to content
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: Document dynamic source snippets #12530

Merged
merged 2 commits into from
Sep 24, 2020
Merged

Conversation

shilman
Copy link
Member

@shilman shilman commented Sep 21, 2020

Issue: N/A

What I did

Document dynamic source snippets

  • For users
  • For framework developers

Related #11588 #11400 #8672

How to test

N/A

@shilman shilman added documentation patch:yes Bugfix & documentation PR that need to be picked to main branch labels Sep 21, 2020
@shilman shilman added this to the 6.1 docs milestone Sep 21, 2020
Copy link
Contributor

@jonniebigodes jonniebigodes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shilman sorry for taking a bit longer in taking a look at the pull request. I've left a comment regarding this pull request, let me know if you're ok with it, or if we need to adjust the wording a bit more.

Thanks in advance

Comment on lines 107 to 147
## Dynamic source rendering

Starting in 6.0 there are several modes of rendering stories in the [Source doc block](https://storybook.js.org/docs/react/writing-docs/doc-blocks#source). The `dynamic` source type renders a snippet based on the output of a story function. For example React
s `dynamic` snippets are JSX reconstructed based on the React node.

Since this dynamic rendering is framework-specific, it must be added to each framework. Here we dissect the React framework implementation as a reference for implementing this feature in other frameworks.

Here are the key lines of the [React preview config](https://github.com/storybookjs/storybook/blob/next/addons/docs/src/frameworks/react/config.ts):

```ts
import { jsxDecorator } from './jsxDecorator';
export const decorators = [jsxDecorator];
```

This function gets run on every story. Diving into [its implementation](https://github.com/storybookjs/storybook/blob/next/addons/docs/src/frameworks/react/jsxDecorator.tsx):

```ts
import { addons, StoryContext } from '@storybook/addons';
import { SNIPPET_RENDERED } from '../../shared';

export const jsxDecorator = (storyFn: any, context: StoryContext) => {
const story = storyFn();

// We only need to render JSX if the source block is actually going to
// consume it. Otherwise it's just slowing us down.
if (skipJsxRender(context)) {
return story;
}

const channel = addons.getChannel();

const options = {}; // retrieve from story parameters
const jsx = renderJsx(story, options);
channel.emit(SNIPPET_RENDERED, (context || {}).id, jsx);

return story;
};
```

The `renderJsx` function is a react-specific function that takes the output of a story function and converts it into a framework-appropriate string. The resulting value is emitted on Storybook's channel and subsequently consumed up by the Source block for that story, if one exists.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shilman we have room for improvements here we could probably go with something along these lines:

## Dynamic source rendering

With the release of Storybook 6.0, we've improved how stories are rendered in the [Source doc block](https://storybook.js.org/docs/react/writing-docs/doc-blocks#source). One of such improvements is the `dynamic` source type, which renders a snippet based on the output the story function. 

Before we take a look at a concrete example, we would like to remind you that this is framework-specific and you'll need to make the necessary adjustments depending on which framework you're working with.

With that out of the way, let's take a look on how the `dynamic` snippets work with React:

// addons/docs/src/frameworks/jsxDecorator.tsx code example

Taking a closer look at the code snippet above, a couple of things worth mentioning:

- The **renderJsx** function call, as it's responsible for transforming the output of a story function into a string specific to the framework (in this case React).
- The returned value of the function above is emitted on Storybook's channel through **channel.emit()** and subsequently consumed up by the Source block for any given story, if it exists.

<div class="aside">
 If you want to learn more and see how it's implemented take a look <a href="https://github.com/storybookjs/storybook/blob/next/addons/docs/src/frameworks/react/jsxDecorator.tsx">here</a> .
</div>

Now we'll need a way to configure how it's displayed in the UI. You can use a similar approach to the one below to achieve it:

// addons/docs/src/frameworks/react/config.ts code example

<div class="aside">
For brevity purposes we've only included the relevant information. Take a look <a href="https://github.com/storybookjs/storybook/blob/next/addons/docs/src/frameworks/react/config.ts">here</a> for the full implementation.
</div>

We would like to point out that the `jsxDecorator` function will be executed for each story.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jonniebigodes ! I've updated it to the new structure, with a few tweaks

@shilman shilman merged commit 98aea49 into next Sep 24, 2020
@shilman shilman deleted the docs/dynamic-source-snippets branch September 24, 2020 07:48
shilman added a commit that referenced this pull request Oct 22, 2020
Addon-docs: Document dynamic source snippets
@shilman shilman added the patch:done Patch/release PRs already cherry-picked to main/release branch label Oct 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation patch:done Patch/release PRs already cherry-picked to main/release branch patch:yes Bugfix & documentation PR that need to be picked to main branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants