diff --git a/packages/customize-widgets/src/components/customize-widgets/index.js b/packages/customize-widgets/src/components/customize-widgets/index.js
index 35a91cb89de66..78625a5755cf1 100644
--- a/packages/customize-widgets/src/components/customize-widgets/index.js
+++ b/packages/customize-widgets/src/components/customize-widgets/index.js
@@ -7,6 +7,7 @@ import { SlotFillProvider, Popover } from '@wordpress/components';
/**
* Internal dependencies
*/
+import ErrorBoundary from '../error-boundary';
import SidebarBlockEditor from '../sidebar-block-editor';
import FocusControl from '../focus-control';
import SidebarControls from '../sidebar-controls';
@@ -16,6 +17,7 @@ export default function CustomizeWidgets( {
api,
sidebarControls,
blockEditorSettings,
+ onError,
} ) {
const [ activeSidebarControl, setActiveSidebarControl ] = useState( null );
const parentContainer = document.getElementById(
@@ -42,13 +44,15 @@ export default function CustomizeWidgets( {
const activeSidebar =
activeSidebarControl &&
createPortal(
- ,
+
+
+ ,
activeSidebarControl.container[ 0 ]
);
diff --git a/packages/customize-widgets/src/components/error-boundary/index.js b/packages/customize-widgets/src/components/error-boundary/index.js
new file mode 100644
index 0000000000000..9ceddac2a540b
--- /dev/null
+++ b/packages/customize-widgets/src/components/error-boundary/index.js
@@ -0,0 +1,64 @@
+/**
+ * WordPress dependencies
+ */
+import { Component } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import { Button } from '@wordpress/components';
+import { Warning } from '@wordpress/block-editor';
+import { useCopyToClipboard } from '@wordpress/compose';
+
+function CopyButton( { text, children } ) {
+ const ref = useCopyToClipboard( text );
+ return (
+
+ );
+}
+
+export default class ErrorBoundary extends Component {
+ constructor() {
+ super( ...arguments );
+
+ this.reboot = this.reboot.bind( this );
+
+ this.state = {
+ error: null,
+ };
+ }
+
+ componentDidCatch( error ) {
+ this.setState( { error } );
+ }
+
+ reboot() {
+ this.props.onError();
+ }
+
+ render() {
+ const { error } = this.state;
+ if ( ! error ) {
+ return this.props.children;
+ }
+
+ return (
+
+ { __( 'Attempt Recovery' ) }
+ ,
+
+ { __( 'Copy Error' ) }
+ ,
+ ] }
+ >
+ { __( 'The editor has encountered an unexpected error.' ) }
+
+ );
+ }
+}
diff --git a/packages/customize-widgets/src/index.js b/packages/customize-widgets/src/index.js
index e578b491adbb9..c40142bf5351e 100644
--- a/packages/customize-widgets/src/index.js
+++ b/packages/customize-widgets/src/index.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
-import { render } from '@wordpress/element';
+import { render, unmountComponentAtNode } from '@wordpress/element';
import {
registerCoreBlocks,
__experimentalGetCoreBlocks,
@@ -26,6 +26,25 @@ const { wp } = window;
const DISABLED_BLOCKS = [ 'core/more', 'core/block', 'core/freeform' ];
const ENABLE_EXPERIMENTAL_FSE_BLOCKS = false;
+export function reinitializeEditor( target, sidebarControls, settings ) {
+ unmountComponentAtNode( target );
+ const reboot = reinitializeEditor.bind(
+ null,
+ target,
+ sidebarControls,
+ settings
+ );
+ render(
+ ,
+ target
+ );
+}
+
/**
* Initializes the widgets block editor in the customizer.
*
@@ -62,6 +81,7 @@ export function initialize( editorName, blockEditorSettings ) {
wp.customize.controlConstructor.sidebar_block_editor = SidebarControl;
const container = document.createElement( 'div' );
+ container.classList.add( 'test' );
document.body.appendChild( container );
wp.customize.bind( 'ready', () => {
@@ -72,11 +92,19 @@ export function initialize( editorName, blockEditorSettings ) {
}
} );
+ const reboot = reinitializeEditor.bind(
+ null,
+ container,
+ sidebarControls,
+ blockEditorSettings
+ );
+
render(
,
container
);