Skip to content
This repository was archived by the owner on Jan 31, 2024. It is now read-only.

Commit 942de96

Browse files
committed
Fix composeStories for new TS types
1 parent abacb7d commit 942de96

File tree

4 files changed

+26
-28
lines changed

4 files changed

+26
-28
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
"prettier.printWidth": 100,
88
"editor.formatOnSave": true,
99
"editor.tabSize": 2,
10-
"deepscan.enable": true
10+
"deepscan.enable": true,
11+
"typescript.tsdk": "node_modules/typescript/lib"
1112
}

example/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@
3030
"noEmit": true
3131
},
3232
"include": [
33-
"src"
33+
"src", "../../dist"
3434
]
3535
}

src/index.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { defaultDecorateStory, combineParameters, addons, applyHooks, HooksContext, mockChannel } from '@storybook/preview-api';
22
import type { ReactRenderer, Args } from '@storybook/react';
3-
import type { ComponentAnnotations, StoryContext } from '@storybook/types';
3+
import type { ComponentAnnotations, Store_CSFExports, StoryContext } from '@storybook/types';
44
import { isExportStory } from '@storybook/csf';
55

66
export { StoriesWithPartialProps } from './types';
7-
import type { GlobalConfig, StoriesWithPartialProps, StoryFile, TestingStory, TestingStoryPlayContext } from './types';
7+
import type { GlobalConfig, StoriesWithPartialProps, TestingStory, TestingStoryPlayContext } from './types';
88
import { getStoryName, globalRender, isInvalidStory, objectEntries } from './utils';
99

1010
// Some addons use the channel api to communicate between manager/preview, and this is a client only feature, therefore we must mock it.
@@ -152,8 +152,9 @@ export function composeStory<GenericArgs extends Args>(
152152
}
153153

154154
const boundPlay = ({ ...extraContext }: TestingStoryPlayContext<GenericArgs>) => {
155+
const playFn = meta.play ?? story.play ?? (() => {});
155156
// @ts-expect-error (just trying to get this to build)
156-
return story.play?.({ ...context, ...extraContext });
157+
return playFn({ ...context, ...extraContext });
157158
}
158159

159160
composedStory.storyName = story.storyName || story.name
@@ -190,19 +191,17 @@ export function composeStory<GenericArgs extends Args>(
190191
* @param storiesImport - e.g. (import * as stories from './Button.stories')
191192
* @param [globalConfig] - e.g. (import * as globalConfig from '../.storybook/preview') this can be applied automatically if you use `setGlobalConfig` in your setup files.
192193
*/
193-
export function composeStories<
194-
TModule extends StoryFile
195-
>(storiesImport: TModule, globalConfig?: GlobalConfig) {
196-
const { default: meta, __esModule, ...stories } = storiesImport;
194+
export function composeStories<TModule extends Store_CSFExports<ReactRenderer>>(storiesImport: TModule, globalConfig?: GlobalConfig) {
195+
const { default: meta, __esModule, __namedExportsOrder, ...stories } = storiesImport;
197196

198-
// This function should take this as input:
197+
// This function should take this as input:
199198
// {
200199
// default: Meta,
201200
// Primary: Story<ButtonProps>, <-- Props extends Args
202201
// Secondary: Story<OtherProps>,
203202
// }
204203

205-
// And strips out default, then return composed stories as output:
204+
// And strips out default, then return composed stories as output:
206205
// {
207206
// Primary: ComposedStory<Partial<ButtonProps>>,
208207
// Secondary: ComposedStory<Partial<OtherProps>>,
@@ -229,5 +228,5 @@ export function composeStories<
229228

230229
// @TODO: the inferred type of composedStories is correct but Partial.
231230
// investigate whether we can return an unpartial type of that without this hack
232-
return composedStories as unknown as Omit<StoriesWithPartialProps<TModule>, keyof StoryFile>;
231+
return composedStories as unknown as Omit<StoriesWithPartialProps<TModule>, keyof Store_CSFExports>;
233232
}

src/types.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import type { Addon_BaseStoryFn as OriginalBaseStoryFn, BaseAnnotations, ProjectAnnotations, StoryContext, Args, StoryAnnotations, AnnotatedStoryFn } from '@storybook/types';
2-
import type { StoryFn as OriginalStoryFn, Meta, ReactRenderer } from '@storybook/react';
3-
import type { ReactElement } from 'react';
1+
import type {
2+
AnnotatedStoryFn,
3+
Args,
4+
PlayFunction, PlayFunctionContext,
5+
ProjectAnnotations,
6+
StoryAnnotations,
7+
} from '@storybook/types';
8+
import type { ReactRenderer } from '@storybook/react';
49

5-
type StoryFnReactReturnType = ReactElement<unknown>;
6-
7-
export type BaseStoryFn<Args> = OriginalBaseStoryFn<Args, StoryFnReactReturnType> & BaseAnnotations<ReactRenderer, Args>;
810
/**
911
* Object representing the preview.ts module
1012
*
@@ -13,22 +15,18 @@ export type BaseStoryFn<Args> = OriginalBaseStoryFn<Args, StoryFnReactReturnType
1315
*/
1416
export type GlobalConfig = ProjectAnnotations<ReactRenderer>;
1517

16-
export type TestingStory<T = Args> = AnnotatedStoryFn<ReactRenderer, T> | StoryAnnotations<ReactRenderer, T>;
17-
18-
export type StoryFile = { default: Meta<any>, __esModule?: boolean }
19-
20-
export type TestingStoryPlayContext<T = Args> = Partial<StoryContext<ReactRenderer, T>> & Pick<StoryContext, 'canvasElement'>
18+
export type TestingStory<T = Args> = StoryAnnotations<ReactRenderer, T>;
2119

22-
export type TestingStoryPlayFn<TArgs = Args> = (context: TestingStoryPlayContext<TArgs>) => Promise<void> | void;
20+
export type TestingStoryPlayContext<T = Args> = Partial<PlayFunctionContext<ReactRenderer, T>> & Pick<PlayFunctionContext, 'canvasElement'>
2321

24-
export type StoryFn<TArgs = Args> = OriginalStoryFn<TArgs> & { play: TestingStoryPlayFn<TArgs> }
22+
export type StoryFn<TArgs = Args> = AnnotatedStoryFn<ReactRenderer, TArgs> & { play: PlayFunction<ReactRenderer, TArgs> }
2523

2624
/**
2725
* T represents the whole es module of a stories file. K of T means named exports (basically the Story type)
2826
* 1. pick the keys K of T that have properties that are Story<AnyProps>
2927
* 2. infer the actual prop type for each Story
3028
* 3. reconstruct Story with Partial. Story<Props> -> Story<Partial<Props>>
3129
*/
32-
export type StoriesWithPartialProps<T> = {
33-
[K in keyof T as T[K] extends TestingStory<any> ? K : never]: T[K] extends TestingStory<infer P> ? StoryFn<Partial<P>> : unknown
34-
}
30+
export type StoriesWithPartialProps<T> = {
31+
[K in keyof T]: T[K] extends StoryAnnotations<ReactRenderer, infer P> ? StoryFn<Partial<P>> : number
32+
}

0 commit comments

Comments
 (0)