DEV Community

Cover image for Storybook x React x Typescript | How to manage complex props with simple control
Alexandre Fauchard for Kezios

Posted on • Originally published at kezios.fr

5 3

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 !

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

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

Okay