DEV Community

SeongKuk Han
SeongKuk Han

Posted on

6

React TS Storybook: Using Custom Props in a Story

React TS Storybook: Appending Custom Props to a Story

Let's say you have a list component like below,



import { HTMLAttributes } from "react";

const List = ({ children, ...props }: HTMLAttributes<HTMLUListElement>) => {
  return <ul {...props}>{children}</ul>;
};

const ListItem = ({ children, ...props }: HTMLAttributes<HTMLLIElement>) => {
  return <li {...props}>{children}</li>;
};

List.Item = ListItem;

export default List;


Enter fullscreen mode Exit fullscreen mode

And for explaining how to add List.Item as List's children, you append a custom props itemCount that how many List.Item List has.



import { useMemo } from "react";
import { ComponentStory, ComponentMeta } from "@storybook/react";

import List from "./List";

export default {
  title: "Example/List",
  component: List,
  args: {
    itemCount: 1,
  },
  argTypes: {
    itemCount: { control: "number" },
  },
} as ComponentMeta<typeof List>;

const Template: ComponentStory<typeof List> = ({ itemCount, ...args }) => {
  const liComponents = useMemo(() => {
    const components = [];

    for (let i = 1; i <= itemCount; i++) {
      components.push(<List.Item>{i} Item</List.Item>);
    }

    return components;
  }, [itemCount]);

  return <List {...args}>{liComponents}</List>;
};

export const ListExample = Template.bind({});


Enter fullscreen mode Exit fullscreen mode

When you try to use the custom prop, you would get an error message like this
Property 'itemCount' does not exist on type '[Component's Props]'..

In this case, use Meta and Story instead of ComponentMeta and ComponentStory.



import { ComponentProps, useMemo } from "react";
import { Story, Meta } from "@storybook/react";

import List from "./List";

type CustomListProps = ComponentProps<typeof List> & { itemCount: number };

export default {
  title: "Example/List",
  component: List,
  args: {
    itemCount: 1,
  },
  argTypes: {
    itemCount: { control: "number" },
  },
} as Meta<CustomListProps>;

const Template: Story<CustomListProps> = ({ itemCount, ...args }) => {
  const liComponents = useMemo(() => {
    const components = [];

    for (let i = 1; i <= itemCount; i++) {
      components.push(<List.Item>{i} Item</List.Item>);
    }

    return components;
  }, [itemCount]);

  return <List {...args}>{liComponents}</List>;
};

export const ListExample = Template.bind({});


Enter fullscreen mode Exit fullscreen mode

I defined a new custom type with union operator, and I used it Meta and Story as a generic type.

first storybook example

second storybook example

Now, you can adjust a value itemCount on the website like this.


I hope this is helpful for someone :)

Happy Coding!

Top comments (0)

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay