@wordpress/edit-widgets 2.1.19 → 2.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/build/blocks/widget-area/edit/index.js +3 -1
  2. package/build/blocks/widget-area/edit/index.js.map +1 -1
  3. package/build/blocks/widget-area/edit/inner-blocks.js +4 -1
  4. package/build/blocks/widget-area/edit/inner-blocks.js.map +1 -1
  5. package/build/components/error-boundary/index.js +76 -0
  6. package/build/components/error-boundary/index.js.map +1 -0
  7. package/build/components/layout/index.js +8 -3
  8. package/build/components/layout/index.js.map +1 -1
  9. package/build/components/more-menu/index.js +1 -1
  10. package/build/components/more-menu/index.js.map +1 -1
  11. package/build/components/sidebar/widget-areas.js +11 -1
  12. package/build/components/sidebar/widget-areas.js.map +1 -1
  13. package/build/hooks/use-widget-library-insertion-point.js +11 -0
  14. package/build/hooks/use-widget-library-insertion-point.js.map +1 -1
  15. package/build/index.js +24 -2
  16. package/build/index.js.map +1 -1
  17. package/build/store/selectors.js +20 -0
  18. package/build/store/selectors.js.map +1 -1
  19. package/build-module/blocks/widget-area/edit/index.js +3 -1
  20. package/build-module/blocks/widget-area/edit/index.js.map +1 -1
  21. package/build-module/blocks/widget-area/edit/inner-blocks.js +4 -1
  22. package/build-module/blocks/widget-area/edit/inner-blocks.js.map +1 -1
  23. package/build-module/components/error-boundary/index.js +65 -0
  24. package/build-module/components/error-boundary/index.js.map +1 -0
  25. package/build-module/components/layout/index.js +7 -3
  26. package/build-module/components/layout/index.js.map +1 -1
  27. package/build-module/components/more-menu/index.js +1 -1
  28. package/build-module/components/more-menu/index.js.map +1 -1
  29. package/build-module/components/sidebar/widget-areas.js +10 -1
  30. package/build-module/components/sidebar/widget-areas.js.map +1 -1
  31. package/build-module/hooks/use-widget-library-insertion-point.js +10 -0
  32. package/build-module/hooks/use-widget-library-insertion-point.js.map +1 -1
  33. package/build-module/index.js +24 -3
  34. package/build-module/index.js.map +1 -1
  35. package/build-module/store/selectors.js +18 -0
  36. package/build-module/store/selectors.js.map +1 -1
  37. package/build-style/style-rtl.css +8 -0
  38. package/build-style/style.css +8 -0
  39. package/package.json +26 -25
  40. package/src/blocks/widget-area/edit/index.js +1 -1
  41. package/src/blocks/widget-area/edit/inner-blocks.js +2 -1
  42. package/src/components/error-boundary/index.js +64 -0
  43. package/src/components/error-boundary/style.scss +7 -0
  44. package/src/components/layout/index.js +14 -11
  45. package/src/components/more-menu/index.js +1 -1
  46. package/src/components/sidebar/widget-areas.js +10 -1
  47. package/src/hooks/use-widget-library-insertion-point.js +11 -0
  48. package/src/index.js +22 -3
  49. package/src/store/selectors.js +12 -0
  50. package/src/style.scss +1 -0
@@ -18,7 +18,7 @@ import { useRef } from '@wordpress/element';
18
18
  */
19
19
  import useIsDraggingWithin from './use-is-dragging-within';
20
20
 
