Closed6

Storybookで簡単にエンジニア向けのUIカタログを作りたい

よぺよぺ

Storybookで簡単にコンポーネントをドキュメント化する方法

結論

Storyファイル*.stories.ts|js上のmetaにtags: ["autodocs"]を入れる

Chip.stories.ts
const meta = {
  title: "Test/Chip",
  component: Chip,
  parameters: {
    layout: "centered"
  },
+  tags: ["autodocs"]
} satisfies Meta<typeof Chip>

https://storybook.js.org/docs/writing-docs/autodocs

前提

  • Storybookに表示したいコンポーネントがある

手順

例として、Chipコンポーネントから簡単にドキュメント化する手順を記載

  1. Storyファイルのmetaにtags: ["autodocs"]を入れる
Chip.stories.ts
const meta = {
  title: "Test/Chip",
  component: Chip,
  parameters: {
    layout: "centered"
  },
+  tags: ["autodocs"]
} satisfies Meta<typeof Chip>
  1. 最低1つコンポーネントとしてStoryを追加する
Chip.stories.ts
export const NoAvatarChip: Story = {
  args: {
    size: "sm",
    color: "default",
    variant: "filled",
    label: "Chip",
    deletable: false,
    disabled: false
  }
}
よぺよぺ

設定後

コード

Chip.stories.ts
import type { Meta, StoryObj } from "@storybook/react"
import Chip from "./Chip"

const meta = {
  title: "Test/Chip",
  component: Chip,
  parameters: {
    layout: "centered"
  },
  tags: ["autodocs"]
} satisfies Meta<typeof Chip>

export default meta
type Story = StoryObj<typeof meta>

export const NoAvatarChip: Story = {
  args: {
    size: "sm",
    color: "default",
    variant: "filled",
    label: "Chip",
    deletable: false,
    disabled: false
  }
}

Storybook

よぺよぺ

Storybook上で属性コントロールを変更する方法

結論

Storyファイル*.stories.ts|jsのmetaにargTypesを設定する

Chip.stories.ts
argTypes: {
    size: {
      options: ["sm", "md", "lg"],
      control: { type: "select" }
    }
  }

https://storybook.js.org/docs/essentials/controls

手順

  1. StoryファイルのmetaにargTypesを設定する
Chip.stories.ts
const meta = {
  title: "Test/Chip",
  component: Chip,
  parameters: {
    layout: "centered"
  },
+  argTypes: {
+    size: {
+      options: ["sm", "md", "lg"],
+      control: { type: "select" }
+    }
+  },
  tags: ["autodocs"]
} satisfies Meta<typeof Chip>

設定できるコントロールはDocs (https://storybook.js.org/docs/essentials/controls#annotation) を参照

  1. Storyファイル上にStoryを少なくとも1つ追加する
Chip.stories.ts
export const NoAvatarChip: Story = {
  args: {
    size: "sm",
    color: "default",
    variant: "filled",
    label: "Chip",
    deletable: false,
    disabled: false
  }
}
よぺよぺ

設定後 ~属性コントロールを変更する方法~

コード

Chip.stories.ts
import type { Meta, StoryObj } from "@storybook/react"
import Chip from "./Chip"

const meta = {
  title: "Test/Chip",
  component: Chip,
  parameters: {
    layout: "centered"
  },
  argTypes: {
    size: {
      options: ["sm", "md", "lg"],
      control: { type: "select" }
    }
  },
  tags: ["autodocs"]
} satisfies Meta<typeof Chip>

export default meta
type Story = StoryObj<typeof meta>

export const NoAvatarChip: Story = {
  args: {
    size: "sm",
    color: "default",
    variant: "filled",
    label: "Chip",
    deletable: false,
    disabled: false
  }
}

Storybook

Before After
よぺよぺ

Storybook上で複数のコンポーネントから成るStoryを作成する方法

結論

以下3パターンのいずれかで実現可能

Storyファイル*.stories.ts|jsに対して、

  • A. Storyにサブコンポーネントを引数argsで渡す
  • B. renderを使ってコンポーネントを描画

それぞれのパターンの詳細↓

パターンA. Storyにサブコンポーネントを引数argsで渡す

Chip.stories.ts
import type { Meta, StoryObj } from "@storybook/react"
import Chip from "./Chip"
import Avatar from "../Avatar/Avatar"
(中略)
export const TextChip: Story = {
  args: {
    size: "sm",
    color: "default",
    variant: "filled",
    label: "Chip",
    deletable: false,
    disabled: false,
    avatar: (
      <Avatar size="sm" variant="Circular">
        OP
      </Avatar>
    )
  }
}

パターンB. renderを使ってコンポーネントを描画

Chip.stories.ts
export const Size: Story = {
  parameters: {
    controls: {
      disable: true
    }
  },
  args: {
    size: "lg",
    variant: "Circular",
    children: "OP"
  },
  render: (args) => (
    <div style={{ display: "flex", gap: "8px" }}>
      <Avatar {...args} size="lg" />
      <Avatar {...args} size="md" />
      <Avatar {...args} size="sm" />
    </div>
  )
}
よぺよぺ

StorybookのAuto Docsをリッチにしたい

結論

Story/meta/型定義にJSDocをつける

方法

以下3パターンに対して、Storybookへの反映結果を順に紹介

  • StoryにJSDocをつけた場合
  • metaにJSDocをつけた場合
  • 型定義にJSDocをつけた場合

StoryにJSDocをつけた場合

before after
Avatar.stories.tsx
/**
 * 3サイズを提供
 *
 * #### size
 * - `sm`: 24px
 * - `md`: 32px
 * - `lg`: 40px
 */
export const Size: Story = {
  parameters: {
    controls: {
      disable: true
    }
  },
  args: {
    size: "lg",
    variant: "Circular",
    children: "OP"
  },
  render: (args) => (
    <div style={{ display: "flex", gap: "8px" }}>
      <Avatar {...args} size="lg" />
      <Avatar {...args} size="md" />
      <Avatar {...args} size="sm" />
    </div>
  )
}

metaにJSDocをつけた場合

before after
Avatar.stories.tsx
/**
 * 文字列・画像・アイコンを含んだアバター
 */
const meta = {
  title: "Test/Avatar",
  component: Avatar,
  parameters: {
    layout: "centered"
  },
  tags: ["autodocs"]
} satisfies Meta<typeof Avatar>

型定義にJSDocをつけた場合

before after
Chip.stories.tsx
type ChipProps = {
  /**
   * Chipのサイズ
   */
  size: "sm" | "md"
  /**
   * Chipの色
   */
  color: "default" | "primary" | "secondary" | "error"
  /**
   * Chipの種類
   */
  variant: "filled" | "outlined"
  /**
   * Chipのラベル
   */
  label: string
  /**
   * Avatarコンポーネント
   */
  avatar?: React.ReactElement
  /**
   * 無効化される
   */
  disabled?: boolean
  /**
   * 削除ボタンがある
   */
  deletable?: boolean
}
このスクラップは1ヶ月前にクローズされました