storybook: Storybook templates do not handle default prop values correctly if they are objects
Describe the bug Storybook templates do not appear to handle props default values correctly if they are complex objects. The default value using the template bind is yielding the expression as a string instead of evaluating it.
To Reproduce/Code snippets
Disclaimer: i really dumbed down the example, so i haven’t checked for typos and so on… just to illustrate the problem
Component example
import { Option } from "prelude-ts";
import React from "react";
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
customPlaceholder?: Option<string>;
}
const Input: React.FC<InputProps> = ({
customPlaceholder = Option.none(),
...otherProps
}) => (
<input placeholder={customPlaceholder.getOrUndefined()} {...otherProps} />
);
export default Input;
And the following story:
type InputStoryComponentProps = React.ComponentProps<typeof Input> & {
label: string;
};
const InputTemplate: InputStoryComponentProps = ({ label, ...otherArgs }) => (
<div>
<span>{label}</span>
<Input {...otherArgs} />
</div>
);
export const DefaultInput = InputTemplate.bind({});
DefaultInput.storyName = "Default input";
Opening the story in storybook i get the following:
customPlaceholder.getOrUndefined is not a function
Debugging it, i discovered that using the template, the props is being initialized with “Option.none()” instead of the actual evaluated Option.none(), which of course yield the previous error.
If i don’t use the template, and just write a story, it works perfectly fine (of course i end up duplicating alot of code between the real case complex stories which was the main point of using the template).
Expected behavior Default prop values are properly initialised as evaluated and not passed as a string
System:
Environment Info:
Binaries:
Node: 14.7.0 - ~/.nvm/versions/node/v14.7.0/bin/node
npm: 6.14.7 - ~/.nvm/versions/node/v14.7.0/bin/npm
Browsers:
Chrome: 85.0.4183.102
Firefox: 80.0.1
Safari: 13.1.2
npmPackages:
@storybook/addon-actions: ^6.0.21 => 6.0.21
@storybook/addon-docs: ^6.0.21 => 6.0.21
@storybook/addon-knobs: ^6.0.21 => 6.0.21
@storybook/addon-links: ^6.0.21 => 6.0.21
@storybook/addons: ^6.0.21 => 6.0.21
@storybook/preset-create-react-app: ^3.1.4 => 3.1.4
@storybook/react: ^6.0.21 => 6.0.21
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 8
- Comments: 17 (3 by maintainers)
A workaround that I’ve used that I think is elegant is to apply the component’s default props as default args at the component level, e.g.:
This correctly applies functions and objects as props. Remember to configure your JSX addon (see the react-element-to-jsx-string part) to not show default props in the code snippets 🙂
Hey folks 😃
Just wanna check if it’s going to be solved any time soon? It’s not that obvious issue and I guess it becomes really frustrating for lots of people as they don’t even have an idea what’s broken and how to google about it 😃
I would just fill the args with a deep copy of defaultProps, and modify properties on separate lines. This should work everywhere and without side-effects because defaultProps have to be able to be JSON stringified.
If you had lodash and were so inclined, you could also create a function which hid some messiness, allowing you to write your stories like you wanted to in the first place:
It would be nice to mention this somewhere. I didn’t know if I am missing something in my configuration.