21
- export default function WidgetAreaInnerBlocks() {
21
+ export default function WidgetAreaInnerBlocks( { id } ) {
22
22
  const [ blocks, onInput, onChange ] = useEntityBlockEditor(
23
23
  'root',
24
24
  'postType'
@@ -40,6 +40,7 @@ export default function WidgetAreaInnerBlocks() {
40
40
 
41
41
  return (
42
42
  <div
43
+ data-widget-area-id={ id }
43
44
  className={ classnames(
44
45
  'wp-block-widget-area__inner-blocks block-editor-inner-blocks editor-styles-wrapper',
45
46
  {
@@ -0,0 +1,64 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { Component } from '@wordpress/element';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { Button } from '@wordpress/components';
7
+ import { Warning } from '@wordpress/block-editor';
8
+ import { useCopyToClipboard } from '@wordpress/compose';
9
+
10
+ function CopyButton( { text, children } ) {
11
+ const ref = useCopyToClipboard( text );
12
+ return (
13
+ <Button variant="secondary" ref={ ref }>
14
+ { children }
15
+ </Button>
16
+ );
17
+ }
18
+
19
+ export default class ErrorBoundary extends Component {
20
+ constructor() {
21
+ super( ...arguments );
22
+
23
+ this.reboot = this.reboot.bind( this );
24
+
25
+ this.state = {
26
+ error: null,
27
+ };
28
+ }
29
+
30
+ componentDidCatch( error ) {
31
+ this.setState( { error } );
32
+ }
33
+
34
+ reboot() {
35
+ this.props.onError();
36
+ }
37
+
38
+ render() {
39
+ const { error } = this.state;
40
+ if ( ! error ) {
41
+ return this.props.children;
42
+ }
43
+
44
+ return (
45
+ <Warning
46
+ className="edit-widgets-error-boundary"
47
+ actions={ [
48
+ <Button
49
+ key="recovery"
50
+ onClick={ this.reboot }
51
+ variant="secondary"
52
+ >
53
+ { __( 'Attempt Recovery' ) }
54
+ </Button>,
55
+ <CopyButton key="copy-error" text={ error.stack }>
56
+ { __( 'Copy Error' ) }
57
+ </CopyButton>,
58
+ ] }
59
+ >
60
+ { __( 'The editor has encountered an unexpected error.' ) }
61
+ </Warning>
62
+ );
63
+ }
64
+ }
@@ -0,0 +1,7 @@
1
+ .edit-widgets-error-boundary {
2
+ margin: auto;
3
+ max-width: 780px;
4
+ padding: 20px;
5
+ margin-top: 60px;
6
+ box-shadow: $shadow-modal;
7
+ }
@@ -7,24 +7,27 @@ import { PluginArea } from '@wordpress/plugins';
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
+ import ErrorBoundary from '../error-boundary';
10
11
  import WidgetAreasBlockEditorProvider from '../widget-areas-block-editor-provider';
11
12
  import Sidebar from '../sidebar';
12
13
  import Interface from './interface';
13
14
  import UnsavedChangesWarning from './unsaved-changes-warning';
14
15
  import WelcomeGuide from '../welcome-guide';
15
16
 
16
- function Layout( { blockEditorSettings } ) {
17
+ function Layout( { blockEditorSettings, onError } ) {
17
18
  return (
18
- <WidgetAreasBlockEditorProvider
19
- blockEditorSettings={ blockEditorSettings }
20
- >
21
- <Interface blockEditorSettings={ blockEditorSettings } />
22
- <Sidebar />
23
- <Popover.Slot />
24
- <PluginArea />
25
- <UnsavedChangesWarning />
26
- <WelcomeGuide />
27
- </WidgetAreasBlockEditorProvider>
19
+ <ErrorBoundary onError={ onError }>
20
+ <WidgetAreasBlockEditorProvider
21
+ blockEditorSettings={ blockEditorSettings }
22
+ >
23
+ <Interface blockEditorSettings={ blockEditorSettings } />
24
+ <Sidebar />
25
+ <Popover.Slot />
26
+ <PluginArea />
27
+ <UnsavedChangesWarning />
28
+ <WelcomeGuide />
29
+ </WidgetAreasBlockEditorProvider>
30
+ </ErrorBoundary>
28
31
  );
29
32
  }
30
33
 
@@ -92,7 +92,7 @@ export default function MoreMenu() {
92
92
  role="menuitem"
93
93
  icon={ external }
94
94
  href={ __(
95
- 'https://wordpress.org/support/article/wordpress-editor/'
95
+ 'https://wordpress.org/support/article/block-based-widgets-editor/'
96
96
  ) }
97
97
  target="_blank"
98
98
  rel="noopener noreferrer"
@@ -8,6 +8,7 @@ import { BlockIcon } from '@wordpress/block-editor';
8
8
  import { Button } from '@wordpress/components';
9
9
  import { __ } from '@wordpress/i18n';
10
10
  import { addQueryArgs } from '@wordpress/url';
11
+ import { safeHTML } from '@wordpress/dom';
11
12
 
12
13
  /**
13
14
  * Internal dependencies
@@ -47,7 +48,15 @@ export default function WidgetAreas( { selectedWidgetAreaId } ) {
47
48
  <div className="edit-widgets-widget-areas__top-container">
48
49
  <BlockIcon icon={ blockDefault } />
49
50
  <div>
50
- <p>{ description }</p>
51
+ <p
52
+ // Use `dangerouslySetInnerHTML` to keep backwards
53
+ // compatibility. Basic markup in the description is an
54
+ // established feature of WordPress.
55
+ // @see https://github.com/WordPress/gutenberg/issues/33106
56
+ dangerouslySetInnerHTML={ {
57
+ __html: safeHTML( description ),
58
+ } }
59
+ />
51
60
  { widgetAreas?.length === 0 && (
52
61
  <p>
53
62
  { __(
@@ -7,6 +7,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
+ import { store as editWidgetsStore } from '../store';
10
11
  import { buildWidgetAreasPostId, KIND, POST_TYPE } from '../store/utils';
11
12
 
12
13
  const useWidgetLibraryInsertionPoint = () => {
@@ -30,6 +31,16 @@ const useWidgetLibraryInsertionPoint = () => {
30
31
  getBlockIndex,
31
32
  } = select( blockEditorStore );
32
33
 
34
+ const insertionPoint = select(
35
+ editWidgetsStore
36
+ ).__experimentalGetInsertionPoint();
37
+
38
+ // "Browse all" in the quick inserter will set the rootClientId to the current block.
39
+ // Otherwise, it will just be undefined, and we'll have to handle it differently below.
40
+ if ( insertionPoint.rootClientId ) {
41
+ return insertionPoint;
42
+ }
43
+
33
44
  const clientId = getBlockSelectionEnd() || firstRootId;
34
45
  const rootClientId = getBlockRootClientId( clientId );
35
46
 
package/src/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  unstable__bootstrapServerSideBlockDefinitions, // eslint-disable-line camelcase
7
7
  setFreeformContentHandlerName,
8
8
  } from '@wordpress/blocks';
9
- import { render } from '@wordpress/element';
9
+ import { render, unmountComponentAtNode } from '@wordpress/element';
10
10
  import {
11
11
  registerCoreBlocks,
12
12
  __experimentalGetCoreBlocks,
@@ -36,6 +36,23 @@ const disabledBlocks = [
36
36
  ...( ! ALLOW_REUSABLE_BLOCKS && [ 'core/block' ] ),
37
37
  ];
38
38
 
39
+ /**
40
+ * Reinitializes the editor after the user chooses to reboot the editor after
41
+ * an unhandled error occurs, replacing previously mounted editor element using
42
+ * an initial state from prior to the crash.
43
+ *
44
+ * @param {Element} target DOM node in which editor is rendered.
45
+ * @param {?Object} settings Editor settings object.
46
+ */
47
+ export function reinitializeEditor( target, settings ) {
48
+ unmountComponentAtNode( target );
49
+ const reboot = reinitializeEditor.bind( null, target, settings );
50
+ render(
51
+ <Layout blockEditorSettings={ settings } onError={ reboot } />,
52
+ target
53
+ );
54
+ }
55
+
39
56
  /**
40
57
  * Initializes the block editor in the widgets screen.
41
58
  *
@@ -43,6 +60,8 @@ const disabledBlocks = [
43
60
  * @param {Object} settings Block editor settings.
44
61
  */
45
62
  export function initialize( id, settings ) {
63
+ const target = document.getElementById( id );
64
+ const reboot = reinitializeEditor.bind( null, target, settings );
46
65
  const coreBlocks = __experimentalGetCoreBlocks().filter( ( block ) => {
47
66
  return ! (
48
67
  disabledBlocks.includes( block.name ) ||
@@ -70,8 +89,8 @@ export function initialize( id, settings ) {
70
89
  // see: https://github.com/WordPress/gutenberg/issues/33097
71
90
  setFreeformContentHandlerName( 'core/html' );
72
91
  render(
73
- <Layout blockEditorSettings={ settings } />,
74
- document.getElementById( id )
92
+ <Layout blockEditorSettings={ settings } onError={ reboot } />,
93
+ target
75
94
  );
76
95
  }
77
96
 
@@ -218,6 +218,18 @@ export function isInserterOpened( state ) {
218
218
  return !! state.blockInserterPanel;
219
219
  }
220
220
 
221
+ /**
222
+ * Get the insertion point for the inserter.
223
+ *
224
+ * @param {Object} state Global application state.
225
+ *
226
+ * @return {Object} The root client ID and index to insert at.
227
+ */
228
+ export function __experimentalGetInsertionPoint( state ) {
229
+ const { rootClientId, insertionIndex } = state.blockInserterPanel;
230
+ return { rootClientId, insertionIndex };
231
+ }
232
+
221
233
  /**
222
234
  * Returns true if a block can be inserted into a widget area.
223
235
  *
package/src/style.scss CHANGED
@@ -1,6 +1,7 @@
1
1
  @import "../../interface/src/style.scss";
2
2
 
3
3
  @import "./blocks/widget-area/editor.scss";
4
+ @import "./components/error-boundary/style.scss";
4
5
  @import "./components/header/style.scss";
5
6
  @import "./components/keyboard-shortcut-help-modal/style.scss";
6
7
  @import "./components/more-menu/style.scss";