-
-
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
How to add docs for TypeScript extended types? #13637
Comments
Is this what you are looking for? https://storybook.js.org/docs/react/configure/typescript |
Using typescript: {
reactDocgen: 'react-docgen-typescript',
reactDocgenTypescriptOptions: {
compilerOptions: {
allowSyntheticDefaultImports: false,
esModuleInterop: false,
},
},
}, With the following story: import {
Meta,
Story,
} from '@storybook/react/types-6-0';
import React from 'react';
import Code, { Props } from '@/common/components/dataDisplay/Code';
export default {
title: 'Next Right Now/Data display/Code',
component: Code,
argTypes: {},
} as Meta;
const defaultText = `
import { css } from '@emotion/react';
import React from 'react';
import AnimatedLoader from '../svg/AnimatedLoader';
export type Props = {}
const Loader: React.FunctionComponent<Props> = (props): JSX.Element => {
return (
<div
css={css\`
justify-content: center;
text-align: center;
margin-left: auto;
margin-right: auto;
\`}
>
<AnimatedLoader />
</div>
);
};
export default Loader;
`;
const Template: Story<Props> = (props) => {
return (
<Code
text={defaultText}
{...props}
/>
);
};
export const DynamicExample: Story<Props> = Template.bind({});
DynamicExample.args = {
text: defaultText,
}; Generates the doc: I lose all props that aren't defined in the story. Using the same component with typescript: {
check: false,
checkOptions: {},
reactDocgen: 'react-docgen-typescript',
reactDocgenTypescriptOptions: {
shouldExtractLiteralValuesFromEnum: true,
propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
},
}, Basically, using a custom |
This is default behaviour of react-docgen-typescript: typings of |
Turning this configuration on, however, might also not be what you want: You really do see ALL props. |
Yeah, I had tried that and it was way too noisy to be usable. |
The only possible route then is: turn the config on to see ALL types and build your own types Possibly, a lot of effort. |
What would be really fantastic: if react-docgen-typescript would create seperate documentation tabs per extended interface / type |
@texttechne There's an open issue for that here. I've been meaning to fix it for months but other things have taken priority. #7943 |
@shilman Thanks for the linked context! Cool, that this feature is already planned. 👍 If Storybook provides this feature of making huge type hierarchies browsable, then this issue is solved en-passant. This would actually be a huge and really cool feature. Apart from that, there's nothing that Storybook can do: The rest has to be solved in TypeScript-land. In the end it's a problem with the typings themselves that we are facing. The typings of HTMLElements (provided by React, e.g. ButtonHTMLAttributes, HTMLAttributes) are just they way they are: really exhaustive, not modular and probably quite imperfect. |
Here is what we can do with TypeScript: Build our own interface without the need to redefine known props. ExampleMy component: Autocomplete // Magic TS helper function
type ExcludedTypes<T, U> = {
[K in Exclude<keyof T, keyof U>]: T[K];
};
// exclude all props belonging to standard HTML elements
type ReducedMultiInputProps = ExcludedTypes<MultiInputPropTypes, HTMLAttributes<HTMLElement>>;
// pick only those props which we do care about
type SharedProps = Pick<MultiInputPropTypes, "style" | "className" | "id" | "onChange" | "placeholder">;
// union of previous prop sets and exclude props of the library interface, that we don't want
type WantedMultiInputProps = SharedProps | Omit<ReducedMultiInputProps, "tokens">;
// finally: union of the wanted props with our own props
export type AutoCompleteProps =
| WantedMultiInputProps
| {
values?: AutoCompleteItemsProps;
suggestions?: Array<string>;
}; ResultThe docs now only show the following props:
Conclusion
|
I want to see my props plus all the mantine props in the storybook but seems like only props defined by me are shown in the storybook My type files
My storyBook file
The StoryBook output just displays
and not the other mantine props i tried configuring both vite plugin and storybook main with Tried Plugins: @joshwooding/vite-plugin-react-docgen-typescript, react-docgen-typescript-vite-plugin tried both react doc-gen configs
and
Even tried
|
I have the same issue as @Snivio reported. With MaterialUI I can choose using
but then I can't set any other prop that's not picked, for example
Now, using this component in other places anything that's passed on via
|
Hi @gerardparareda, that's a different issue. You're not extending some base props and adding new props to it. The issue there is that the base props from which the own interface extends are not shown. By using But what are you trying to achieve by picking? Do you rather want to |
Thanks @texttechne, I understand what you mean. What I want is for the controls to show only my picked types and keep using the rest of the types when using the component directly. For example using Does this go against the Storybook workflow? Does everything I use need to be picked? I don't need to show all the controls MUI components offer. |
Hey @gerardparareda, your use case is really a different one: Actually you want to exploit the described bug 😄. However, I am unable to formulate this properly in TS: // here we're extending two times => now, nothing should be visible
export interface MyTypoProps extends Pick<BaseTypoProps, "children" | "variant">, BaseTypoProps {}
// semantically the same as above, but now you would see every prop again, which makes the picking part pretty useless
export type MyTypoProps = Pick<BaseTypoProps, "children" | "variant"> & BaseTypoProps I'm not claiming it's impossible, but I just don't see right now how to do that... Alternatively, here are my 2 cents: I would recommend to use |
The "problem" with both solutions is that the same interface used in the component constructor is used in the storybook controls. So, whatever I do, either I have all the controls and props of a MUI component or I'm going to miss a lot of functionality in exchange for visibility. |
By omitting the more verbose typings, I'm seeing good results at getting extended types from external libraries with:
I might play with it more, but our controls and mdx docs are more comprehensive now. |
@Snivio I was able to get Mantine props to show within storybook using the following config. This is the same config I use for Material-UI. I just changed the prop filter. // .storybook/main.ts
typescript: {
check: false,
/**
* For improved speed use react-docgen instead of react-docgen-typescript
* Use react-docgen-typescript for verbose documentation of mantine components
*/
reactDocgen: "react-docgen-typescript", // use react-docgen instead of react-docgen-typescript to improve speed
reactDocgenTypescriptOptions: {
// Speeds up Storybook build time
compilerOptions: {
allowSyntheticDefaultImports: false,
esModuleInterop: false,
},
// Makes union prop types like variant and size appear as select controls
shouldExtractLiteralValuesFromEnum: true,
// Makes string and boolean types that can be undefined appear as inputs and switches
shouldRemoveUndefinedFromOptional: true,
// Filter out third-party props from node_modules except @mantine packages
propFilter: (prop) =>
prop.parent
? !/node_modules\/(?!@mantine)/.test(prop.parent.fileName)
: true,
}, |
I use the following type:
The extended type is
But Storybook renders only the props defined in
Props
, not those inCodeBlockProps
.Is it the expected behaviour? I'm still new to storybook, I had seen something about TS types extending somewhere but can't find it again.
The text was updated successfully, but these errors were encountered: