I have a Chip
component that accepts an extra element from its leftSection
prop, a ReactNode
. One of the possible uses is to render a ColorSwatch
.
Then, I have the following story metadata:
const meta = {
component: Chip,
argTypes: {
label: { control: 'text' },
leftSection: {
control: 'select',
options: ['none', 'swatch'],
},
swatchColor: {
control: 'color',
if: { arg: 'leftSection', eq: 'swatch' },
},
},
} as Meta<Component>;
The Chip
component doesn't have the swatchColor
prop. It's defined only on the storybook for editing its value on the storybook itself.
But when writing the story object, it raises a type error:
export const Default: StoryObj<Component> = {
render: (args) => {
const { leftSection, swatchColor, ...rest } = args;
// ^ type error here: Property 'swatchColor' does not exist
if (leftSection === 'swatch') {
return (
<Chip
leftSection={<ColorSwatch color={swatchColor} />}
{...rest}
/>
);
}
return <Chip {...rest} />;
},
args: {
label: 'foo',
leftSection: 'none',
},
};
Despite it works, I would like to fix the type error at the same time that I have type safety.
Is there a way to have extra controls on the story and still make the TS/Storybook happy?
We can append on the component's Prop
our custom story props, and use it instead of Component
.
import Chip, { Props } from './Chip';
type CustomStoryProps = { swatchColor: string };
type Component = Props & CustomStoryProps;
const meta: Meta<Component> = {
// ^ type safer than using `as` ✅
}
export const Default: StoryObj<Component> = {
render: (args) => {
const { leftSection, swatchColor, ...rest } = args;
// ^ no more errors ✅