I didn't find any answer that resolve my problem. I'm building a React Storybook with Typescript. With optional props, Storybook addon add an "undefined" option. I put a defaultProps but it doesn't take it. Do you have any solution ?
Component :
type IconType = 'outline' | 'solid'
export interface IconProps {
  name: keyof typeof icons
  size?: number
  type?: IconType
  className?: string
  fallback?:
    | boolean
    | React.ReactChild
    | React.ReactFragment
    | React.ReactPortal
    | null
}
const Icon = ({
  name,
  type = 'solid',
  className = '',
  size = 4,
  fallback = null,
}: IconProps): JSX.Element => {
  if (!name) {
    throw new Error("Can't call Icon component without name props")
  }
  const Icon = React.lazy(
    () => import(`../${type}/${icons[name]}`)
  )
  return (
    <React.Suspense fallback={fallback}>
      <Icon className={className} style={{width: size, height: size}} />
    </React.Suspense>
  )
}
Icon.defaultProps = {
  type: 'solid',
}
export default Icon
Story:
import React from 'react'
import { Story, Meta } from '@storybook/react'
import Icon, { IconProps } from '.'
export default {
  title: 'Components/Icon',
  component: Icon,
} as Meta
const Template: Story<IconProps> = (args) => <Icon {...args} />
export const Basic = Template.bind({})
Basic.args = {
  name: 'plus',
}
It shows me:

And when I select undefined it doesn't take the defaultProps of Icon ðŸ˜
I had the same problem, for me it works fine like this:
import React from 'react'
import { ComponentStory, ComponentMeta } from '@storybook/react'
import Icon, { IconProps } from '.'
export default {
  title: 'Components/Icon',
  component: Icon,
} as ComponentMeta<typeof Icon>
const Template: ComponentStory<typeof Icon> = (args: IconProps) => <Icon {...args} />
export const Basic = Template.bind({})
export const BasicArgs: IconProps = {
  name: 'plus',
}
Basic.args = BasicArgs
Also when I was trying to export and use the story somewhere else it didn't work because the type was not matching: This I was able to solve it by creating an additional typed object called BasicArgs in between and then assigning it to Basic.args in your case.
Now you can import it somewhere else and use it just like that:
import { Basic, BasicArgs } from './Icon.stories'
    
...  (
       <Basic {...BasicArgs} />
    ) ...
When setting storybook text controls, it always returns type string and sometimes I need it to be undefined. One workaround I have found is to handle it in the story and override the args.
if (args.label?.length === 0) {
    args.label = undefined;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With