Skip to content

Commit

Permalink
Merge pull request #18711 from storybookjs/tom/sb-419-sb18477-changes…
Browse files Browse the repository at this point in the history
…-to-global-values-do-not

Preview: Ensure docs container re-renders when globals change
  • Loading branch information
shilman committed Jul 26, 2022
1 parent 0d031bb commit 39171b8
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
@@ -1,19 +1,38 @@
import { Meta, DocsContainer, Story } from '@storybook/addon-docs';
import { useRef } from 'react';
import { Meta, DocsContainer, Story, ArgsTable } from '@storybook/addon-docs';

<Meta
title="Addons/Docs/container-override"
parameters={{
docs: {
// eslint-disable-next-line react/prop-types
container: ({ children, context }) => (
<DocsContainer context={context}>
<div style={{ border: '5px solid red' }}>{children}</div>
</DocsContainer>
),
container: ({ children, context }) => {
const countRef = useRef();
countRef.current = (countRef.current || 0) + 1;
return (
<DocsContainer context={context}>
<div style={{ border: '5px solid red' }}>{children}</div>
<p>Container rendered {countRef.current} times</p>
<p>Try changing:</p>
<ul>
<li>the arg - story should rerender but container should not</li>
<li>a global (eg theme) - both should rerender</li>
</ul>
</DocsContainer>
);
},
},
}}
/>

export const Component = () => {
const countRef = useRef();
countRef.current = (countRef.current || 0) + 1;
return <div>Story rendered {countRef.current} times</div>;
};

<Story name="dummy" parameters={{ layout: 'fullscreen' }}>
<div>some content</div>
<Component />
</Story>

<ArgsTable story="." />
4 changes: 2 additions & 2 deletions lib/preview-web/src/DocsRender.ts
Expand Up @@ -72,12 +72,12 @@ export class DocsRender<TFramework extends AnyFramework> implements Render<TFram
);
}

async rerender() {
async rerender(isGlobals: boolean) {
// NOTE: in modern inline render mode, each story is rendered via
// `preview.renderStoryToElement` which means the story will track
// its own re-renders. Thus there will be no need to re-render the whole
// docs page when a single story changes.
if (!global.FEATURES?.modernInlineRender) await this.render();
if (!global.FEATURES?.modernInlineRender || isGlobals) await this.render();
}

async teardown({ viewModeChanged }: { viewModeChanged?: boolean } = {}) {
Expand Down
24 changes: 22 additions & 2 deletions lib/preview-web/src/PreviewWeb.test.ts
Expand Up @@ -686,7 +686,27 @@ describe('PreviewWeb', () => {
expect(mockChannel.emit).toHaveBeenCalledWith(STORY_RENDERED, 'component-one--a');
});

describe('in docs mode', () => {
describe('in docs mode, legacy inline render', () => {
it('re-renders the docs container', async () => {
document.location.search = '?id=component-one--a&viewMode=docs';

await createAndRenderPreview();

mockChannel.emit.mockClear();
emitter.emit(UPDATE_GLOBALS, { globals: { foo: 'bar' } });
await waitForRender();

expect(ReactDOM.render).toHaveBeenCalledTimes(2);
});
});

describe('in docs mode, modern inline render', () => {
beforeEach(() => {
global.FEATURES.modernInlineRender = true;
});
afterEach(() => {
global.FEATURES.modernInlineRender = false;
});
it('re-renders the docs container', async () => {
document.location.search = '?id=component-one--a&viewMode=docs';

Expand Down Expand Up @@ -982,7 +1002,7 @@ describe('PreviewWeb', () => {
global.FEATURES.modernInlineRender = true;
});
afterEach(() => {
global.FEATURES.modernInlineRender = true;
global.FEATURES.modernInlineRender = false;
});
it('does not re-render the docs container', async () => {
document.location.search = '?id=component-one--a&viewMode=docs';
Expand Down
4 changes: 2 additions & 2 deletions lib/preview-web/src/PreviewWeb.tsx
Expand Up @@ -212,7 +212,7 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
async onUpdateGlobals({ globals }: { globals: Globals }) {
super.onUpdateGlobals({ globals });

if (this.currentRender instanceof DocsRender) await this.currentRender.rerender();
if (this.currentRender instanceof DocsRender) await this.currentRender.rerender(true);
}

async onUpdateArgs({ storyId, updatedArgs }: { storyId: StoryId; updatedArgs: Args }) {
Expand All @@ -223,7 +223,7 @@ export class PreviewWeb<TFramework extends AnyFramework> extends Preview<TFramew
// of which ones were rendered by the docs page.
// However, in `modernInlineRender`, the individual stories track their own events as they
// each call `renderStoryToElement` below.
if (this.currentRender instanceof DocsRender) await this.currentRender.rerender();
if (this.currentRender instanceof DocsRender) await this.currentRender.rerender(false);
}

async onPreloadStories(ids: string[]) {
Expand Down

0 comments on commit 39171b8

Please sign in to comment.