ストーリー
コントロール付きでコンポーネントを表示します。
Callout
はじめに
Fumadocs Story は、コンポーネントを表示し、ドキュメント化するためのツールです。 Storybook に代わる、ドキュメントに特化したシンプルなツールで、主にコンポーネントライブラリ向けに設計されています。
ストーリーという概念を初めて知る方のために、Storybook のドキュメントから簡単な説明を引用します。
ストーリーは、UI コンポーネントのレンダリングされた状態を捉えたものです。アノテーションを持つオブジェクトであり、 一連の引数が与えられたときのコンポーネントの振る舞いと外観を記述します。
Storybook ではなくこちらを使うべきなのはどんなとき?
Fumadocs Story は Storybook を置き換えるものではありません。本格的な UI テストには、引き続き Storybook をおすすめします。
インストール
npm i @fumadocs/storyTailwind CSS のプリセットを追加します。
@import '@fumadocs/story/css/preset.css';Vite プラグインを追加します。
import { defineConfig } from 'vite';
import story from '@fumadocs/story/vite';
export default defineConfig({
plugins: [story()],
});ストーリーを作成する
グローバル設定を保持するストーリーファクトリーを作成します。
import { defineStoryFactory } from '@fumadocs/story/vite/client';
export const { defineStory } = defineStoryFactory();次に、最初のストーリーを作成します。
import { defineStory } from '@/lib/story';
import { MyComponent } from './my-component';
export const story = defineStory({
Component: MyComponent,
args: {
// デフォルトの props(推奨)
initial: {},
},
});.story サフィックスは必須です
プラグインが変換するのは *.story.{js,jsx,ts,tsx} に一致するファイルのみです。この条件はVite プラグインの filter オプションで変更できます。
ストーリーをレンダリングする
MDX ファイル内でストーリーをレンダリングします。
import { story } from '@/components/my-component.story';
<story.WithControl />設定
バリアント
args を使うと、コンポーネントのバリアントを複数指定できます。
import { defineStory } from '@/lib/story';
import { Callout } from '@/components/callout';
export const story = defineStory({
Component: Callout,
args: [
{
variant: 'Default',
initial: {
title: 'This is a Callout',
},
},
{
variant: 'Warning',
initial: {
title: 'This is a Callout',
},
// props の固定値
fixed: {
type: 'warning',
},
},
],
});controls
コントロールはコンポーネントのpropsから自動生成されます。これらを置き換えるには、コントロールノードを指定します。
import { defineStory } from '@/lib/story';
import { GraphView } from '@/components/graph-view';
export const story = defineStory({
Component: GraphView,
args: {
controls: {
node: {
type: 'object',
properties: [],
},
},
},
});frame
レイアウトのようにビューポート全体を占めるコンポーネントは、iframe 内でレンダリングできます。 ストーリーパネルではフレームがパネルに収まるよう縮小して表示され、フルスクリーンで開くためのボタンも用意されています。
import { defineStory } from '@/lib/story';
import { MyLayout } from './my-layout.lazy';
import { Window } from './window';
export const story = defineStory({
Component: MyLayout,
frame: {
src: '/story/my-layout',
// ビューポートサイズ(省略可)
width: 1280,
height: 800,
// フレームをウィンドウなどでラップする(省略可)
Container: Window,
},
});コンポーネントをレンダリングするページを src に作成します。このページはストーリーパネルから引数を受け取ります。
import { createFileRoute } from '@tanstack/react-router';
import { story } from '@/components/my-layout.story';
export const Route = createFileRoute('/story/my-layout')({
component: () => <story.Frame />,
});ストーリーは、それをレンダリングするすべてのページでコンポーネントを読み込みます。遅延読み込みのコンポーネントを渡せば、フレームでのみ読み込まれるようになります。
import { lazy } from 'react';
export const MyLayout = lazy(() =>
import('./my-layout').then((mod) => ({ default: mod.MyLayout })),
);補足
- ページはドキュメントと同じオリジン上に配置する必要があります。
- 引数は
postMessage()で送信されるため、シリアライズ可能な値である必要があります (関数や JSX は使用できません) 。
国際化
UI レベルで国際化を設定済みの場合:
import { defineI18n } from 'fumadocs-core/i18n';
import { uiTranslations } from 'fumadocs-ui/i18n';
import { storyTranslations } from '@fumadocs/story/i18n';
const i18n = defineI18n({
languages: ['en', 'cn'],
defaultLanguage: 'en',
});
export const translations = i18n
.translations()
.extend(uiTranslations())
.extend(storyTranslations())
.add({
cn: {
displayName: 'Chinese',
'Add Item(story arguments form)': '新增項目',
},
});詳しくは翻訳を参照してください。
How is this guide?
最終更新日
