-
-
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
CSF: Add typescript typings #7677
Comments
I think we already have types for a story function. |
Is this types fixed in v5.2 ? |
@kroeder Yes there are. There's a bit of a problem, and I do not know how to solve this: A CSF file doesn't have have a reference to storybook. So even if you'd be able to link the file to the fact the CSF file is exporting A StoryFn is a simple function, it's returntype is different for each viewlayer. How do we link a CSF to a storybook viewlayer? |
@ndelangen why can't the user import the right types from the appropriate package? just because CSF doesn't depend on storybook doesn't mean that "typed-CSF" can't depend on storybook. |
The user can, they are already available then I guess? |
It would be nice if there was an exported interface for the CSF metadata (default export). Consider the following: TS in strict mode will error if types for the decorators are not provided export default {
component: Event,
title: 'Event',
decorators: [
storyFn => <div style={{ backgroundColor: 'yellow' }}>{storyFn()}</div>,
],
}; Adding a import { addDecorator } from '@storybook/react';
type DecoratorFunction = Parameters<typeof addDecorator>[0];
export interface StoryMetadata {
component: React.ReactNode;
title: string;
decorators?: DecoratorFunction[];
}
// Alt 1:
const metadata: StoryMetadata = {
component: Event,
title: 'Event',
decorators: [
storyFn => <div style={{ backgroundColor: 'yellow' }}>{storyFn()}</div>,
],
};
export default metadata;
// Alt 2:
export default {
component: Event,
title: 'Event',
decorators: [
storyFn => <div style={{ backgroundColor: 'yellow' }}>{storyFn()}</div>,
],
} as StoryMetadata; |
@lirbank, I think, for decorators you can use For stories it would be like this: import { DecoratorFunction } from '@storybook/addons';
interface CSFStory<StoryFnReturnType = unknown> {
(): StoryFnReturnType;
story?: {
name?: string;
decorators?: DecoratorFunction<StoryFnReturnType>[];
parameters?: { [name: string]: unknown };
};
};
export const SimpleButton: CSFStory<JSX.Element> = () => <Button>Hello</Button>;
SimpleButton.story = {
name: 'simple button',
decorators: [storyFn => <div style={{ padding: '10px' }}>{storyFn()}</div>],
parameters: { /* ... */ }
} |
Is there already a TS type definition that we can use for the default export of a module containing stories? ATM I'm using any and it doesn't feel good :p |
Not yet. It's on the radar. |
@dsebastien or @wKich or @lirbank would you be interested in contributing to https://github.com/storybookjs/csf? |
Yes, I would like to try. |
I think interfaces could be exported here: WDYT @shilman ? |
Yeah, that would be great. I'd like to revise what's in there currently and make it better reflect what we're doing with Storybook Args, among other improvements. |
Regarding #7677 (comment) I would recommend the first and not the second solution. Here's why: import { addDecorator } from '@storybook/react';
type DecoratorFunction = Parameters<typeof addDecorator>[0];
export interface StoryMetadata {
component: React.ReactNode;
title: string;
decorators?: DecoratorFunction[];
}
// Alt 1:
// This approach is better since it forces the object to be constructed the way that the interface requires (unlike the "as" keyword that is used in Alt 2)
const metadata: StoryMetadata = {
component: Event,
title: 'Event',
decorators: [
storyFn => <div style={{ backgroundColor: 'yellow' }}>{storyFn()}</div>,
],
};
export default metadata;
// Alt 2:
export default {
component: Event,
title: 'Event',
decorators: [
storyFn => <div style={{ backgroundColor: 'yellow' }}>{storyFn()}</div>,
],
} as StoryMetadata; //<-- this doesn't force the obj to be a StoryMetadata, it coerces it. Don't do this.
// Use Alt 1 instead. |
Btw, I think that the typing for CSF should be carefully considered so that it plays nicely with react-docgen-typescript-loader since that's what everyone is using in TypeScript to generate the docs. |
@dgreene1, could you please take a look at proposal of typings and it usage in this PR ComponentDriven/csf#5? |
I think @strothj is a better person to review the typings proposal (PR ComponentDriven/csf#5) since I am not a contributor to |
We've just released zero-config typescript support in 6.0-beta. Please upgrade and test it! Thanks for your help and support getting this stable for release! |
I don't find clear instructions in any of the documentation provided there about how to properly type my exports. Referencing back to #issuecomment-612927442 the 6x beta doesn't currently export a StoryMetadata yet. Reviewing some recent merge code for Kind and Story types, I don't see a match for my own Vue needs. Both lack a template property. Is the short term solution to implement |
@lancegliser, you are right. |
@shilman Any update on |
I think this is going to end up as a 6.1 feature |
In case anyone else comes here looking, import { Meta } from '@storybook/react/types-6-0';
const meta: Meta = {
title: 'Forms/Text Area',
component: TextArea,
argTypes: {
onUpdateText: { action: 'text change' },
},
decorators: [
Component => (
<Surface
style={{ background: '#272731', width: '300px', height: '100px', padding: '10px' }}
>
<Component />
</Surface>
),
],
};
export default meta; |
Also, regarding your example, Storybook import { Meta } from '@storybook/react/types-6-0';
export default {
title: 'Forms/Text Area',
...
} as Meta; |
@shilman by doing that, however, you lose type checking. It would allow you to do: export default {
trustMe: "I am meta"
} as Meta;
However, it is still not equivalent, compare: export default {} as Meta // all fine With: const meta: Meta = {} // Error: Property 'title' is missing in type '{}' but required in type 'BaseMeta<ReactComponent>'
export default meta |
@bard Thanks for the clarification. I saw an issue in the TypeScript project saying that So let me rephrase my comment from above: until we support variable default exports in CSF, my suggestion is a partial (no pun intended) workaround. 😄 |
Hm, as soon as I import example error:
Interestingly, As a temporary workaround I avoid those imports, and rather declare my own
|
@fabb Same problem here. Did you find a way to fix it other than redeclaring a |
Totally forgot about this workaround, seems like I'm still using it. |
|
Add typescript typings for CSF:
Update monorepo examples:
**/*.stories.tsx?
The text was updated successfully, but these errors were encountered: