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: Support MDX source in Preview w/ no Story blocks #7966

Merged
merged 10 commits into from
Oct 15, 2019
11 changes: 9 additions & 2 deletions addons/docs/src/blocks/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@ export enum SourceState {

type PreviewProps = PurePreviewProps & {
withSource?: SourceState;
mdxSource?: string;
};

const getPreviewProps = (
{ withSource = SourceState.CLOSED, children, ...props }: PreviewProps & { children?: ReactNode },
{ withSource = SourceState.CLOSED, mdxSource, children, ...props }: PreviewProps & { children?: ReactNode },
{ mdxStoryNameToId, storyStore }: DocsContextProps
): PurePreviewProps => {
if (withSource === SourceState.NONE && !children) {
if (withSource === SourceState.NONE) {
return props;
}
if (mdxSource) {
return {
...props,
withSource: getSourceProps({ code: decodeURI(mdxSource) }, { storyStore }),
};
}
const childArray: ReactNodeArray = Array.isArray(children) ? children : [children];
const stories = childArray.filter(
(c: ReactElement) => c.props && (c.props.id || c.props.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ function MDXContent({ components, ...props }) {
</Story>
<Story id=\\"welcome--welcome\\" mdxType=\\"Story\\" />
</Preview>
<p>{\`Preview wthout a story\`}</p>
<Preview mdxSource=\\"%0A%3CButton%3EJust%20a%20button%3C/Button%3E%0A\\" mdxType=\\"Preview\\">
<Button mdxType=\\"Button\\">Just a button</Button>
</Preview>
</MDXLayout>
);
}
Expand Down
7 changes: 7 additions & 0 deletions addons/docs/src/mdx/__testfixtures__/previews.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ Previews can contain normal components, stories, and story references
</Story>
<Story id="welcome--welcome" />
</Preview>


Preview wthout a story

<Preview>
<Button>Just a button</Button>
</Preview>
61 changes: 61 additions & 0 deletions addons/docs/src/mdx/mdx-compiler-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,68 @@ function stringifyMeta(meta) {
return result;
}

const hasStoryChild = node => {
if (node.openingElement && node.openingElement.name.name === 'Story') {
return node;
}
if (node.children && node.children.length > 0) {
return node.children.find(child => hasStoryChild(child));
}
return null;
};

function extractExports(node, options) {
node.children.forEach(child => {
if (child.type === 'jsx') {
try {
const ast = parser.parseExpression(child.value, { plugins: ['jsx'] });
if (
ast.openingElement &&
ast.openingElement.type === 'JSXOpeningElement' &&
ast.openingElement.name.name === 'Preview' &&
!hasStoryChild(ast)
) {
const previewAst = ast.openingElement;
previewAst.attributes.push({
type: 'JSXAttribute',
name: {
type: 'JSXIdentifier',
name: 'mdxSource',
},
value: {
type: 'StringLiteral',
value: encodeURI(
ast.children
.map(
el =>
generate(el, {
quotes: 'double',
}).code
)
.join('\n')
),
},
});
}
const { code } = generate(ast, {});
// eslint-disable-next-line no-param-reassign
child.value = code;
} catch {
/** catch erroneous child.value string where the babel parseExpression makes exception
* https://github.com/mdx-js/mdx/issues/767
* eg <button>
* <div>hello world</div>
*
* </button>
* generates error
* 1. child.value =`<button>\n <div>hello world</div`
* 2. child.value =`\n`
* 3. child.value =`</button>`
*
*/
}
}
});
// we're overriding default export
const defaultJsx = mdxToJsx.toJSX(node, {}, { ...options, skipExport: true });
const storyExports = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ export const nonStory2 = () => <Button>Not a story</Button>; // another one

<Source name="hello story" />

<Preview>
<Button onClick={action('clicked')}>view source in preview</Button>
</Preview>

## Configurable height

<Preview withToolbar>
Expand All @@ -122,6 +126,18 @@ Flow types are not officially supported

<Props of={FlowTypeButton} />

### withSource="none"

<Preview withSource="none">
<h1>no source</h1>
</Preview>

<Preview withSource="none">
<Story name="no source preview">
<Button onClick={action('clicked')}>solo</Button>
</Story>
</Preview>

## Docs Disable

<Story name="docs disable" parameters={{ docs: { disable: true } }}>
Expand Down