diff --git a/lib/client-api/src/client_api.ts b/lib/client-api/src/client_api.ts index 513724f5ca0..d9f2c3c5d5c 100644 --- a/lib/client-api/src/client_api.ts +++ b/lib/client-api/src/client_api.ts @@ -3,7 +3,13 @@ import { logger } from '@storybook/client-logger'; import { StoryFn, Parameters } from '@storybook/addons'; import { toId } from '@storybook/csf'; -import { ClientApiParams, DecoratorFunction, ClientApiAddons, StoryApi } from './types'; +import { + ClientApiParams, + DecoratorFunction, + ClientApiAddons, + StoryApi, + ParameterEnhancer, +} from './types'; import { applyHooks } from './hooks'; import StoryStore from './story_store'; import { defaultDecorateStory } from './decorators'; @@ -25,6 +31,13 @@ export const addParameters = (parameters: Parameters) => { singleton.addParameters(parameters); }; +export const addParameterEnhancer = (enhancer: ParameterEnhancer) => { + if (!singleton) + throw new Error(`Singleton client API not yet initialized, cannot call addParameterEnhancer`); + + singleton.addParameterEnhancer(enhancer); +}; + export default class ClientApi { private _storyStore: StoryStore; @@ -83,6 +96,10 @@ export default class ClientApi { this._storyStore.addGlobalMetadata({ decorators: [], parameters }); }; + addParameterEnhancer = (enhancer: ParameterEnhancer) => { + this._storyStore.addParameterEnhancer(enhancer); + }; + clearDecorators = () => { this._storyStore.clearGlobalDecorators(); }; diff --git a/lib/client-api/src/index.ts b/lib/client-api/src/index.ts index 750d9a17ca6..b4d0d92c495 100644 --- a/lib/client-api/src/index.ts +++ b/lib/client-api/src/index.ts @@ -1,4 +1,4 @@ -import ClientApi from './client_api'; +import ClientApi, { addDecorator, addParameters, addParameterEnhancer } from './client_api'; import { defaultDecorateStory } from './decorators'; import StoryStore from './story_store'; import ConfigApi from './config_api'; @@ -10,6 +10,9 @@ export * from './hooks'; export { ClientApi, + addDecorator, + addParameters, + addParameterEnhancer, StoryStore, ConfigApi, defaultDecorateStory, diff --git a/lib/client-api/src/story_store.ts b/lib/client-api/src/story_store.ts index 2e6ac37f11b..0fb458ba3f3 100644 --- a/lib/client-api/src/story_store.ts +++ b/lib/client-api/src/story_store.ts @@ -8,16 +8,16 @@ import stable from 'stable'; import { Channel } from '@storybook/channels'; import Events from '@storybook/core-events'; import { logger } from '@storybook/client-logger'; -import { Comparator, Parameters, StoryFn, StoryContext } from '@storybook/addons'; +import { Comparator, Parameters, Args, StoryFn, StoryContext } from '@storybook/addons'; import { DecoratorFunction, StoryMetadata, StoreData, AddStoryArgs, StoreItem, - StoryArgs, ErrorLike, GetStorybookKind, + ParameterEnhancer, } from './types'; import { HooksContext } from './hooks'; import storySort from './storySort'; @@ -34,8 +34,6 @@ interface StoryOptions { type KindMetadata = StoryMetadata & { order: number }; -type ParameterEnhancer = (context: StoryContext) => Parameters; - const isStoryDocsOnly = (parameters?: Parameters) => { return parameters && parameters.docsOnly; }; diff --git a/lib/client-api/src/types.ts b/lib/client-api/src/types.ts index debe91e5fc4..f3e625240f7 100644 --- a/lib/client-api/src/types.ts +++ b/lib/client-api/src/types.ts @@ -21,6 +21,8 @@ export interface StoryMetadata { decorators: DecoratorFunction[]; } +export type ParameterEnhancer = (context: StoryContext) => Parameters; + export interface StoreItem extends StoryContext { id: string; kind: string; diff --git a/lib/core/src/server/preview/iframe-webpack.config.js b/lib/core/src/server/preview/iframe-webpack.config.js index 5466c277f0b..000ff2494a7 100644 --- a/lib/core/src/server/preview/iframe-webpack.config.js +++ b/lib/core/src/server/preview/iframe-webpack.config.js @@ -46,12 +46,13 @@ export default ({ if (match) { const configFilename = match[1]; virtualModuleMapping[entryFilename] = ` - import { addDecorator, addParameters } from '@storybook/${framework}'; + import { addDecorator, addParameters, addParameterEnhancer } from '@storybook/client-api'; - const { decorators, parameters } = require('${configFilename}'); + const { decorators, parameters, parameterEnhancers } = require('${configFilename}'); if (decorators) decorators.forEach(decorator => addDecorator(decorator)); if (parameters) addParameters(parameters); + if (parameterEnhancers) parameterEnhancers.forEach(enhancer => addParameterEnhancer(enhancer)); `; } });