Storybookのv5.2 で入る予定の新しいアドオン addon-docs
を試してみたら、なかなかいい感じだったので布教記事を書きます。
実物はGitHub Pagesで公開しています。
https://y-takey.github.io/storybook_docs_example/
(リポジトリ: https://github.com/y-takey/storybook_docs_example )
addon-docs
は (既存のアドオンである) addon-info
をほぼ置き換える新しいアドオンで、従来のストーリー形式に加えて MDXも使えることが一番の特徴だと思います。上の画像のようなドキュメントを手軽に書くことができます。
MDXを使えることが理由で、 Styleguidist や Docz を選んだ人もいるんじゃないかと思いますが、これからは Storybook も負けていません。
※ 本記事は Storybook
および addon-docs
のバージョン 5.2.0-alpha.29 を元にしており、最新バージョンでは設定や使用方法が変わっている可能性がありますのでご注意下さい。
設定方法など
Storybook自体のインストール・設定は終わっている前提で、addon-docs
のインストール・設定等は次のとおりです。
Storybook 本体と既存アドオンのアップグレード
2019/06/23 時点では Storybook@5.2 はまだ正式リリースされていないため、debug
を指定してアップグレードします。
yarn upgrade @storybook/react@debug @storybook/addons@debug @storybook/addon-actions@debug
他にも使用している公式アドオンがあれば同様にアップグレードしてください。
addon-docs
等のインストール
yarn add -D @storybook/addon-docs@debug @storybook/source-loader@debug
addon-docs
の他に、ソースも表示できるようにするために @storybook/source-loader
もインストールしています。
ソース表示が不要な場合はインストールしなくても大丈夫です。
addon-docs
の設定など
import { load } from '@storybook/react';
load(require.context('../src', true, /\.stories\.[tj]sx?$/), module);
load(require.context('../src', true, /\.stories\.mdx$/), module);
ロード対象ファイルの正規表現は適宜変えて下さい。この例では TypeScript , mdx をロードするようにしています。
今回はMDXのみとするので書いていませんが、以下の設定を上の config.js に追加すると、従来のストーリにも自動で(ある程度よしなに)ドキュメントを追加してくれます。
import { addParameters } from '@storybook/react'
import { DocsPage } from '@storybook/addon-docs/blocks';
addParameters({
docs: DocsPage,
});
module.exports = [
'@storybook/addon-docs/react/preset',
];
const path = require('path');
module.exports = ({ config }) => {
config.module.rules.push({
test: /\.stories\.[tj]sx?$/,
use: [
{
loader: require.resolve('@storybook/source-loader'),
options: { injectParameters: true },
},
],
include: [path.resolve(__dirname, '../src')],
enforce: 'pre',
}, {
test: /\.(ts|tsx)$/,
use: [
{
loader: require.resolve('awesome-typescript-loader'),
},
{
loader: require.resolve('react-docgen-typescript-loader'),
},
],
include: [path.resolve(__dirname, '../src')],
});
config.resolve.extensions.push('.ts', '.tsx');
return config;
};
ソースコードを表示するには @storybook/source-loader
が必要となるため、 webpack.config に設定を追加します。(module.rules.push の1つ目の引数)
また TypeScript のソースコードから props のテーブルを表示するには react-docgen-typescript-loader
が必要となるため、こちらもwebpack.config に設定を追加します。(module.rules.push の2つ目の引数)
ここでは awesome-typescript-loader
を使っていますが、 ts-loader
でも大丈夫です。ちなみに、TypeScriptまわりの設定については、 @storybook/preset-typescript
を使えばwebpackの設定を自分でやる必要はありません。(内部では ts-loader
, react-docgen-typescript-loader
を追加してくます)
また、TypeScriptの他にも prop-types, flowでも props のテーブルを表示してくれます。(それぞれの対応する loader の設定が必要)
MDX
ドキュメントは以下のような感じで書きます。(MDXのハイライトがないみたいで、ちょっと見にくいかもしれません。)
import { action } from "@storybook/addon-actions";
import { Story, Meta, Preview, Props, Source, Description } from "@storybook/addon-docs/blocks";
import Button from "./Button";
<Meta title="hoge" parameters={{ component: Button }} />
# Button
何の変哲もない、ただのボタン。
<Source code={`import Button from "~/components/Button";`} />
<Preview withSource="open">
<Story name="basic" >
<Button label="this is src" onClick={action('clicked')} />
</Story>
</Preview>
<Props of="." />
@storybook/addon-docs/blocks
から import できるコンポーネントは以下のものがあります。
Meta
Props
プロパティ | 必須 | 説明 |
---|---|---|
title | 必須 | サイドバーに表示されるタイトル。"¦"(縦棒)でセクショニングできて、"/"で階層化できる。(たぶん addon-info と同じ記法) |
decorators | 任意(デフォはなし) |
addon-info と同様なため詳細はそちらを参照。指定する場合は1つでもdecoratorの配列にする必要がある。 |
parameters | 任意(デフォはなし) |
{ component, notes, info } のオブジェクトでいずれも任意要素。後述の Props, Description 等のコンポーネントから参照される。 |
例
<Meta
title="セクションA|Components/Button"
parameters={{
component: Button,
notes: "This is notes;",
info: "This is info.",
}}
/>
Preview
Props
プロパティ | 必須 | 説明 |
---|---|---|
withSource | 任意(デフォは"closed") | ソースも一緒に表示するかの設定で、"open" |
例
<Preview withSource="open">
<Story name="basic" >
<Button label="this is src" onClick={action('clicked')} />
</Story>
</Preview>
Story
Props
プロパティ | 必須 | 説明 |
---|---|---|
id | 任意 | 他の箇所でidを指定して参照できるようになる。 |
name | 任意 | サイドメニューに表示される名称 |
height | 任意 | 表示領域の高さ |
例
<Story name="basic" >
<Button label="this is src" onClick={action('clicked')} />
</Story>
Source
Props
プロパティ | 必須 | 説明 |
---|---|---|
code | 必須 | 表示するソースコード |
language | 任意(デフォは"jsx") | ハイライト用に使われる言語。 |
例
<Source code={`import Button from "~/components/Button";`} />
Props
Props
プロパティ | 必須 | 説明 |
---|---|---|
of | 必須 | 対象のコンポーネント。"." でカレントコンポーネント(Metaコンポーネントの parameters.component ) |
例
<Props of={Button} />
// <Props of="." /> と書いても同じ
Description
Props
プロパティ | 必須 | 説明 |
---|---|---|
of | 任意 | 対象のコンポーネント。"." でカレントコンポーネント。 |
markdown | 任意 | 表示するマークダウンテキスト。 |
type | 任意 | "info", "notes", "docgen", "auto" のいずれかを指定可能。"info", "notes" は Meta コンポーネントの parameters プロパティで指定した 同名の要素を使用する。"docgen" は各種のdocgen loader によって注入される 対象コンポーネントの __docgenInfo.description を使用する。 |
markdown が指定されている場合には type は無視される。
例
<Description markdown="**BOLD**" />
<Description type="info" />
その他
Storybook は React 以外にも Vue や Angular 等など色々サポートしていますが、 addon-docs
が対応しているのは現時点では React, Vue だけです。( Vue は一部未実装の模様)
Angularも今後対応予定のようです。
説明は以上です。まだまだドキュメントがほとんどないため addon-docs
のソースコードも読みながら調べた内容をまとめてみました。
正式リリースされる際にはきっとドキュメントも整備されていると思います。