Make StoryFn accept Cmp or Props in all frameworks

This commit is contained in:
Kasper Peulen 2022-10-26 14:10:37 +02:00
parent be6fb1ffb6
commit 8c439a8e38
4 changed files with 39 additions and 23 deletions

View File

@ -25,7 +25,9 @@ export type Meta<CmpOrArgs = Args> = CmpOrArgs extends SvelteComponentTyped<infe
* *
* @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports) * @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports)
*/ */
export type StoryFn<TArgs = Args> = AnnotatedStoryFn<SvelteFramework, TArgs>; export type StoryFn<TCmpOrArgs = Args> = TCmpOrArgs extends SvelteComponentTyped<infer Props>
? AnnotatedStoryFn<SvelteFramework, Props>
: AnnotatedStoryFn<SvelteFramework, TCmpOrArgs>;
/** /**
* Story function that represents a CSFv3 component example. * Story function that represents a CSFv3 component example.

View File

@ -19,19 +19,20 @@ export type { Args, ArgTypes, Parameters, StoryContext } from '@storybook/types'
* *
* @see [Default export](https://storybook.js.org/docs/formats/component-story-format/#default-export) * @see [Default export](https://storybook.js.org/docs/formats/component-story-format/#default-export)
*/ */
export type Meta<TCmpOrArgs = Args> = TCmpOrArgs extends Component<any> export type Meta<TCmpOrArgs = Args> = ComponentAnnotations<
? ComponentAnnotations< VueFramework,
VueFramework, ComponentPropsOrProps<TCmpOrArgs>
unknown extends ComponentProps<TCmpOrArgs> ? TCmpOrArgs : ComponentProps<TCmpOrArgs> >;
>
: ComponentAnnotations<VueFramework, TCmpOrArgs>;
/** /**
* Story function that represents a CSFv2 component example. * Story function that represents a CSFv2 component example.
* *
* @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports) * @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports)
*/ */
export type StoryFn<TArgs = Args> = AnnotatedStoryFn<VueFramework, TArgs>; export type StoryFn<TCmpOrArgs = Args> = AnnotatedStoryFn<
VueFramework,
ComponentPropsOrProps<TCmpOrArgs>
>;
/** /**
* Story function that represents a CSFv3 component example. * Story function that represents a CSFv3 component example.
@ -43,8 +44,8 @@ export type StoryObj<TMetaOrCmpOrArgs = Args> = TMetaOrCmpOrArgs extends {
component?: infer C; component?: infer C;
args?: infer DefaultArgs; args?: infer DefaultArgs;
} }
? TMetaOrCmpOrArgs extends Component<any> ? TMetaOrCmpOrArgs extends Component<any> // needed because StoryObj<typeof Button> falls into this branch, see test
? StoryAnnotations<VueFramework, ComponentProps<TMetaOrCmpOrArgs>> ? StoryAnnotations<VueFramework, ComponentPropsOrProps<TMetaOrCmpOrArgs>>
: Simplify<ComponentProps<C> & ArgsFromMeta<VueFramework, TMetaOrCmpOrArgs>> extends infer TArgs : Simplify<ComponentProps<C> & ArgsFromMeta<VueFramework, TMetaOrCmpOrArgs>> extends infer TArgs
? StoryAnnotations< ? StoryAnnotations<
VueFramework, VueFramework,
@ -52,9 +53,7 @@ export type StoryObj<TMetaOrCmpOrArgs = Args> = TMetaOrCmpOrArgs extends {
SetOptional<TArgs, Extract<keyof TArgs, keyof DefaultArgs>> SetOptional<TArgs, Extract<keyof TArgs, keyof DefaultArgs>>
> >
: never : never
: TMetaOrCmpOrArgs extends Component<any> : StoryAnnotations<VueFramework, ComponentPropsOrProps<TMetaOrCmpOrArgs>>;
? StoryAnnotations<VueFramework, ComponentProps<TMetaOrCmpOrArgs>>
: StoryAnnotations<VueFramework, TMetaOrCmpOrArgs>;
type ComponentProps<C> = C extends ExtendedVue<any, any, any, any, infer P> type ComponentProps<C> = C extends ExtendedVue<any, any, any, any, infer P>
? P ? P
@ -62,6 +61,12 @@ type ComponentProps<C> = C extends ExtendedVue<any, any, any, any, infer P>
? P ? P
: unknown; : unknown;
type ComponentPropsOrProps<TCmpOrArgs> = TCmpOrArgs extends Component<any>
? unknown extends ComponentProps<TCmpOrArgs>
? TCmpOrArgs
: ComponentProps<TCmpOrArgs>
: TCmpOrArgs;
/** /**
* @deprecated Use `StoryFn` instead. * @deprecated Use `StoryFn` instead.
* Use `StoryObj` if you want to migrate to CSF3, which uses objects instead of functions to represent stories. * Use `StoryObj` if you want to migrate to CSF3, which uses objects instead of functions to represent stories.

View File

@ -3,11 +3,11 @@ import { ComponentAnnotations, StoryAnnotations } from '@storybook/csf';
import { expectTypeOf } from 'expect-type'; import { expectTypeOf } from 'expect-type';
import { SetOptional } from 'type-fest'; import { SetOptional } from 'type-fest';
import { ComponentOptions, FunctionalComponent, h } from 'vue'; import { ComponentOptions, FunctionalComponent, h } from 'vue';
import Button from './__tests__/Button.vue';
import Decorator2TsVue from './__tests__/Decorator2.vue';
import DecoratorTsVue from './__tests__/Decorator.vue';
import { DecoratorFn, Meta, StoryObj } from './public-types'; import { DecoratorFn, Meta, StoryObj } from './public-types';
import { VueFramework } from './types'; import { VueFramework } from './types';
import Button from './__tests__/Button.vue';
import DecoratorTsVue from './__tests__/Decorator.vue';
import Decorator2TsVue from './__tests__/Decorator2.vue';
describe('Meta', () => { describe('Meta', () => {
test('Generic parameter of Meta can be a component', () => { test('Generic parameter of Meta can be a component', () => {

View File

@ -17,16 +17,20 @@ import type { VueFramework } from './types';
* *
* @see [Default export](https://storybook.js.org/docs/formats/component-story-format/#default-export) * @see [Default export](https://storybook.js.org/docs/formats/component-story-format/#default-export)
*/ */
export type Meta<TCmpOrArgs = Args> = TCmpOrArgs extends ComponentOptions<infer Props> export type Meta<TCmpOrArgs = Args> = ComponentAnnotations<
? ComponentAnnotations<VueFramework, unknown extends Props ? TCmpOrArgs : Props> VueFramework,
: ComponentAnnotations<VueFramework, TCmpOrArgs>; ComponentPropsOrProps<TCmpOrArgs>
>;
/** /**
* Story function that represents a CSFv2 component example. * Story function that represents a CSFv2 component example.
* *
* @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports) * @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports)
*/ */
export type StoryFn<TArgs = Args> = AnnotatedStoryFn<VueFramework, TArgs>; export type StoryFn<TCmpOrArgs = Args> = AnnotatedStoryFn<
VueFramework,
ComponentPropsOrProps<TCmpOrArgs>
>;
/** /**
* Story function that represents a CSFv3 component example. * Story function that represents a CSFv3 component example.
@ -47,15 +51,20 @@ export type StoryObj<TMetaOrCmpOrArgs = Args> = TMetaOrCmpOrArgs extends {
SetOptional<TArgs, Extract<keyof TArgs, keyof DefaultArgs>> SetOptional<TArgs, Extract<keyof TArgs, keyof DefaultArgs>>
> >
: never : never
: TMetaOrCmpOrArgs extends ConcreteComponent<any> : StoryAnnotations<VueFramework, ComponentPropsOrProps<TMetaOrCmpOrArgs>>;
? StoryAnnotations<VueFramework, ComponentProps<TMetaOrCmpOrArgs>>
: StoryAnnotations<VueFramework, TMetaOrCmpOrArgs>;
type ComponentProps<C> = C extends ComponentOptions<infer P> type ComponentProps<C> = C extends ComponentOptions<infer P>
? P ? P
: C extends FunctionalComponent<infer P> : C extends FunctionalComponent<infer P>
? P ? P
: unknown; : unknown;
type ComponentPropsOrProps<TCmpOrArgs> = TCmpOrArgs extends ConcreteComponent<any>
? unknown extends ComponentProps<TCmpOrArgs>
? TCmpOrArgs
: ComponentProps<TCmpOrArgs>
: TCmpOrArgs;
/** /**
* @deprecated Use `StoryFn` instead. * @deprecated Use `StoryFn` instead.
* Use `StoryObj` if you want to migrate to CSF3, which uses objects instead of functions to represent stories. * Use `StoryObj` if you want to migrate to CSF3, which uses objects instead of functions to represent stories.