Emit a STORY_ARGS_UPDATED event whenever the current story's implementation changes.

This means things like the `ArgsTable` can keep up to date.

NOTE: this does not work if a different story to the the "selected" story is updated in docs mode, which can be visible on the screen. This is a symptom of a larger problem in the way that docs mode works.
This commit is contained in:
Tom Coleman 2021-10-27 16:17:10 +11:00
parent b4afd45ecf
commit 2504e5a3d2
2 changed files with 28 additions and 7 deletions

View File

@ -1973,6 +1973,20 @@ describe('PreviewWeb', () => {
});
});
it('emits STORY_ARGS_UPDATED with new args', async () => {
document.location.search = '?id=component-one--a';
const preview = await createAndRenderPreview();
mockChannel.emit.mockClear();
preview.onStoriesChanged({ importFn: newImportFn });
await waitForRender();
expect(mockChannel.emit).toHaveBeenCalledWith(Events.STORY_ARGS_UPDATED, {
storyId: 'component-one--a',
args: { foo: 'edited' },
});
});
it('applies loaders with story context', async () => {
document.location.search = '?id=component-one--a';
const preview = await createAndRenderPreview();

View File

@ -313,19 +313,22 @@ export class PreviewWeb<TFramework extends AnyFramework> {
throw new Error('Cannot render story as no selection was made');
}
const { selection } = this.urlStore;
const {
selection,
selection: { storyId },
} = this.urlStore;
let story;
try {
story = await this.storyStore.loadStory({ storyId: selection.storyId });
story = await this.storyStore.loadStory({ storyId });
} catch (err) {
this.previousStory = null;
logger.warn(err);
await this.renderMissingStory(selection.storyId);
await this.renderMissingStory(storyId);
return;
}
const storyIdChanged = this.previousSelection?.storyId !== selection.storyId;
const storyIdChanged = this.previousSelection?.storyId !== storyId;
const viewModeChanged = this.previousSelection?.viewMode !== selection.viewMode;
const implementationChanged =
@ -339,7 +342,7 @@ export class PreviewWeb<TFramework extends AnyFramework> {
// Don't re-render the story if nothing has changed to justify it
if (this.previousStory && !storyIdChanged && !implementationChanged && !viewModeChanged) {
this.channel.emit(Events.STORY_UNCHANGED, selection.storyId);
this.channel.emit(Events.STORY_UNCHANGED, storyId);
return;
}
@ -347,7 +350,7 @@ export class PreviewWeb<TFramework extends AnyFramework> {
// If we are rendering something new (as opposed to re-rendering the same or first story), emit
if (this.previousSelection && (storyIdChanged || viewModeChanged)) {
this.channel.emit(Events.STORY_CHANGED, selection.storyId);
this.channel.emit(Events.STORY_CHANGED, storyId);
}
// Record the previous selection *before* awaiting the rendering, in cases things change before it is done.
@ -357,13 +360,17 @@ export class PreviewWeb<TFramework extends AnyFramework> {
const { parameters, initialArgs, argTypes, args } = this.storyStore.getStoryContext(story);
if (FEATURES?.storyStoreV7) {
this.channel.emit(Events.STORY_PREPARED, {
id: story.id,
id: storyId,
parameters,
initialArgs,
argTypes,
args,
});
}
// If the implementation changed, the args also may have changed
if (implementationChanged) {
this.channel.emit(Events.STORY_ARGS_UPDATED, { storyId, args });
}
if (selection.viewMode === 'docs' || story.parameters.docsOnly) {
this.previousCleanup = await this.renderDocs({ story });