Skip to content

Commit

Permalink
Merge pull request #15071 from storybookjs/11542-docs-mdx-source-rend…
Browse files Browse the repository at this point in the history
…ering

Addon-docs: Fix MDX source rendering
  • Loading branch information
shilman authored May 28, 2021
2 parents a454718 + d951eec commit 60b7bd9
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
20 changes: 20 additions & 0 deletions addons/docs/src/frameworks/react/jsxDecorator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,24 @@ describe('jsxDecorator', () => {
jsxDecorator(storyFn, context);
expect(transformSource).toHaveBeenCalledWith('<div>\n args story\n</div>', context);
});

it('renders MDX properly', () => {
// FIXME: generate this from actual MDX
const mdxElement = {
type: { displayName: 'MDXCreateElement' },
props: {
mdxType: 'div',
originalType: 'div',
className: 'foo',
},
};

jsxDecorator(() => mdxElement, makeContext('mdx-args', { __isArgsStory: true }, {}));

expect(mockChannel.emit).toHaveBeenCalledWith(
SNIPPET_RENDERED,
'jsx-test--mdx-args',
'<div className="foo" />'
);
});
});
19 changes: 17 additions & 2 deletions addons/docs/src/frameworks/react/jsxDecorator.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { createElement, ReactElement } from 'react';
import reactElementToJSXString, { Options } from 'react-element-to-jsx-string';
import dedent from 'ts-dedent';
import deprecate from 'util-deprecate';
Expand Down Expand Up @@ -150,6 +150,19 @@ export const skipJsxRender = (context: StoryContext) => {
return !isArgsStory || sourceParams?.code || sourceParams?.type === SourceType.CODE;
};

const isMdx = (node: any) => node.type?.displayName === 'MDXCreateElement' && !!node.props?.mdxType;

const mdxToJsx = (node: any) => {
if (!isMdx(node)) return node;
const { mdxType, originalType, children, ...rest } = node.props;
let jsxChildren = [] as ReactElement[];
if (children) {
const array = Array.isArray(children) ? children : [children];
jsxChildren = array.map(mdxToJsx);
}
return createElement(originalType, rest, ...jsxChildren);
};

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

Expand All @@ -167,10 +180,12 @@ export const jsxDecorator = (storyFn: any, context: StoryContext) => {
} as Required<JSXOptions>;

// Exclude decorators from source code snippet by default
const sourceJsx = context?.parameters.docs?.source?.excludeDecorators
const storyJsx = context?.parameters.docs?.source?.excludeDecorators
? context.originalStoryFn(context.args)
: story;

const sourceJsx = mdxToJsx(storyJsx);

let jsx = '';
const rendered = renderJsx(sourceJsx, options);
if (rendered) {
Expand Down

0 comments on commit 60b7bd9

Please sign in to comment.