型定義の方法によってはStorybookのControlsが制御できなくなる

別の記事で`tailwind-variants`の`VariantProps`を利用すると型定義いい感じ！
みたいな記事を書いたのですが…

https://qiita.com/tanimoto-hikari/items/0e406233581de6181cb1

~~コードをスッキリさせるのと引き換えにStorybookの機能を犠牲にしてしまうBadに気がつきました…という記事です。~~

:::note alert
私の記述方法が間違っていただけで、Controlsはちゃんと制御することができました…。
誤った発信をしてしまい大変申し訳ございません…。
:::

```diff_javascript:正しい記述
argTypes: {
  borderType: 
-    control: {
-      type: 'select',
-      option: ['solid', 'dashed']
-    },
+   control: {type: 'select'}
+   option: ['solid', 'dashed']
  },
 },
```

これより以下の記事は間違って書くとこうなります。
という反面教師として興味がある方は確認してください。


## Storybookが自動でControlsを認識しなくなる＆制御できない…
下記のようにコンポーネントを定義したとします。

```typescript:component.tsx
// tailwind-variantsからVariantPropsをimportします
import { tv, type VariantProps } from 'tailwind-variants';

const style = tv({
  base: 'border-gray-400 block',
  variants: {
    borderType: {
      solid: 'border-solid',
      dashed: 'border-dashed',
    },
  },
});

type Props = {
  borderType: VariantProps<typeof style>['borderType']
}

export const Divider: FC<Props> = ({
  borderType = 'solid',
}) => {
  return <span className={style({ borderType })}></span>;
};
```

storiesファイルは下記のように書いてみました。

```typescript:component.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Component } from './Component';

const meta = {
  title: 'Component',
  component: Component,
  tags: ['autodocs'],
} satisfies Meta<typeof Component>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
```

実際の表示はというと…「Set object」となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/a94f0e7e-bfeb-e5ac-632a-11919a0b8e83.png)

クリックするとからのオブジェクトが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/70ccd253-bf06-e808-fc73-79b6048cb773.png)

下記のように値を指定することで`solid`がデフォルトの値として表示されるようになりますが…**本当はselectやradioのtypeで選択できる方が嬉しいです。**
```typescript
export const Default: Story = {
  args: {
    borderType: 'solid',
  },
};
```

### argsTypeを変えてみようとした
storiesファイルを編集して上書きしてみます。

```diff_typescript:component.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Component } from './Component';

const meta = {
  title: 'Component',
  component: Component,
  tags: ['autodocs'],
+ argTypes: {
+  borderType: {
+    control: {
+      type: 'select',
+      option: ['solid', 'dashed']
+    },
+  },
+ },
} satisfies Meta<typeof Component>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
```

ただ、変化はなく下記のような表示になってしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/4bc8c1b7-e35d-fb97-e99a-d0e5330caff5.png)

`VariantProps`を利用せずに型を定義した場合はどうなるか試します。

### `VariantProps`ではなくユニオン型で定義し直してみる

```diff_typescript:component.tsx
- type Props = VariantProps<typeof style>
+ type Props = 'solid' | 'dashed'
```

Storybookの表示は下記のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/74c9af44-5419-5a06-0972-64fc3443a20d.png)

試しにradioタイプ変えてみると反映されることが確認できました。

```diff_typescript:component.stories.tsx
argTypes: {
  borderType: {
    control: {
-     type: 'select',
+     type: 'radio'
      options: ['solid', 'dashed'],
    },
  },
},
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/3f472de5-2732-151f-65ab-29d14c26c2bd.png)


## まとめ
コードの最適化を優先して`variants`を利用するのが良いかな…と思っています…。

下記のような書き方も試してみましたが、ダメでした…。

```diff_typescript:component.tsx
- type Props = VariantProps<typeof style>
+ type Props = keyof (typeof style)['variants']['borderType']
```

なんとか両方が良い状態にできないか引き続き解決策を探していきたいと思います。

ちなみに`VariantProps`はいくつか問題があるようなので、おかしいな…と思ったらissueを確認してみてください！

https://github.com/nextui-org/tailwind-variants/issues?q=is%3Aissue+is%3Aopen+VariantProps