別の記事でtailwind-variants
のVariantProps
を利用すると型定義いい感じ!
みたいな記事を書いたのですが…
コードをスッキリさせるのと引き換えにStorybookの機能を犠牲にしてしまうBadに気がつきました…という記事です。
私の記述方法が間違っていただけで、Controlsはちゃんと制御することができました…。
誤った発信をしてしまい大変申し訳ございません…。
argTypes: {
borderType:
- control: {
- type: 'select',
- option: ['solid', 'dashed']
- },
+ control: {type: 'select'}
+ option: ['solid', 'dashed']
},
},
これより以下の記事は間違って書くとこうなります。
という反面教師として興味がある方は確認してください。
Storybookが自動でControlsを認識しなくなる&制御できない…
下記のようにコンポーネントを定義したとします。
// 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ファイルは下記のように書いてみました。
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」となります。
クリックするとからのオブジェクトが表示されます。
下記のように値を指定することでsolid
がデフォルトの値として表示されるようになりますが…本当はselectやradioのtypeで選択できる方が嬉しいです。
export const Default: Story = {
args: {
borderType: 'solid',
},
};
argsTypeを変えてみようとした
storiesファイルを編集して上書きしてみます。
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 = {};
ただ、変化はなく下記のような表示になってしまいました。
VariantProps
を利用せずに型を定義した場合はどうなるか試します。
VariantProps
ではなくユニオン型で定義し直してみる
- type Props = VariantProps<typeof style>
+ type Props = 'solid' | 'dashed'
Storybookの表示は下記のようになります。
試しにradioタイプ変えてみると反映されることが確認できました。
argTypes: {
borderType: {
control: {
- type: 'select',
+ type: 'radio'
options: ['solid', 'dashed'],
},
},
},
まとめ
コードの最適化を優先してvariants
を利用するのが良いかな…と思っています…。
下記のような書き方も試してみましたが、ダメでした…。
- type Props = VariantProps<typeof style>
+ type Props = keyof (typeof style)['variants']['borderType']
なんとか両方が良い状態にできないか引き続き解決策を探していきたいと思います。
ちなみにVariantProps
はいくつか問題があるようなので、おかしいな…と思ったらissueを確認してみてください!