UNPKG

2.54 kBJavaScriptView Raw
1import "core-js/modules/es.array.reduce.js";
2
3function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
4
5const defaultContext = {
6 id: 'unspecified',
7 name: 'unspecified',
8 kind: 'unspecified',
9 parameters: {},
10 args: {},
11 argTypes: {},
12 globals: {}
13};
14export const decorateStory = (storyFn, decorator, bindWithContext) => {
15 // Bind the partially decorated storyFn so that when it is called it always knows about the story context,
16 // no matter what it is passed directly. This is because we cannot guarantee a decorator will
17 // pass the context down to the next decorated story in the chain.
18 const boundStoryFunction = bindWithContext(storyFn);
19 return context => decorator(boundStoryFunction, context);
20};
21export const defaultDecorateStory = (storyFn, decorators) => {
22 // We use a trick to avoid recreating the bound story function inside `decorateStory`.
23 // Instead we pass it a context "getter", which is defined once (at "decoration time")
24 // The getter reads a variable which is scoped to this call of `decorateStory`
25 // (ie to this story), so there is no possibility of overlap.
26 // This will break if you call the same story twice interleaved
27 // (React might do it if you rendered the same story twice in the one ReactDom.render call, for instance)
28 const contextStore = {
29 value: defaultContext
30 };
31 /**
32 * When you call the story function inside a decorator, e.g.:
33 *
34 * ```jsx
35 * <div>{storyFn({ foo: 'bar' })}</div>
36 * ```
37 *
38 * This will override the `foo` property on the `innerContext`, which gets
39 * merged in with the default context
40 */
41
42 const bindWithContext = decoratedStoryFn => // (NOTE: You cannot override the parameters key, it is fixed)
43 (_ref = {}) => {
44 let contextUpdate = _objectWithoutPropertiesLoose(_ref, ["id", "name", "kind", "parameters"]);
45
46 contextStore.value = Object.assign({}, contextStore.value, contextUpdate);
47 return decoratedStoryFn(contextStore.value);
48 };
49
50 const decoratedWithContextStore = decorators.reduce((story, decorator) => decorateStory(story, decorator, bindWithContext), storyFn);
51 return (context = defaultContext) => {
52 contextStore.value = context;
53 return decoratedWithContextStore(context); // Pass the context directly into the first decorator
54 };
55};
\No newline at end of file