storybook
storybook copied to clipboard
[Bug]: Typescript optional function is not default to undefined in story
Describe the bug
When I create a component and set a property to optional function and then try to test the story I see storybook create a mock function and sent it to component as default
For example
interface Props{
onChange?: () => void
}
And here is code generated from storybook
<Component onChange={() => {}} />
Even in example that generate by default, in Button component onClick
is optional but storybook still ignore it and add it by default even when argTypes
and args
are empty
Im not sure What i should to reproduce as this issue exist in the default example in Button component
To Reproduce
https://stackblitz.com/github/storybookjs/sandboxes/tree/next/react-vite/default-ts/after-storybook?file=src%2Fstories%2FButton.stories.ts&preset=node
System
No response
Additional context
No response
This is a problem with how Storybook's Source block works today. It's taking the React element that is the result of rendering the story and trying to turn that into a string. As far as I know those functions don't stringify cleanly, so we just put () => {}
as a placeholder. We are open to suggestions about how we might do this differently.
This is a problem with how Storybook's Source block works today. It's taking the React element that is the result of rendering the story and trying to turn that into a string. As far as I know those functions don't stringify cleanly, so we just put
() => {}
as a placeholder. We are open to suggestions about how we might do this differently.
I don't think it should be () => {}
, because I mark the parameter as optional, so It should be never defined at all.
@shilman I think this could be improved. The optional prop onChange
that the user has not specified, is provided to the React component, actually by ArgsEnhancer
s in @storybook/addon-actions
and @storybook/addon-interactions
. The additional args
provided by these addons are merged into context.initialArgs
, which originally only contains what the user has specified in story's args
. So if we could track separately the args that users have explicitly provided in their stories (separate from those added by addons and enhancers, etc), we're able to use this information to generate code snippets that only contains user-specified props, in the docs page.
I'm planning to write a feature request for this, so I'll let you know once more when I submit it.
I think I am having the same issue here using Storybook 6.5.X. Here's the short version of ours:
"use client";
import React, { useState } from "react";
export interface BarChartProps extends BaseChartProps {
+ onValueChange?: (value: any) => void;
}
const BarChart = React.forwardRef<HTMLDivElement, BarChartProps>((props, ref) => {
const {
data = [],
categories = [],
+ onValueChange,
className,
...other
} = props;
const [activeBar, setActiveBar] = React.useState<any | undefined>(undefined);
function onBarClick(data: any, index: number, event: React.MouseEvent) {
event.stopPropagation();
+ if (onValueChange == null) return; // not working, because onValueChange in not undefined, but "ƒ () {return fn2.apply(this, arguments);}"
if (deepEqual(activeBar, data.tooltipPosition)) {
setActiveBar(undefined);
} else {
setActiveBar(data.tooltipPosition);
onValueChange?.({
...data.payload,
dataKeyClicked: data.tooltipPayload[0]?.dataKey,
});
}
}
const yAxisDomain = getYAxisDomain(autoMinValue, minValue, maxValue);
return (
<div ref={ref} className={tremorTwMerge("w-full h-80", className)} {...other}>
<ResponsiveContainer className="h-full w-full">
{data?.length ? (
<ReChartsBarChart
// ...
Same issue here. Even when I define the prop with undefined
in the default story, it still applies the mock function, and therefore rendering something conditionally with the prop does not work. Any updates on this?
Also running into this, was a bit confused why my conditional logic didn't work in Storybook, and found this issue.
EDIT: My function was named onHelpClicked
and I had actions: { argTypesRegex: '^on[A-Z].*' },
in my preview.tsx
file, removing that fixed it ... but I don't really want to remove it. Oh well.