diff --git a/addons/docs/src/blocks/DocsRenderer.tsx b/addons/docs/src/blocks/DocsRenderer.tsx index 917ec49b7d02..66fa711b2850 100644 --- a/addons/docs/src/blocks/DocsRenderer.tsx +++ b/addons/docs/src/blocks/DocsRenderer.tsx @@ -1,18 +1,31 @@ import React, { ComponentType, ReactElement } from 'react'; import ReactDOM from 'react-dom'; import { AnyFramework, Parameters } from '@storybook/csf'; +import { DocsRenderFunction } from '@storybook/preview-web'; + import { DocsContainer } from './DocsContainer'; import { DocsPage } from './DocsPage'; - import { DocsContext, DocsContextProps } from './DocsContext'; -export function renderDocs( - docsContext: DocsContextProps, - docsParameters: Parameters, - element: HTMLElement, - callback: () => void -): void { - renderDocsAsync(docsContext, docsParameters, element).then(callback); +export class DocsRenderer { + public render: DocsRenderFunction; + + public unmount: (element: HTMLElement) => void; + + constructor() { + this.render = ( + docsContext: DocsContextProps, + docsParameters: Parameters, + element: HTMLElement, + callback: () => void + ): void => { + renderDocsAsync(docsContext, docsParameters, element).then(callback); + }; + + this.unmount = (element: HTMLElement) => { + ReactDOM.unmountComponentAtNode(element); + }; + } } async function renderDocsAsync( @@ -43,7 +56,3 @@ async function renderDocsAsync( ReactDOM.render(docsElement, element, resolve); }); } - -export function unmountDocs(element: HTMLElement) { - ReactDOM.unmountComponentAtNode(element); -} diff --git a/addons/docs/src/blocks/index.ts b/addons/docs/src/blocks/index.ts index 7096967b0db3..11fc1de42df1 100644 --- a/addons/docs/src/blocks/index.ts +++ b/addons/docs/src/blocks/index.ts @@ -7,6 +7,7 @@ export * from './Description'; export * from './DocsContext'; export * from './DocsPage'; export * from './DocsContainer'; +export * from './DocsRenderer'; // For testing export * from './DocsStory'; export * from './Heading'; export * from './Meta'; diff --git a/addons/docs/src/preview.ts b/addons/docs/src/preview.ts index 00ed5271d263..1cb1b297f323 100644 --- a/addons/docs/src/preview.ts +++ b/addons/docs/src/preview.ts @@ -1,9 +1,8 @@ export const parameters = { docs: { renderer: async () => { - const x = await import('./blocks/DocsRenderer'); - console.log(x); - return x; + const { DocsRenderer } = await import('./blocks/DocsRenderer'); + return new DocsRenderer(); }, }, }; diff --git a/lib/preview-web/src/DocsRender.ts b/lib/preview-web/src/DocsRender.ts index eaed9932fbd7..069ce6ca21ba 100644 --- a/lib/preview-web/src/DocsRender.ts +++ b/lib/preview-web/src/DocsRender.ts @@ -144,7 +144,7 @@ export class DocsRender implements Render)( + (renderer.render as DocsRenderFunction)( this.docsContext, { ...docs, @@ -155,8 +155,7 @@ export class DocsRender implements Render { if (!viewModeChanged || !this.canvasElement) return; - // TODO type - renderer.unmountDocs(this.canvasElement); + renderer.unmount(this.canvasElement); }; } diff --git a/lib/preview-web/src/PreviewWeb.integration.test.ts b/lib/preview-web/src/PreviewWeb.integration.test.ts index 2e452c167c45..3dc66a8f8c2f 100644 --- a/lib/preview-web/src/PreviewWeb.integration.test.ts +++ b/lib/preview-web/src/PreviewWeb.integration.test.ts @@ -2,6 +2,7 @@ import React from 'react'; import global from 'global'; import { RenderContext } from '@storybook/store'; import addons, { mockChannel as createMockChannel } from '@storybook/addons'; +import { DocsRenderer } from '@storybook/addon-docs'; import { PreviewWeb } from './PreviewWeb'; import { @@ -13,6 +14,7 @@ import { mockChannel, waitForRender, storyIndex as mockStoryIndex, + docsRenderer, } from './PreviewWeb.mockdata'; // PreviewWeb.test mocks out all rendering @@ -51,6 +53,7 @@ beforeEach(() => { projectAnnotations.renderToDOM.mockReset(); projectAnnotations.render.mockClear(); projectAnnotations.decorators[0].mockClear(); + projectAnnotations.parameters.docs.renderer = () => new DocsRenderer(); addons.setChannel(mockChannel as any); addons.setServerChannel(createMockChannel()); diff --git a/lib/preview-web/src/PreviewWeb.mockdata.ts b/lib/preview-web/src/PreviewWeb.mockdata.ts index 8346fc021963..23384cb3d0f9 100644 --- a/lib/preview-web/src/PreviewWeb.mockdata.ts +++ b/lib/preview-web/src/PreviewWeb.mockdata.ts @@ -38,8 +38,8 @@ export const importFn = jest.fn( ); export const docsRenderer = { - renderDocs: jest.fn().mockImplementation((context, parameters, element, cb) => cb()), - unmountDocs: jest.fn(), + render: jest.fn().mockImplementation((context, parameters, element, cb) => cb()), + unmount: jest.fn(), }; export const projectAnnotations = { globals: { a: 'b' }, diff --git a/lib/preview-web/src/PreviewWeb.test.ts b/lib/preview-web/src/PreviewWeb.test.ts index bd036bc55ad3..a567bb84319c 100644 --- a/lib/preview-web/src/PreviewWeb.test.ts +++ b/lib/preview-web/src/PreviewWeb.test.ts @@ -102,7 +102,7 @@ beforeEach(() => { projectAnnotations.renderToDOM.mockReset(); projectAnnotations.render.mockClear(); projectAnnotations.decorators[0].mockClear(); - docsRenderer.renderDocs.mockClear(); + docsRenderer.render.mockClear(); // @ts-ignore logger.warn.mockClear(); mockStoryIndex.mockReset().mockReturnValue(storyIndex); @@ -588,7 +588,7 @@ describe('PreviewWeb', () => { await createAndRenderPreview(); - expect(docsRenderer.renderDocs).toHaveBeenCalledWith( + expect(docsRenderer.render).toHaveBeenCalledWith( expect.objectContaining({ id: 'component-one--a', title: 'Component One', @@ -621,7 +621,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=legacy--docs&viewMode=docs'; await createAndRenderPreview(); - expect(docsRenderer.renderDocs).toHaveBeenCalledWith( + expect(docsRenderer.render).toHaveBeenCalledWith( expect.any(Object), expect.objectContaining({ page: legacyDocsExports.Docs.parameters.docs.page, @@ -644,7 +644,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=introduction--docs&viewMode=docs'; await createAndRenderPreview(); - expect(docsRenderer.renderDocs).toHaveBeenCalledWith( + expect(docsRenderer.render).toHaveBeenCalledWith( expect.any(Object), expect.objectContaining({ page: modernDocsExports.default, @@ -728,7 +728,7 @@ describe('PreviewWeb', () => { emitter.emit(Events.UPDATE_GLOBALS, { globals: { foo: 'bar' } }); await waitForRender(); - expect(docsRenderer.renderDocs).toHaveBeenCalledTimes(2); + expect(docsRenderer.render).toHaveBeenCalledTimes(2); }); }); }); @@ -997,7 +997,7 @@ describe('PreviewWeb', () => { await createAndRenderPreview(); - docsRenderer.renderDocs.mockClear(); + docsRenderer.render.mockClear(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -1005,7 +1005,7 @@ describe('PreviewWeb', () => { }); await waitForRender(); - expect(docsRenderer.renderDocs).toHaveBeenCalledTimes(1); + expect(docsRenderer.render).toHaveBeenCalledTimes(1); }); }); @@ -1021,7 +1021,7 @@ describe('PreviewWeb', () => { await createAndRenderPreview(); - docsRenderer.renderDocs.mockClear(); + docsRenderer.render.mockClear(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -1029,7 +1029,7 @@ describe('PreviewWeb', () => { }); await waitForEvents([Events.STORY_ARGS_UPDATED]); - expect(docsRenderer.renderDocs).not.toHaveBeenCalled(); + expect(docsRenderer.render).not.toHaveBeenCalled(); }); describe('when renderStoryToElement was called', () => { @@ -1053,7 +1053,7 @@ describe('PreviewWeb', () => { 'story-element' ); - docsRenderer.renderDocs.mockClear(); + docsRenderer.render.mockClear(); mockChannel.emit.mockClear(); emitter.emit(Events.UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -1968,7 +1968,7 @@ describe('PreviewWeb', () => { await waitForSetCurrentStory(); await waitForRender(); - expect(docsRenderer.renderDocs).toHaveBeenCalledWith( + expect(docsRenderer.render).toHaveBeenCalledWith( expect.objectContaining({ id: 'component-one--a', title: 'Component One', @@ -2026,7 +2026,7 @@ describe('PreviewWeb', () => { await waitForSetCurrentStory(); await waitForRender(); - expect(docsRenderer.unmountDocs).toHaveBeenCalled(); + expect(docsRenderer.unmount).toHaveBeenCalled(); }); // NOTE: I am not sure this entirely makes sense but this is the behaviour from 6.3