-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addon-docs: forwardRef trips up Props block #8881
Comments
Mirror issue on react-docgen-typescript-loader side: strothj/react-docgen-typescript-loader#76 |
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks! |
Any Leads on this, I'm Stuck too |
@Zunaib this was fixed for me in Storybook 5.3 |
Any specific Version like 5.3.0rc ? |
Tried it out with one of the late betas (.28 or so) and it still worked with the RC |
@Zunaib I believe you need to install https://github.com/atanasster/webpack-react-docgen-typescript @jonathanherdt - can you please confirm your configuration here. |
Got it working 👌 |
Great - can you post your config and we can close this issue. |
Okay sure. Here is my config.jsimport { withKnobs } from '@storybook/addon-knobs';
import { addDecorator, addParameters, configure } from '@storybook/react';
import requireContext from 'require-context.macro';
import '../src/styles/airokit.scss';
import airotheme from './airotheme';
addParameters({
options: {
theme: airotheme,
showSearchBox: true,
sidebarAnimations: true
},
});
addDecorator(withKnobs);
const loader = () => {
const allExports = [require('../src/GetStarted/GetStarted.stories.mdx')];
const req = requireContext('../src/', true, /\.stories\.(tsx|mdx)$/);
req.keys().forEach(fname => allExports.push(req(fname)));
return allExports;
}
configure(loader, module); Here are my presets.jsconst path = require("path");
module.exports = [
{
name: "@storybook/preset-typescript",
options: {
tsDocgenLoaderOptions: {
tsconfigPath: path.resolve(__dirname, "../tsconfig.json")
},
tsLoaderOptions: {
configFile: path.resolve(__dirname, '../tsconfig.json'),
},
include: [path.resolve(__dirname, "../src")]
}
},
{
name: '@storybook/preset-scss'
},
{
name: '@storybook/addon-docs/preset'
}
]; Here is a component using ForwardRefexport const Col = forwardRef<HTMLDivElement, ColProps>(function (
{
...props
},
ref
) {
return (
<div
{...props}
ref={ref}
>
{children}
</div>
);
});
export default Col; |
Thanks - closing |
Modified: I found I have stuck in exact same problem in v5.3.14(latest release). Here's my code:
dependencies:
I tried to change |
Removing |
I had the same problem with the // does not work
export const Button: React.FunctionComponent<ButtonProps> = props => {...}
// works
export const Button: FunctionComponent<ButtonProps> = props => {...}
// does not work
export const Button3 = React.forwardRef<RawButton, ButtonProps>((props, ref) => {...}
// works
export const Button = forwardRef<RawButton, ButtonProps>((props, ref) => {...} Moreover, just changing the type while Storybook is running in watch mode does not work. You need to restart the storybook (or force a full recompilation of the file). |
Explicitly setting the tsconfig path is what worked for me: {
reactDocgenTypescriptOptions: {
tsconfigPath: path.resolve(__dirname, '../packages/package/tsconfig.json')
}
} |
If it helps anyone coming from Google there was a subtle distinction that was needed for my case: Storybook version: I was already destructuring import React, { forwardRef, ForwardedRef } from 'react';
export type CodeFieldInputProps = {
...
};
const CodeFieldInput = (
props: CodeFieldInputProps,
ref: ForwardedRef<HTMLInputElement>
) => (
<input
...
ref={ref}
/>
);
export default forwardRef<HTMLInputElement, CodeFieldInputProps>(CodeFieldInput); However the key appears to be that you need to do the invocation of import React, { forwardRef, ForwardedRef } from 'react';
export type CodeFieldInputProps = {
...
};
const CodeFieldInput = forwardRef<HTMLInputElement, CodeFieldInputProps>(
(
props: CodeFieldInputProps,
ref: ForwardedRef<HTMLInputElement>
) => (
<input
...
ref={ref}
/>
)
);
export default CodeFieldInput; Hope this saves someone some time 😃 |
Hi, I have the same issue, but I don't know how to use the solution with generics. This is my button: import { forwardRef } from 'react';
import styles from './Button.module.css';
import { ButtonProps } from './types';
/**
* Primary UI component for user interaction
*/
const ButtonBase = <T extends React.ElementType = 'button'>(
{
className = '',
as,
style = 'primary',
disabled = false,
size = 'normal',
negative = false,
icon = null,
label,
...props
}: ButtonProps<T> &
Omit<React.ComponentPropsWithRef<T>, keyof ButtonProps<T>>,
ref: React.Ref<any>
) => {
const HTMLTag = as || 'button';
return (
<HTMLTag
className={`
${styles['o-button']} \
${styles[`o-button--${size}`]} \
${styles[`o-button--${style}${negative ? '-negative' : ''}`]} \
${disabled ? styles['o-button--disabled'] : ''} \
${className} \
`}
disabled={disabled}
ref={ref}
{...props}
>
<>
{label}
{icon}
</>
</HTMLTag>
);
};
export const Button = forwardRef(ButtonBase); I tried several forms but it didn't work. Anyone have the same problem? Thanks! |
Like gius suggested simply changing
|
I had the exact same situation where I had a polymorphic component that renders a different element type based on an I redeclared the My final solution looked like this: /*
* Augment `forwardRef` only for this module so that storybook can infer controls
* (despite component being wrapped in forwardRef)
* https://fettblog.eu/typescript-react-generic-forward-refs/#option-3%3A-augment-forwardref
* https://github.com/microsoft/TypeScript/pull/30215
*/
declare module 'react' {
// eslint-disable-next-line @typescript-eslint/ban-types
function forwardRef<T, P = {}>(
render: (props: P, ref: Ref<T>) => ReactElement | null
): (props: P & RefAttributes<T>) => ReactElement | null;
}
/**
* A polymorphic component used to render html elements that contain text.
* The visual appearance of the text and the underlying html element can be controlled independently.
*/
export const Text = forwardRef(
<C extends ElementType = 'span'>(
{
as,
children,
value,
textStyle = 'P1',
textColor,
enableEllipsis = false,
enableUnderline = false,
className,
...props
}: TextProps<C>,
ref?: PolymorphicRef<C>
) => (
<TextStyledComponent
ref={ref}
as={as as keyof JSX.IntrinsicElements}
textStyle={textStyle}
enableEllipsis={enableEllipsis}
enableUnderline={enableUnderline}
textColor={textColor}
className={className}
{...props}
>
{value || children || ''}
</TextStyledComponent>
)
); |
The only solution that worked for me is
Supplying a type to forwardRef such as |
When you pass MUI component (e.g. Divider) to
If you add this code below to other file and import it to code above, use the component in
If you move that component to same file where you declare
Why is this happening? |
Describe the bug
When implementing a Component in the way described below, the Props block only shows the following text:
"Cannot read property 'appearance' of undefined"
To Reproduce
Declare a component in way mentioned under "Code snippets".
Expected behavior
The Props block should display the corresponding Props.
Screenshots
Code snippets
Button.tsx
Button.stories.tsx
System:
Tried out with both Storybook 5.2.5 and Storybook 5.3.0-beta.1, using react-docgen-typescript-loader 3.6.0.
Using stories in the TSX file format but encountered the error also when using the JSX file format.
Component is in TSX format.
Please paste the results of
npx -p @storybook/cli@next sb info
here.Additional context
Props block used to work before introducing
RefForwardingComponent
andReact.forwardRef
Possibly related to #7933, #8445, and #4787.
The text was updated successfully, but these errors were encountered: