A next-generation tool to create blazing-fast documentation sites
API
created:12/30/2020
updated:12/30/2020

MDX Stories

Overview

You can create interactive component examples (aka stories) similar to ESM in MDX
To do so, you need to import some components from '@component-controls/blocks' and use them inside your MDX files

Advantages

The MDX format has the following advantages:
  • You have full control over your documentation, testing, and design pages.
  • You can include custom markdown documentation text.
The MDX format has the following disadvantages:
  • Documentation pages are not automatically created.
  • IDE code-completion and linting support will be sub-par for now.

File extensions

The MDX story files need to have an .mdx file extension and they should contain at least one Story componnet (if not, they are treated as regular MDX documentation pages);

Example

---
title: First Story
---
import { Button } from '../components/Button';
import { Playground, Story, PropsTable, ComponentSource, StorySource } from '@component-controls/blocks';
# My first doc story
<ComponentSource of={Button} title="Component source" />
<Playground description="Button story">
<Story name="simple">
<Button>
click me
</Button>
</Story>
</Playground>
<StorySource id="." />
<PropsTable of={Button} />

External stories

You can import ESM stories into your MDX documentation. Usually, this is to use the benefits of writing your stories in .tsx/.jsx files with full code completion support from your code editor.
Our instrumenting module will take care to show the actual story source imported, not the code in the MDX file doing the importing.
---
title: External Story
---
import { Playground, Story } from '@component-controls/blocks';
import { customStory } from '../../stories/src/stories/external/external-story-props';
<Playground description="story from external file with props">
<Story name='mdx-external-story' controls={{ text: 'hello' }} >
{props => customStory(props)}
</Story>
</Playground>
In the example below, click on open source to view the imported story source.
hello

Components

Below is a list of the most commonly used components (aka blocks) when writing MDX stories:

Story-related

Playground

Component to display a live playground of component examples. Has custom actions for zooming, switching direction, reviewing story source, and configuration.

Story

Block component to render story function with decorators.

StoryConfig

Displays the configuration object of a story.

StorySource

Displays the source code of a story. If controls are used, all story arguments will be highlighted. Additional commands are made available if the repository data of the story is available.

Subtitle

Displays a subtitle as assigned to the story.subtitle field

PropsTable

Displays the component's properties as well as configurable controls to interact with the component.

ComponentSource

Displays import statement for a component as well as the component file source code Optionally also displays some repository information from the component's package.json

Description

Description component with markdown. The 'of' property can specify which component's description to display.

ComponentDeps

Displays external dependencies for a component

Stories

Displays multiple stories in their own Playground components.

TagsList

Displays a row of tags assigned to the current document, with links to their pages

Story templates

Using story templates you can reduce the amount of repetitive code in your MDX stories documentation. This is usually needed when you want to create separate stories for the various state values of your components.
In MDX files, you can bind stories to a template, and this syntax is compatible with Storybook 6
---
title: "MDX/Template bind"
component: Button
---
import { Playground, Story } from '@component-controls/blocks';
import { Button } from '../../../stories/src/components/Button';
export const Template = props => (
<Button {...props}>Button</Button>
);
<Playground>
<Story name='tom' controls={{
name: 'tom',
}}>
{Template.bind()}
</Story>
</Playground>
<Playground>
<Story name='harry' controls={{
name: 'harry',
}}>
{Template.bind()}
</Story>
</Playground>