| @@ -10,29 +10,56 @@ | ||
| 10 | 10 | /** |
| 11 | 11 | * WordPress dependencies. |
| 12 | 12 | */ |
| 13 | 13 | import { StrictMode } from 'react'; |
| 14 | -import { createRoot, render } from 'react-dom'; // eslint-disable-line react/no-deprecated | |
| 14 | +import { createPortal, createRoot } from 'react-dom'; | |
| 15 | +import { addFilter } from '@wordpress/hooks'; | |
| 15 | 16 | |
| 16 | 17 | /** |
| 17 | 18 | * Initializes a React component on the page. |
| 18 | 19 | * |
| 19 | 20 | * @param {string} rootId HTML ID of the root element for the component. |
| 20 | - * @param {Component} component JSX of the component. | |
| 21 | + * @param {Component} Component JSX component. | |
| 21 | 22 | */ |
| 22 | -export const initializeReactComponent = ( rootId, component ) => { | |
| 23 | +export const initializeReactComponent = ( rootId, Component ) => { | |
| 23 | 24 | if ( process.env.DEVELOP ) { |
| 24 | - component = <StrictMode>{ component }</StrictMode>; | |
| 25 | + Component = <StrictMode>{ Component }</StrictMode>; | |
| 25 | 26 | } |
| 26 | 27 | |
| 27 | 28 | const root = document.getElementById( rootId ); |
| 28 | 29 | if ( root ) { |
| 29 | - // Compatibility check for React 17 and 18. | |
| 30 | - if ( 'function' === typeof createRoot ) { | |
| 31 | - // React 18 (WP 6.2 and newer): Use createRoot(). | |
| 32 | - createRoot( root ).render( component ); | |
| 33 | - } else { | |
| 34 | - // React 17 (WP 6.1 and older): Use render(). | |
| 35 | - render( component, root ); | |
| 36 | - } | |
| 30 | + createRoot( root ).render( Component ); | |
| 37 | 31 | } |
| 32 | +}; | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * Initializes a React component on the page, in a React Portal, and registers its meta box. | |
| 36 | + * | |
| 37 | + * @param {string} slug Slug of the component/feature module. | |
| 38 | + * @param {string} screen Slug/action of the screen. | |
| 39 | + * @param {Component} Component JSX component. | |
| 40 | + */ | |
| 41 | +export const initializeReactComponentInPortal = ( slug, screen, Component ) => { | |
| 42 | + addFilter( | |
| 43 | + `tablepress.${screen}ScreenFeatures`, | |
| 44 | + `tp/${slug}/${screen}-screen-feature`, | |
| 45 | + ( features ) => ( [ ...features, slug ] ), | |
| 46 | + ); | |
| 47 | + | |
| 48 | + addFilter( | |
| 49 | + `tablepress.${screen}ScreenPortals`, | |
| 50 | + `tp/${slug}/${screen}-screen-portal`, | |
| 51 | + ( Portals ) => { | |
| 52 | + return ( props ) => ( | |
| 53 | + <> | |
| 54 | + <Portals { ...props } /> | |
| 55 | + { | |
| 56 | + createPortal( | |
| 57 | + <Component { ...props } />, | |
| 58 | + document.getElementById( `tablepress-${slug}-section` ), | |
| 59 | + ) | |
| 60 | + } | |
| 61 | + </> | |
| 62 | + ); | |
| 63 | + }, | |
| 64 | + ); | |
| 38 | 65 | }; |