main
js 55 lines 1.59 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import * as React from 'react';
11 import {useContext} from 'react';
12 import {createPortal} from 'react-dom';
13 import ErrorBoundary from './ErrorBoundary';
14 import {StoreContext} from './context';
15 import ThemeProvider from './ThemeProvider';
16
17 export type Props = {portalContainer?: Element, ...};
18
19 export default function portaledContent(
20 Component: component(...props: any),
21 ): component(...props: any) {
22 return function PortaledContent({portalContainer, ...rest}: Props) {
23 const store = useContext(StoreContext);
24
25 let children = (
26 <ErrorBoundary store={store}>
27 <Component {...rest} />
28 </ErrorBoundary>
29 );
30
31 if (portalContainer != null) {
32 // The ThemeProvider works by writing DOM style variables to an HTMLDivElement.
33 // Because Portals render in a different DOM subtree, these variables don't propagate.
34 // So in this case, we need to re-wrap portaled content in a second ThemeProvider.
35 children = (
36 <ThemeProvider>
37 <div
38 data-react-devtools-portal-root={true}
39 style={{
40 width: '100vw',
41 height: '100vh',
42 containerName: 'devtools',
43 containerType: 'inline-size',
44 }}>
45 {children}
46 </div>
47 </ThemeProvider>
48 );
49 }
50
51 return portalContainer != null
52 ? createPortal(children, portalContainer)
53 : children;
54 };
55 }