LoginSignup
3
0

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

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

Storybookが自動でControlsを認識しなくなる&制御できない…

下記のようにコンポーネントを定義したとします。

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ファイルは下記のように書いてみました。

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

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

image.png

下記のように値を指定することでsolidがデフォルトの値として表示されるようになりますが…本当はselectやradioのtypeで選択できる方が嬉しいです。

export const Default: Story = {
  args: {
    borderType: 'solid',
  },
};

argsTypeを変えてみようとした

storiesファイルを編集して上書きしてみます。

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

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

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

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

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

image.png

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

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

image.png

まとめ

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

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

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

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

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

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0