Storybook(CSF3.0)をTypeScriptで書くときのメモ

11092 ワード

基本的には東雲様の記事で事足ります(ありがとうございます)。
実際に書いていく中で、「あれ、こうゆうときどうするんだろう」となったケースの解決方法をメモします。

以下は、Chakra UIを拡張したコンポーネントを使った例です。

1. argsを一部だけ上書きしたい

simple-confirm-modal.stories.tsx
export default などは略)

export const SimpleConfirmModal: ComponentStoryObj<typeof Modal> = {
  args: {
    message: 'メッセージ',
    actionLabel: 'はい',
    cancelLabel: 'いいえ',
    onAction: () => alert('You clicked はい'),
    onClose: () => alert('You clicked いいえ'),
    isOpen: true
  }
}

export const SimpleConfirmModalWide: ComponentStoryObj<typeof Modal> = {
  ...SimpleConfirm,
  args: {
    ...SimpleConfirm.args,
    w: '600px'
  }
}

こんな感じで、スプレッド演算子で上書き(使い回し)できます。


2. 目的のコンポーネント以外も表示させたい

単体テスト的に、1つのコンポーネントだけを1つのStoryとして書くことが多いかもしれませんが、
結合テスト的に、複数のコンポーネントを組み合わせた形で書くこともあると思います。
その場合は、render関数を明示的に入れることで可能です。

modal.stories.tsx
export const Basic: ComponentStoryObj<typeof CommonModal> = {
  render: (args: ModalProps) => (
    <CommonModal {...args}>
      <CommonModalHeader title='タイトル' />
      <CommonModalBody>
        <Box h='200px' bg='blue.300'>
          ボディ
        </Box>
      </CommonModalBody>
      <CommonModalFooter>フッター</CommonModalFooter>
    </CommonModal>
  ),
  args: {
    isOpen: true,
    maxW: '600px'
  }
}

render関数は省略できるので、一つ目のような書き方ができるんですね。


余談

なんならargsも省略できるので、最短では空のオブジェクトだけでStoryは作れます。
アイコンなどそのまま表示させたい場合はこれで十分かもしれません。

arrow-left.stories.tsx
import { ComponentMeta } from "@storybook/react";
import { ArrowLeft as ArrowLeftIcon } from "./arrow-left";

export default {
  title: 'parts/icons',
  component: ArrowLeftIcon
} as ComponentMeta<typeof ArrowLeftIcon>

export const ArrowLeft = {}

ちなみに、上記のように名前を変えてインポートすれば、BasicみたいなStory名が不要になるので、同じ階層で違うファイルのStoryを並べたい場合は便利かもしれません。


参考