import React, { useState } from 'react' import CodeWrapper from './CodeWrapper' import BrowserOnly from '@docusaurus/BrowserOnly' import ReactDOM from 'react-dom' import { ErrorBoundary, FallbackProps } from 'react-error-boundary' export interface Example { source: { ts: string } name: string path: string load: () => { default: React.FC } } export interface ExampleContainerProps { example: Example } export const ExampleContainer = ({ example }: ExampleContainerProps) => ( <> {() => }
{example.source.ts} ) interface ExampleRendererProps { example: Example } function ExampleRenderer({ example }: ExampleRendererProps) { const [Component = () => <>] = useState(() => loadExample(example)) return (
) } // Needed because of require caching const exampleCache = new Map() /** * Loads the example and returns the component that will render the example app. * It's either the JSX passed to `ReactDOM.render` or otherwise the default export of the module. * This function hooks the `ReactDOM.render` so we can use it in examples and not crash the docs app. * Crash happens because the example tries to render into a '#root` component, which is not immediately available, * and could be repeated if there is more than one example in a mdx file. * * @param example Result of importing the example script using `example-loader.js * @returns A renderable component */ function loadExample(example: Example): React.FC { if (exampleCache.has(example.path)) { return exampleCache.get(example.path) } const originalRender = (ReactDOM as any).render let renderJsx = undefined ;(ReactDOM as any).render = (jsx: any) => { renderJsx = jsx // Not rendering anything, overriding default behaviour of App examples. } const exports = example.load() const component = renderJsx ? () => renderJsx : exports.default ;(ReactDOM as any).render = originalRender exampleCache.set(example.path, component) return component } const ErrorFallback: React.FC = ({ error, resetErrorBoundary }) => (
{error.stack}
)