diff --git a/code/addons/docs/src/DocsRenderer.tsx b/code/addons/docs/src/DocsRenderer.tsx index 0124bf4dabe6..797f967282e1 100644 --- a/code/addons/docs/src/DocsRenderer.tsx +++ b/code/addons/docs/src/DocsRenderer.tsx @@ -1,6 +1,6 @@ import type { PropsWithChildren } from 'react'; import React, { Component } from 'react'; -import { renderElement, unmountElement } from '@storybook/react-dom-shim'; +import ReactDomShim from '@storybook/react-dom-shim'; import type { Renderer, Parameters, @@ -62,7 +62,7 @@ export class DocsRenderer { import('@mdx-js/react') .then(({ MDXProvider }) => // We use a `key={}` here to reset the `hasError` state each time we render ErrorBoundary - renderElement( + ReactDomShim.renderElement( @@ -76,7 +76,7 @@ export class DocsRenderer { }; this.unmount = (element: HTMLElement) => { - unmountElement(element); + ReactDomShim.unmountElement(element); }; } } diff --git a/code/lib/react-dom-shim/src/react-16.tsx b/code/lib/react-dom-shim/src/react-16.tsx index a519dbd51bb6..d040ca63a2f7 100644 --- a/code/lib/react-dom-shim/src/react-16.tsx +++ b/code/lib/react-dom-shim/src/react-16.tsx @@ -1,13 +1,15 @@ /* eslint-disable react/no-deprecated */ import type { ReactElement } from 'react'; -import ReactDOM from 'react-dom'; +import * as ReactDOM from 'react-dom'; -export const renderElement = async (node: ReactElement, el: Element) => { +const renderElement = async (node: ReactElement, el: Element) => { return new Promise((resolve) => { ReactDOM.render(node, el, () => resolve(null)); }); }; -export const unmountElement = (el: Element) => { +const unmountElement = (el: Element) => { ReactDOM.unmountComponentAtNode(el); }; + +export default { renderElement, unmountElement }; diff --git a/code/lib/react-dom-shim/src/react-18.tsx b/code/lib/react-dom-shim/src/react-18.tsx index 5b9e88f98a84..022e8f1dc0e2 100644 --- a/code/lib/react-dom-shim/src/react-18.tsx +++ b/code/lib/react-dom-shim/src/react-18.tsx @@ -1,7 +1,7 @@ import type { FC, ReactElement } from 'react'; -import React, { useLayoutEffect, useRef } from 'react'; +import * as React from 'react'; import type { Root as ReactRoot, RootOptions } from 'react-dom/client'; -import ReactDOM from 'react-dom/client'; +import * as ReactDOM from 'react-dom/client'; // A map of all rendered React 18 nodes const nodes = new Map(); @@ -11,8 +11,8 @@ const WithCallback: FC<{ callback: () => void; children: ReactElement }> = ({ children, }) => { // See https://github.com/reactwg/react-18/discussions/5#discussioncomment-2276079 - const once = useRef<() => void>(); - useLayoutEffect(() => { + const once = React.useRef<() => void>(); + React.useLayoutEffect(() => { if (once.current === callback) return; once.current = callback; callback(); @@ -21,7 +21,7 @@ const WithCallback: FC<{ callback: () => void; children: ReactElement }> = ({ return children; }; -export const renderElement = async (node: ReactElement, el: Element, rootOptions?: RootOptions) => { +const renderElement = async (node: ReactElement, el: Element, rootOptions?: RootOptions) => { // Create Root Element conditionally for new React 18 Root Api const root = await getReactRoot(el, rootOptions); @@ -30,7 +30,7 @@ export const renderElement = async (node: ReactElement, el: Element, rootOptions }); }; -export const unmountElement = (el: Element, shouldUseNewRootApi?: boolean) => { +const unmountElement = (el: Element, shouldUseNewRootApi?: boolean) => { const root = nodes.get(el); if (root) { @@ -49,3 +49,5 @@ const getReactRoot = async (el: Element, rootOptions?: RootOptions): Promise, canvasElement: ReactRenderer['canvasElement'] ) { + const { renderElement, unmountElement } = (await import('@storybook/react-dom-shim')).default; const Story = unboundStoryFn as FC>; const content = (