Storybook x React x Typescript | How to manage complex props with simple control

alexandrefauchard

Alexandre Fauchard

Posted on May 1, 2022

Storybook x React x Typescript | How to manage complex props with simple control

The problem

When you're implementing a Storybook you can change your components props with Storybook's controls. But sometimes, when you have a complex props, controls are not adapted and you may need multiple control for one props and/or have to mock some data.

The problem come with Typescript, your argTypes is waiting for a type equals to the component props type. But I have a good news ! I'm going to give you a trick to properly bypass this problem.

The trick

Let's take a "simple" complex prop as an example :
I have a component Heading with props which have this type :

type HeadingPropType = {
  text : {
    text : string
    html : ReactNode
    raw : string
  }
  image : {
    url : string
    alt : string
  }
}
Enter fullscreen mode Exit fullscreen mode

As you can see we have two props :

  • text : a string displayed in multiples format
  • image : an image url with an alt attribute which will not be very useful in a Storybook

With this type of props, Storybook will display controls which ask the user to fill an object but I guess we all agree that a string and an input file are more suitable.

We can display them simply with ArgTypes but making them work is a bit more complicated.
What you need is a HOC (Higher Order Component) which will return your component but with simplified props.

Something like this :

const componentSimplifier = <T1, T2>(
  ComplexComp: React.ComponentType<T2>,
  propsConverter: (props: T1) => T2
) => (props: T1) => <ComplexComp {...propsConverter(props)} />
Enter fullscreen mode Exit fullscreen mode

These line define the function componentSimplifier which takes two Generics Types (T1, the simple one and T2, the component props type) and two arguments :

  • ComplexComp : Simply the component you want to add in your story
  • propsConverter : A function that will convert simple props into complex ones

For our example we have :

T1 = {
  text : string
  image : string
}
T2 = HeadingPropType
ComplexComp = Heading //The component we want to display
propsConverter = ({text, image}: T1) => ({
  text : {
    text : text,
    html : <h1>${text}</h1>,
    raw : text,
  },
  image : {
    url : image,
    alt : "default alt string"
  }
})
Enter fullscreen mode Exit fullscreen mode

The final call to this function will be :

const SimpleHeadingPropsType = {
  text : string
  image : string
}

const propsConverter = ({text, image}: T1) => ({
  text : {
    text : text,
    html : <h1>${text}</h1>,
    raw : text,
  },
  image : {
    url : image,
    alt : "default alt string"
  }
})

const SimplifiedHeading = componentSimplifier<
  SimpleHeadingPropsType,
  HeadingPropType
>(
  Heading,
  propsConverter
)
Enter fullscreen mode Exit fullscreen mode

That's it ! Now you can use SimplifiedHeading in your story with adapted controls !

💖 💪 🙅 🚩
alexandrefauchard
Alexandre Fauchard

Posted on May 1, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related