diff --git a/packages/edit-post/src/index.native.js b/packages/edit-post/src/index.native.js
index 13cf9ce44efe3c..8efafa0714d633 100644
--- a/packages/edit-post/src/index.native.js
+++ b/packages/edit-post/src/index.native.js
@@ -3,23 +3,31 @@
*/
import '@wordpress/core-data';
import '@wordpress/block-editor';
-import '@wordpress/editor';
import '@wordpress/viewport';
import '@wordpress/notices';
import { registerCoreBlocks } from '@wordpress/block-library';
import '@wordpress/format-library';
+import { render } from '@wordpress/element';
/**
* Internal dependencies
*/
import './store';
+import Editor from './editor';
let blocksRegistered = false;
/**
- * Initializes the Editor.
+ * Initializes the Editor and returns a componentProvider
+ * that can be registered with `AppRegistry.registerComponent`
*/
-export function initializeEditor() {
+export function initializeEditor( {
+ id,
+ initialHtml,
+ initialTitle,
+ initialHtmlModeEnabled,
+ postType,
+} ) {
if ( blocksRegistered ) {
return;
}
@@ -27,6 +35,14 @@ export function initializeEditor() {
// register and setup blocks
registerCoreBlocks();
blocksRegistered = true;
-}
-export { default as Editor } from './editor';
+ render(
+ ,
+ id
+ );
+}
diff --git a/packages/element/src/react-platform.native.js b/packages/element/src/react-platform.native.js
index e69de29bb2d1d6..ab2e8bd32fdc6f 100644
--- a/packages/element/src/react-platform.native.js
+++ b/packages/element/src/react-platform.native.js
@@ -0,0 +1,44 @@
+/**
+ * External dependencies
+ */
+import { AppRegistry } from 'react-native';
+import { isEmpty, omit } from 'lodash';
+
+/**
+ * WordPress dependencies
+ */
+import { applyFilters, doAction } from '@wordpress/hooks';
+
+/**
+ * Internal dependencies
+ */
+import { cloneElement } from './react';
+
+const render = ( element, id ) =>
+ AppRegistry.registerComponent( id, () => ( propsFromNative ) => {
+ const nativeProps = omit( propsFromNative || {}, [ 'rootTag' ] );
+
+ doAction( 'native.render', nativeProps );
+
+ // if we have not received props from a parent native app
+ // just render the element as it is
+ if ( isEmpty( nativeProps ) ) {
+ return element;
+ }
+
+ // Otherwise overwrite the existing props using a filter hook
+ const filteredProps = applyFilters(
+ 'native.block_editor_props',
+ nativeProps
+ );
+
+ return cloneElement( element, filteredProps );
+ } );
+
+/**
+ * Render a given element on Native.
+ * This actually returns a componentProvider that can be registered with `AppRegistry.registerComponent`
+ *
+ * @param {WPElement} element Element to render.
+ */
+export { render };
diff --git a/packages/react-native-editor/index.js b/packages/react-native-editor/index.js
index a3c56418ddeb4c..1417cc0322975d 100644
--- a/packages/react-native-editor/index.js
+++ b/packages/react-native-editor/index.js
@@ -1,6 +1,4 @@
/**
* Internal dependencies
*/
-import { registerApp } from './src';
-
-registerApp();
+import './src';
diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json
index 5429f1da2c61db..ce574de4d5d987 100644
--- a/packages/react-native-editor/package.json
+++ b/packages/react-native-editor/package.json
@@ -26,6 +26,8 @@
"node": ">=10",
"npm": ">=6.9"
},
+ "main": "src/index.js",
+ "react-native": "src/index",
"dependencies": {
"@babel/runtime": "^7.7.7",
"@react-native-community/slider": "git+https://github.com/wordpress-mobile/react-native-slider.git#5ad284d92b8d886e366445bf215be741ed53ddc6",
diff --git a/packages/react-native-editor/src/index.js b/packages/react-native-editor/src/index.js
index 19a144395396b5..919ed86a727d0e 100644
--- a/packages/react-native-editor/src/index.js
+++ b/packages/react-native-editor/src/index.js
@@ -1,16 +1,7 @@
/**
* External dependencies
*/
-import { AppRegistry, I18nManager } from 'react-native';
-/**
- * WordPress dependencies
- */
-import { Component } from '@wordpress/element';
-
-/**
- * WordPress dependencies
- */
-import { setLocaleData } from '@wordpress/i18n';
+import { I18nManager } from 'react-native';
/**
* Internal dependencies
@@ -20,6 +11,14 @@ import { getTranslation } from '../i18n-cache';
import initialHtml from './initial-html';
import setupApiFetch from './api-fetch-setup';
+const reactNativeSetup = () => {
+ // Disable warnings as they disrupt the user experience in dev mode
+ // eslint-disable-next-line no-console
+ console.disableYellowBox = true;
+
+ I18nManager.forceRTL( false ); // Change to `true` to debug RTL layout easily.
+};
+
const gutenbergSetup = () => {
const wpData = require( '@wordpress/data' );
@@ -27,9 +26,51 @@ const gutenbergSetup = () => {
const userId = 1;
const storageKey = 'WP_DATA_USER_' + userId;
wpData.use( wpData.plugins.persistence, { storageKey } );
+
+ setupApiFetch();
+
+ const isHermes = () => global.HermesInternal !== null;
+ // eslint-disable-next-line no-console
+ console.log( 'Hermes is: ' + isHermes() );
+
+ setupInitHooks();
+
+ const initializeEditor = require( '@wordpress/edit-post' ).initializeEditor;
+ initializeEditor( {
+ id: 'gutenberg',
+ initialHtml,
+ initialHtmlModeEnabled: false,
+ initialTitle: 'Welcome to Gutenberg!',
+ postType: 'post'
+ } );
+};
+
+const setupInitHooks = () => {
+ const wpHooks = require( '@wordpress/hooks' );
+
+ wpHooks.doAction( 'native.setup-init-hooks' );
+
+ wpHooks.addAction( 'native.render', 'core/react-native-editor', ( props ) => {
+ setupLocale( props.locale, props.translations );
+ } );
+
+ // Map native props to Editor props
+ wpHooks.addFilter( 'native.block_editor_props', 'core/react-native-editor', ( {
+ initialData,
+ initialTitle,
+ initialHtmlModeEnabled,
+ postType,
+ } ) => ( {
+ initialHtml: initialData,
+ initialHtmlModeEnabled,
+ initialTitle,
+ postType,
+ } ) );
};
const setupLocale = ( locale, extraTranslations ) => {
+ const setLocaleData = require( '@wordpress/i18n' ).setLocaleData;
+
I18nManager.forceRTL( false ); // Change to `true` to debug RTL layout easily.
let gutenbergTranslations = getTranslation( locale );
@@ -51,51 +92,5 @@ const setupLocale = ( locale, extraTranslations ) => {
}
};
-export class RootComponent extends Component {
- constructor( props ) {
- super( props );
- setupLocale( props.locale, props.translations );
- setupApiFetch();
- require( '@wordpress/edit-post' ).initializeEditor();
-
- const isHermes = () => global.HermesInternal !== null;
- // eslint-disable-next-line no-console
- console.log( 'Hermes is: ' + isHermes() );
- }
-
- render() {
- const { initialHtmlModeEnabled } = this.props;
- let initialData = this.props.initialData;
- let initialTitle = this.props.initialTitle;
- let postType = this.props.postType;
-
- if ( initialData === undefined && __DEV__ ) {
- initialData = initialHtml;
- }
- if ( initialTitle === undefined ) {
- initialTitle = 'Welcome to Gutenberg!';
- }
- if ( postType === undefined ) {
- postType = 'post';
- }
- const Editor = require( '@wordpress/edit-post' ).Editor;
- return (
-
- );
- }
-}
-
-export function registerApp() {
- // Disable warnings as they disrupt the user experience in dev mode
- // eslint-disable-next-line no-console
- console.disableYellowBox = true;
-
- gutenbergSetup();
-
- AppRegistry.registerComponent( 'gutenberg', () => RootComponent );
-}
+reactNativeSetup();
+gutenbergSetup();