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 );