Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preview: Ensure docs container re-renders when globals change #18711

Merged
merged 2 commits into from
Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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