mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-07 07:21:17 +08:00
Added basic global args mechanism to story_store
This commit is contained in:
parent
c64b99d6b8
commit
d75b4e09a0
@ -85,7 +85,7 @@ describe('preview.story_store', () => {
|
||||
});
|
||||
|
||||
describe('args', () => {
|
||||
it('args is initialized to the value stored in parameters.args[name] || parameters.argType[name].defaultValue', () => {
|
||||
it('is initialized to the value stored in parameters.args[name] || parameters.argType[name].defaultValue', () => {
|
||||
const store = new StoryStore({ channel });
|
||||
addStoryToStore(store, 'a', '1', () => 0, {
|
||||
argTypes: {
|
||||
@ -201,6 +201,111 @@ describe('preview.story_store', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('globalArgs', () => {
|
||||
it.skip('is initialized to the value stored in parameters.globalArgTypes[name].defaultValue', () => {
|
||||
const store = new StoryStore({ channel });
|
||||
addStoryToStore(store, 'a', '1', () => 0, {
|
||||
argTypes: {
|
||||
arg1: { defaultValue: 'arg1' },
|
||||
arg2: { defaultValue: 2 },
|
||||
arg3: { defaultValue: { complex: { object: ['type'] } } },
|
||||
},
|
||||
});
|
||||
expect(store.getRawStory('a', '1').args).toEqual({
|
||||
arg1: 'arg1',
|
||||
arg2: 2,
|
||||
arg3: { complex: { object: ['type'] } },
|
||||
});
|
||||
});
|
||||
|
||||
it('setGlobalArgs changes the global args', () => {
|
||||
const store = new StoryStore({ channel });
|
||||
addStoryToStore(store, 'a', '1', () => 0);
|
||||
expect(store.getRawStory('a', '1').globalArgs).toEqual({});
|
||||
|
||||
store.setGlobalArgs({ foo: 'bar' });
|
||||
expect(store.getRawStory('a', '1').globalArgs).toEqual({ foo: 'bar' });
|
||||
|
||||
store.setGlobalArgs({ baz: 'bing' });
|
||||
expect(store.getRawStory('a', '1').globalArgs).toEqual({ foo: 'bar', baz: 'bing' });
|
||||
});
|
||||
|
||||
it('is passed to the story in the context', () => {
|
||||
const storyFn = jest.fn();
|
||||
const store = new StoryStore({ channel });
|
||||
|
||||
store.setGlobalArgs({ foo: 'bar' });
|
||||
addStoryToStore(store, 'a', '1', storyFn);
|
||||
store.getRawStory('a', '1').storyFn();
|
||||
|
||||
expect(storyFn).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
globalArgs: { foo: 'bar' },
|
||||
})
|
||||
);
|
||||
|
||||
store.setGlobalArgs({ baz: 'bing' });
|
||||
store.getRawStory('a', '1').storyFn();
|
||||
|
||||
expect(storyFn).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
globalArgs: { foo: 'bar', baz: 'bing' },
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('setGlobalArgs emits GLOBAL_ARGS_CHANGED', () => {
|
||||
const onGlobalArgsChangedChannel = jest.fn();
|
||||
const testChannel = mockChannel();
|
||||
testChannel.on(Events.GLOBAL_ARGS_CHANGED, onGlobalArgsChangedChannel);
|
||||
|
||||
const store = new StoryStore({ channel: testChannel });
|
||||
addStoryToStore(store, 'a', '1', () => 0);
|
||||
|
||||
store.setGlobalArgs({ foo: 'bar' });
|
||||
expect(onGlobalArgsChangedChannel).toHaveBeenCalledWith({ foo: 'bar' });
|
||||
|
||||
store.setGlobalArgs({ baz: 'bing' });
|
||||
expect(onGlobalArgsChangedChannel).toHaveBeenCalledWith({ foo: 'bar', baz: 'bing' });
|
||||
});
|
||||
|
||||
it('should update if the CHANGE_GLOBAL_ARGS event is received', () => {
|
||||
const testChannel = mockChannel();
|
||||
const store = new StoryStore({ channel: testChannel });
|
||||
addStoryToStore(store, 'a', '1', () => 0);
|
||||
|
||||
testChannel.emit(Events.CHANGE_GLOBAL_ARGS, { foo: 'bar' });
|
||||
|
||||
expect(store.getRawStory('a', '1').globalArgs).toEqual({ foo: 'bar' });
|
||||
});
|
||||
|
||||
it('DOES NOT pass globalArgs as the first argument to the story if `parameters.passArgsFirst` is true', () => {
|
||||
const store = new StoryStore({ channel });
|
||||
|
||||
const storyOne = jest.fn();
|
||||
addStoryToStore(store, 'a', '1', storyOne);
|
||||
|
||||
store.setGlobalArgs({ foo: 'bar' });
|
||||
|
||||
store.getRawStory('a', '1').storyFn();
|
||||
expect(storyOne).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
globalArgs: { foo: 'bar' },
|
||||
})
|
||||
);
|
||||
|
||||
const storyTwo = jest.fn();
|
||||
addStoryToStore(store, 'a', '2', storyTwo, { passArgsFirst: true });
|
||||
store.getRawStory('a', '2').storyFn();
|
||||
expect(storyTwo).toHaveBeenCalledWith(
|
||||
{},
|
||||
expect.objectContaining({
|
||||
globalArgs: { foo: 'bar' },
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parameterEnhancer', () => {
|
||||
it('allows you to alter parameters when stories are added', () => {
|
||||
const store = new StoryStore({ channel });
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
StoreData,
|
||||
AddStoryArgs,
|
||||
StoreItem,
|
||||
PublishedStoreItem,
|
||||
ErrorLike,
|
||||
GetStorybookKind,
|
||||
ParameterEnhancer,
|
||||
@ -75,6 +76,8 @@ export default class StoryStore {
|
||||
|
||||
_configuring: boolean;
|
||||
|
||||
_globalArgs: Args;
|
||||
|
||||
_globalMetadata: StoryMetadata;
|
||||
|
||||
// Keyed on kind name
|
||||
@ -92,6 +95,8 @@ export default class StoryStore {
|
||||
constructor(params: { channel: Channel }) {
|
||||
// Assume we are configuring until we hear otherwise
|
||||
this._configuring = true;
|
||||
|
||||
this._globalArgs = {};
|
||||
this._globalMetadata = { parameters: {}, decorators: [] };
|
||||
this._kinds = {};
|
||||
this._stories = {};
|
||||
@ -115,6 +120,10 @@ export default class StoryStore {
|
||||
this._channel.on(Events.CHANGE_STORY_ARGS, (id: string, newArgs: Args) =>
|
||||
this.setStoryArgs(id, newArgs)
|
||||
);
|
||||
|
||||
this._channel.on(Events.CHANGE_GLOBAL_ARGS, (newGlobalArgs: Args) =>
|
||||
this.setGlobalArgs(newGlobalArgs)
|
||||
);
|
||||
}
|
||||
|
||||
startConfiguring() {
|
||||
@ -247,6 +256,7 @@ export default class StoryStore {
|
||||
parameters,
|
||||
hooks,
|
||||
args: _stories[id].args,
|
||||
globalArgs: this._globalArgs,
|
||||
});
|
||||
|
||||
// Pull out parameters.args.$ || .argTypes.$.defaultValue into initialArgs
|
||||
@ -306,7 +316,20 @@ export default class StoryStore {
|
||||
}, {});
|
||||
}
|
||||
|
||||
fromId = (id: string): StoreItem | null => {
|
||||
setGlobalArgs(newGlobalArgs: Args) {
|
||||
this._globalArgs = { ...this._globalArgs, ...newGlobalArgs };
|
||||
this._channel.emit(Events.GLOBAL_ARGS_CHANGED, this._globalArgs);
|
||||
}
|
||||
|
||||
setStoryArgs(id: string, newArgs: Args) {
|
||||
if (!this._stories[id]) throw new Error(`No story for id ${id}`);
|
||||
const { args } = this._stories[id];
|
||||
this._stories[id].args = { ...args, ...newArgs };
|
||||
|
||||
this._channel.emit(Events.STORY_ARGS_CHANGED, id, this._stories[id].args);
|
||||
}
|
||||
|
||||
fromId = (id: string): PublishedStoreItem | null => {
|
||||
try {
|
||||
const data = this._stories[id as string];
|
||||
|
||||
@ -314,7 +337,10 @@ export default class StoryStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
return data;
|
||||
return {
|
||||
...data,
|
||||
globalArgs: this._globalArgs,
|
||||
};
|
||||
} catch (e) {
|
||||
logger.warn('failed to get story:', this._stories);
|
||||
logger.error(e);
|
||||
@ -434,14 +460,6 @@ export default class StoryStore {
|
||||
this.getStoriesForKind(kind).map(story => this.cleanHooks(story.id));
|
||||
}
|
||||
|
||||
setStoryArgs(id: string, newArgs: Args) {
|
||||
if (!this._stories[id]) throw new Error(`No story for id ${id}`);
|
||||
const { args } = this._stories[id];
|
||||
this._stories[id].args = { ...args, ...newArgs };
|
||||
|
||||
this._channel.emit(Events.STORY_ARGS_CHANGED, id, this._stories[id].args);
|
||||
}
|
||||
|
||||
// This API is a reimplementation of Storybook's original getStorybook() API.
|
||||
// As such it may not behave *exactly* the same, but aims to. Some notes:
|
||||
// - It is *NOT* sorted by the user's sort function, but remains sorted in "insertion order"
|
||||
|
@ -39,6 +39,10 @@ export type StoreItem = StoryIdentifier & {
|
||||
args: Args;
|
||||
};
|
||||
|
||||
export type PublishedStoreItem = StoreItem & {
|
||||
globalArgs: Args;
|
||||
};
|
||||
|
||||
export interface StoreData {
|
||||
[key: string]: StoreItem;
|
||||
}
|
||||
|
@ -23,6 +23,9 @@ enum events {
|
||||
CHANGE_STORY_ARGS = 'changeStoryArgs',
|
||||
// The values of a stories args just changed
|
||||
STORY_ARGS_CHANGED = 'storyArgsChanged',
|
||||
// As above
|
||||
CHANGE_GLOBAL_ARGS = 'changeGlobalArgs',
|
||||
GLOBAL_ARGS_CHANGED = 'globalArgsChanged',
|
||||
REGISTER_SUBSCRIPTION = 'registerSubscription',
|
||||
// Tell the manager that the user pressed a key in the preview
|
||||
PREVIEW_KEYDOWN = 'previewKeydown',
|
||||
@ -56,6 +59,8 @@ export const {
|
||||
STORY_THREW_EXCEPTION,
|
||||
CHANGE_STORY_ARGS,
|
||||
STORY_ARGS_CHANGED,
|
||||
CHANGE_GLOBAL_ARGS,
|
||||
GLOBAL_ARGS_CHANGED,
|
||||
REGISTER_SUBSCRIPTION,
|
||||
PREVIEW_KEYDOWN,
|
||||
SELECT_STORY,
|
||||
|
Loading…
x
Reference in New Issue
Block a user