SeongKuk Han
Posted on October 12, 2022
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;
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({});
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({});
I defined a new custom type with union operator, and I used it Meta
and Story
as a generic type.
Now, you can adjust a value itemCount
on the website like this.
I hope this is helpful for someone :)
Happy Coding!
Posted on October 12, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.