storybook에 argTypes를 직접 입력해줘야 storybook 상에서 해당 prop에 대한 테스트가 가능하다
export default {
title: "Button",
component: Button,
parameters: {
layout: "centered",
},
tags: ["autodocs"],
argTypes: {
size: {
control: { type: "radio" },
description: "버튼의 높이를 조절할 수 있습니다",
options: ["small", "medium", "large"],
},
variant: {
control: { type: "radio" },
description: "border의 여부에 따라 primary/text로 나뉩니다",
options: ["primary", "text"],
},
br: {
control: { type: "radio" },
description: "borderRadius를 조절할 수 있습니다",
options: ["normal", "rounded"],
},
disabled: {
control: { type: "boolean" },
description: "버튼의 클릭을 제어할 수 있습니다",
},
},
args: {
onClick: fn(),
},
} satisfies Meta<typeof Button>
어떤 props가 존재하는지 , 해당 props를 어떤 식으로 control 할건지를 일일이 추가해줘야 했는데,
일단 IDE 상에서 해당 컴포넌트에 어떤 props가 존재하는지 미리보기가 안돼서 컴포넌트/stories.tsx를 왔다갔다 하면서 작성해야했다
휴먼 에러가 발생하기 매우 쉬운 환경이다
satisfies Meta<typeof Button> 이것 때문인지 props에 대한 타입 체크는 해준다(존재하지 않는 props가 있을경우 에러)preview.tsx 에서 argTypes를 전역으로 설정하여 일일이 각 stories에서 기입하지 않아도 공통으로 arg를 생성할 수 있다
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
argTypes: {
color: {
control: "color",
},
},
}

나는 해당 stories.tsx 파일에 color 를 넣지 않았음에도 이렇게 color라는 control을 추가해줄 수 있다
컴포넌트의 Prop을 하나하나 Control로 작성하는 것은 매우 귀찮을 수 있습니다. 스토리북은 react-docgen-typescript와 react-docgen-typescript-plugin를 사용하여 컴포넌트의 Prop 타입을 Control로 자동 생성해 줄 수 있습니다. (공식 문서)
라는 내용을 봤다.
공식문서에서 설명하는 해당 라이브러리의 기능은
A simple parser for React properties defined in TypeScript instead of propTypes.
Typescript로 정의된 properties를 파싱해주는 기능을 한다고 한다

설정 후에 기존의 stories.tsx 파일에서 argTypes 부분을 다 지우고 storybook을 실행하면
결과

그대로 properties를 파싱해서 argTypes에 적용시켜준다
type Props = {
/** 예시1 */
a: string
/** 예시2 */
b?: boolean
/** 예시3 */
c?: () => void
}
/**
* 컴포넌트 설명
*
* - 어쩌고
* - 저쩌고
*/
const Ex = ({ a }: Props) => {
return <div>{a}</div>
}
export default Ex

이렇게 컴포넌트의 주석 또한 파싱해서 옮겨주기 때문에, argTypes의 description 기능을 사용하지 않아도 된다
기존에는 컴포넌트가 수정되면 storybook도 이에 맞게 수정해줘야 했다면, 이제는 자동으로 업데이트가 되기 때문에 하나의 SSOT를 가지게 된다고 볼 수 있다
단점이라면, 가끔 추론이 이상하게 되는 경우가 있다
현재 버튼에서는 pandacss recipe 생성시 자체적으로 정의된 ButtonVariantProps 를 사용하고 있다
내부 구현은 좀 복잡하지만, 결과는
{size: 'small' | 'medium' | 'large'
variant : 'text' | 'primary'
...
}
이런 식인데 파싱된 결과물은

내부 구현에서 사용된 ConditionalValue 라는 타입이 적용되었다
그래서 또 다른 타입 output인 ButtonVariant를 사용해서
interface ButtonVariant {
size: "small" | "medium" | "large"
br: "normal" | "rounded"
variant: "primary" | "text"
}
이를 Partial로 적용했더니 정상적으로 반영되었다