mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-06 06:21:23 +08:00
Update stories args handling to cope with refs
This commit is contained in:
parent
56d7671260
commit
bc62b05735
@ -60,7 +60,7 @@ export interface SubAPI {
|
||||
parameterName?: ParameterName
|
||||
) => Story['parameters'] | any;
|
||||
getCurrentParameter<S>(parameterName?: ParameterName): S;
|
||||
updateStoryArgs(id: StoryId, newArgs: Args): void;
|
||||
updateStoryArgs(story: Story, newArgs: Args): void;
|
||||
findLeafStoryId(StoriesHash: StoriesHash, storyId: StoryId): StoryId;
|
||||
}
|
||||
|
||||
@ -257,8 +257,15 @@ export const init: ModuleFn = ({
|
||||
const childStoryId = storiesHash[storyId].children[0];
|
||||
return api.findLeafStoryId(storiesHash, childStoryId);
|
||||
},
|
||||
updateStoryArgs: (id, newArgs) => {
|
||||
fullAPI.emit(UPDATE_STORY_ARGS, id, newArgs);
|
||||
updateStoryArgs: (story, updatedArgs) => {
|
||||
const { id: storyId, refId } = story;
|
||||
fullAPI.emit(UPDATE_STORY_ARGS, {
|
||||
storyId,
|
||||
updatedArgs,
|
||||
options: {
|
||||
target: refId ? `storybook-ref-${refId}` : 'storybook-preview-iframe',
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@ -368,10 +375,36 @@ export const init: ModuleFn = ({
|
||||
}
|
||||
});
|
||||
|
||||
fullAPI.on(STORY_ARGS_UPDATED, (id: StoryId, args: Args) => {
|
||||
const { storiesHash } = store.getState();
|
||||
(storiesHash[id] as Story).args = args;
|
||||
store.setState({ storiesHash });
|
||||
fullAPI.on(STORY_ARGS_UPDATED, function handleStoryArgsUpdated({
|
||||
storyId,
|
||||
args,
|
||||
}: {
|
||||
storyId: StoryId;
|
||||
args: Args;
|
||||
}) {
|
||||
// the event originates from an iframe, event.source is the iframe's location origin + pathname
|
||||
const { source }: { source: string } = this;
|
||||
const [sourceType, sourceLocation] = getSourceType(source);
|
||||
|
||||
switch (sourceType) {
|
||||
case 'local': {
|
||||
const { storiesHash } = store.getState();
|
||||
(storiesHash[storyId] as Story).args = args;
|
||||
store.setState({ storiesHash });
|
||||
break;
|
||||
}
|
||||
case 'external': {
|
||||
const refs = fullAPI.getRefs();
|
||||
const ref = fullAPI.findRef(sourceLocation);
|
||||
(ref.stories[storyId] as Story).args = args;
|
||||
store.setState({ refs: { ...refs, [ref.id]: ref } });
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
logger.warn('received a STORY_ARGS_UPDATED frame that was not configured as a ref');
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -26,12 +26,19 @@ beforeEach(() => {
|
||||
provider.getConfig.mockReturnValue({});
|
||||
});
|
||||
|
||||
const mockSource = jest.fn();
|
||||
class LocalEventEmitter extends EventEmitter {
|
||||
on(event, callback) {
|
||||
return super.on(event, callback.bind({ source: location.toString() }));
|
||||
return super.on(event, (...args) => {
|
||||
callback.apply({ source: mockSource() }, args);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
mockSource.mockReturnValue(location.toString());
|
||||
});
|
||||
|
||||
describe('stories API', () => {
|
||||
it('sets a sensible initialState', () => {
|
||||
const { state } = initStories({
|
||||
@ -357,7 +364,7 @@ describe('stories API', () => {
|
||||
it('changes args properly, per story when receiving STORY_ARGS_UPDATED', () => {
|
||||
const navigate = jest.fn();
|
||||
const store = createMockStore();
|
||||
const api = new EventEmitter();
|
||||
const api = new LocalEventEmitter();
|
||||
|
||||
const {
|
||||
api: { setStories },
|
||||
@ -374,14 +381,34 @@ describe('stories API', () => {
|
||||
expect(initialStoriesHash['b--1'].args).toEqual({ x: 'y' });
|
||||
|
||||
init();
|
||||
api.emit(STORY_ARGS_UPDATED, 'a--1', { foo: 'bar' });
|
||||
api.emit(STORY_ARGS_UPDATED, { storyId: 'a--1', args: { foo: 'bar' } });
|
||||
|
||||
const { storiesHash: changedStoriesHash } = store.getState();
|
||||
expect(changedStoriesHash['a--1'].args).toEqual({ foo: 'bar' });
|
||||
expect(changedStoriesHash['b--1'].args).toEqual({ x: 'y' });
|
||||
});
|
||||
|
||||
it('updateStoryArgs emits UPDATE_STORY_ARGS and does not change anything', () => {
|
||||
it('changes reffed args properly, per story when receiving STORY_ARGS_UPDATED', () => {
|
||||
const navigate = jest.fn();
|
||||
const store = createMockStore();
|
||||
const api = new LocalEventEmitter();
|
||||
const ref = { id: 'refId', stories: { 'a--1': { args: { a: 'b' } } } };
|
||||
api.findRef = () => ref;
|
||||
api.getRefs = () => ({ refId: ref });
|
||||
|
||||
const { init } = initStories({ store, navigate, provider, fullAPI: api });
|
||||
|
||||
init();
|
||||
mockSource.mockReturnValueOnce('http://refId/');
|
||||
api.emit(STORY_ARGS_UPDATED, { storyId: 'a--1', args: { foo: 'bar' } });
|
||||
|
||||
const { refs } = store.getState();
|
||||
expect(refs).toEqual({
|
||||
refId: { id: 'refId', stories: { 'a--1': { args: { foo: 'bar' } } } },
|
||||
});
|
||||
});
|
||||
|
||||
it('updateStoryArgs emits UPDATE_STORY_ARGS to the local frame and does not change anything', () => {
|
||||
const navigate = jest.fn();
|
||||
const emit = jest.fn();
|
||||
const on = jest.fn();
|
||||
@ -399,13 +426,47 @@ describe('stories API', () => {
|
||||
|
||||
init();
|
||||
|
||||
updateStoryArgs('a--1', { foo: 'bar' });
|
||||
expect(emit).toHaveBeenCalledWith(UPDATE_STORY_ARGS, 'a--1', { foo: 'bar' });
|
||||
updateStoryArgs({ id: 'a--1' }, { foo: 'bar' });
|
||||
expect(emit).toHaveBeenCalledWith(UPDATE_STORY_ARGS, {
|
||||
storyId: 'a--1',
|
||||
updatedArgs: { foo: 'bar' },
|
||||
options: {
|
||||
target: 'storybook-preview-iframe',
|
||||
},
|
||||
});
|
||||
|
||||
const { storiesHash: changedStoriesHash } = store.getState();
|
||||
expect(changedStoriesHash['a--1'].args).toEqual({ a: 'b' });
|
||||
expect(changedStoriesHash['b--1'].args).toEqual({ x: 'y' });
|
||||
});
|
||||
|
||||
it('updateStoryArgs emits UPDATE_STORY_ARGS to the right frame', () => {
|
||||
const navigate = jest.fn();
|
||||
const emit = jest.fn();
|
||||
const on = jest.fn();
|
||||
const store = createMockStore();
|
||||
|
||||
const {
|
||||
api: { setStories, updateStoryArgs },
|
||||
init,
|
||||
} = initStories({ store, navigate, provider, fullAPI: { emit, on } });
|
||||
|
||||
setStories({
|
||||
'a--1': { kind: 'a', name: '1', parameters, path: 'a--1', id: 'a--1', args: { a: 'b' } },
|
||||
'b--1': { kind: 'b', name: '1', parameters, path: 'b--1', id: 'b--1', args: { x: 'y' } },
|
||||
});
|
||||
|
||||
init();
|
||||
|
||||
updateStoryArgs({ id: 'a--1', refId: 'refId' }, { foo: 'bar' });
|
||||
expect(emit).toHaveBeenCalledWith(UPDATE_STORY_ARGS, {
|
||||
storyId: 'a--1',
|
||||
updatedArgs: { foo: 'bar' },
|
||||
options: {
|
||||
target: 'storybook-ref-refId',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('jumpToStory', () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user