@wordpress/edit-site 4.1.1 → 4.3.1

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 (170) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/add-new-template/new-template-part.js +2 -9
  3. package/build/components/add-new-template/new-template-part.js.map +1 -1
  4. package/build/components/add-new-template/new-template.js +28 -12
  5. package/build/components/add-new-template/new-template.js.map +1 -1
  6. package/build/components/block-editor/index.js +53 -4
  7. package/build/components/block-editor/index.js.map +1 -1
  8. package/build/components/editor/index.js +12 -4
  9. package/build/components/editor/index.js.map +1 -1
  10. package/build/components/global-styles/border-panel.js +25 -24
  11. package/build/components/global-styles/border-panel.js.map +1 -1
  12. package/build/components/global-styles/color-indicator-wrapper.js +37 -0
  13. package/build/components/global-styles/color-indicator-wrapper.js.map +1 -0
  14. package/build/components/global-styles/dimensions-panel.js +6 -2
  15. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  16. package/build/components/global-styles/header.js +1 -4
  17. package/build/components/global-styles/header.js.map +1 -1
  18. package/build/components/global-styles/icon-with-current-color.js +34 -0
  19. package/build/components/global-styles/icon-with-current-color.js.map +1 -0
  20. package/build/components/global-styles/navigation-button.js +7 -3
  21. package/build/components/global-styles/navigation-button.js.map +1 -1
  22. package/build/components/global-styles/palette.js +8 -5
  23. package/build/components/global-styles/palette.js.map +1 -1
  24. package/build/components/global-styles/preview.js +142 -26
  25. package/build/components/global-styles/preview.js.map +1 -1
  26. package/build/components/global-styles/screen-block-list.js +50 -6
  27. package/build/components/global-styles/screen-block-list.js.map +1 -1
  28. package/build/components/global-styles/screen-colors.js +11 -3
  29. package/build/components/global-styles/screen-colors.js.map +1 -1
  30. package/build/components/global-styles/screen-root.js +7 -5
  31. package/build/components/global-styles/screen-root.js.map +1 -1
  32. package/build/components/global-styles/screen-style-variations.js +12 -5
  33. package/build/components/global-styles/screen-style-variations.js.map +1 -1
  34. package/build/components/header/document-actions/index.js +13 -11
  35. package/build/components/header/document-actions/index.js.map +1 -1
  36. package/build/components/header/index.js +5 -3
  37. package/build/components/header/index.js.map +1 -1
  38. package/build/components/header/more-menu/index.js +9 -1
  39. package/build/components/header/more-menu/index.js.map +1 -1
  40. package/build/components/header/more-menu/site-export.js +5 -2
  41. package/build/components/header/more-menu/site-export.js.map +1 -1
  42. package/build/components/header/plugin-more-menu-item/index.js +5 -0
  43. package/build/components/header/plugin-more-menu-item/index.js.map +1 -1
  44. package/build/components/list/actions/rename-menu-item.js +3 -10
  45. package/build/components/list/actions/rename-menu-item.js.map +1 -1
  46. package/build/components/preferences-modal/enable-feature.js +40 -0
  47. package/build/components/preferences-modal/enable-feature.js.map +1 -0
  48. package/build/components/preferences-modal/index.js +68 -0
  49. package/build/components/preferences-modal/index.js.map +1 -0
  50. package/build/components/sidebar/index.js +12 -1
  51. package/build/components/sidebar/index.js.map +1 -1
  52. package/build/components/sidebar/navigation-menu-sidebar/index.js +40 -0
  53. package/build/components/sidebar/navigation-menu-sidebar/index.js.map +1 -0
  54. package/build/components/sidebar/navigation-menu-sidebar/navigation-inspector.js +185 -0
  55. package/build/components/sidebar/navigation-menu-sidebar/navigation-inspector.js.map +1 -0
  56. package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js +54 -0
  57. package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -0
  58. package/build/components/template-part-converter/convert-to-regular.js +6 -0
  59. package/build/components/template-part-converter/convert-to-regular.js.map +1 -1
  60. package/build/index.js +1 -0
  61. package/build/index.js.map +1 -1
  62. package/build/store/actions.js +3 -3
  63. package/build/store/actions.js.map +1 -1
  64. package/build/store/selectors.js +3 -1
  65. package/build/store/selectors.js.map +1 -1
  66. package/build-module/components/add-new-template/new-template-part.js +3 -10
  67. package/build-module/components/add-new-template/new-template-part.js.map +1 -1
  68. package/build-module/components/add-new-template/new-template.js +27 -12
  69. package/build-module/components/add-new-template/new-template.js.map +1 -1
  70. package/build-module/components/block-editor/index.js +51 -6
  71. package/build-module/components/block-editor/index.js.map +1 -1
  72. package/build-module/components/editor/index.js +12 -5
  73. package/build-module/components/editor/index.js.map +1 -1
  74. package/build-module/components/global-styles/border-panel.js +27 -26
  75. package/build-module/components/global-styles/border-panel.js.map +1 -1
  76. package/build-module/components/global-styles/color-indicator-wrapper.js +25 -0
  77. package/build-module/components/global-styles/color-indicator-wrapper.js.map +1 -0
  78. package/build-module/components/global-styles/dimensions-panel.js +6 -2
  79. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  80. package/build-module/components/global-styles/header.js +2 -5
  81. package/build-module/components/global-styles/header.js.map +1 -1
  82. package/build-module/components/global-styles/icon-with-current-color.js +22 -0
  83. package/build-module/components/global-styles/icon-with-current-color.js.map +1 -0
  84. package/build-module/components/global-styles/navigation-button.js +7 -3
  85. package/build-module/components/global-styles/navigation-button.js.map +1 -1
  86. package/build-module/components/global-styles/palette.js +8 -6
  87. package/build-module/components/global-styles/palette.js.map +1 -1
  88. package/build-module/components/global-styles/preview.js +141 -27
  89. package/build-module/components/global-styles/preview.js.map +1 -1
  90. package/build-module/components/global-styles/screen-block-list.js +49 -6
  91. package/build-module/components/global-styles/screen-block-list.js.map +1 -1
  92. package/build-module/components/global-styles/screen-colors.js +10 -3
  93. package/build-module/components/global-styles/screen-colors.js.map +1 -1
  94. package/build-module/components/global-styles/screen-root.js +8 -7
  95. package/build-module/components/global-styles/screen-root.js.map +1 -1
  96. package/build-module/components/global-styles/screen-style-variations.js +13 -6
  97. package/build-module/components/global-styles/screen-style-variations.js.map +1 -1
  98. package/build-module/components/header/document-actions/index.js +13 -11
  99. package/build-module/components/header/document-actions/index.js.map +1 -1
  100. package/build-module/components/header/index.js +5 -3
  101. package/build-module/components/header/index.js.map +1 -1
  102. package/build-module/components/header/more-menu/index.js +8 -1
  103. package/build-module/components/header/more-menu/index.js.map +1 -1
  104. package/build-module/components/header/more-menu/site-export.js +5 -2
  105. package/build-module/components/header/more-menu/site-export.js.map +1 -1
  106. package/build-module/components/header/plugin-more-menu-item/index.js +4 -0
  107. package/build-module/components/header/plugin-more-menu-item/index.js.map +1 -1
  108. package/build-module/components/list/actions/rename-menu-item.js +4 -11
  109. package/build-module/components/list/actions/rename-menu-item.js.map +1 -1
  110. package/build-module/components/preferences-modal/enable-feature.js +27 -0
  111. package/build-module/components/preferences-modal/enable-feature.js.map +1 -0
  112. package/build-module/components/preferences-modal/index.js +57 -0
  113. package/build-module/components/preferences-modal/index.js.map +1 -0
  114. package/build-module/components/sidebar/index.js +11 -1
  115. package/build-module/components/sidebar/index.js.map +1 -1
  116. package/build-module/components/sidebar/navigation-menu-sidebar/index.js +26 -0
  117. package/build-module/components/sidebar/navigation-menu-sidebar/index.js.map +1 -0
  118. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-inspector.js +168 -0
  119. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-inspector.js.map +1 -0
  120. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js +45 -0
  121. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -0
  122. package/build-module/components/template-part-converter/convert-to-regular.js +6 -0
  123. package/build-module/components/template-part-converter/convert-to-regular.js.map +1 -1
  124. package/build-module/index.js +1 -0
  125. package/build-module/index.js.map +1 -1
  126. package/build-module/store/actions.js +3 -3
  127. package/build-module/store/actions.js.map +1 -1
  128. package/build-module/store/selectors.js +3 -1
  129. package/build-module/store/selectors.js.map +1 -1
  130. package/build-style/style-rtl.css +88 -6
  131. package/build-style/style.css +88 -6
  132. package/package.json +29 -29
  133. package/src/components/add-new-template/new-template-part.js +3 -12
  134. package/src/components/add-new-template/new-template.js +49 -12
  135. package/src/components/block-editor/index.js +79 -9
  136. package/src/components/editor/index.js +19 -1
  137. package/src/components/global-styles/border-panel.js +32 -26
  138. package/src/components/global-styles/color-indicator-wrapper.js +23 -0
  139. package/src/components/global-styles/dimensions-panel.js +7 -2
  140. package/src/components/global-styles/header.js +2 -7
  141. package/src/components/global-styles/icon-with-current-color.js +21 -0
  142. package/src/components/global-styles/navigation-button.js +6 -4
  143. package/src/components/global-styles/palette.js +8 -11
  144. package/src/components/global-styles/preview.js +186 -29
  145. package/src/components/global-styles/screen-block-list.js +64 -11
  146. package/src/components/global-styles/screen-colors.js +7 -6
  147. package/src/components/global-styles/screen-root.js +15 -17
  148. package/src/components/global-styles/screen-style-variations.js +13 -4
  149. package/src/components/global-styles/style.scss +20 -7
  150. package/src/components/header/document-actions/index.js +14 -10
  151. package/src/components/header/index.js +6 -1
  152. package/src/components/header/more-menu/index.js +15 -0
  153. package/src/components/header/more-menu/site-export.js +13 -2
  154. package/src/components/header/plugin-more-menu-item/index.js +2 -0
  155. package/src/components/header/style.scss +45 -0
  156. package/src/components/list/actions/rename-menu-item.js +3 -13
  157. package/src/components/preferences-modal/enable-feature.js +24 -0
  158. package/src/components/preferences-modal/index.js +76 -0
  159. package/src/components/sidebar/index.js +12 -0
  160. package/src/components/sidebar/navigation-menu-sidebar/index.js +34 -0
  161. package/src/components/sidebar/navigation-menu-sidebar/navigation-inspector.js +224 -0
  162. package/src/components/sidebar/navigation-menu-sidebar/navigation-menu.js +62 -0
  163. package/src/components/sidebar/navigation-menu-sidebar/style.scss +42 -0
  164. package/src/components/sidebar/style.scss +1 -1
  165. package/src/components/template-part-converter/convert-to-regular.js +9 -0
  166. package/src/index.js +1 -0
  167. package/src/store/actions.js +4 -4
  168. package/src/store/selectors.js +10 -0
  169. package/src/store/test/selectors.js +4 -0
  170. package/src/style.scss +1 -0
@@ -23,8 +23,17 @@ export default function SiteExport() {
23
23
  parse: false,
24
24
  } );
25
25
  const blob = await response.blob();
26
+ const contentDisposition = response.headers.get(
27
+ 'content-disposition'
28
+ );
29
+ const contentDispositionMatches = contentDisposition.match(
30
+ /=(.+)\.zip/
31
+ );
32
+ const fileName = contentDispositionMatches[ 1 ]
33
+ ? contentDispositionMatches[ 1 ]
34
+ : 'edit-site-export';
26
35
 
27
- downloadjs( blob, 'edit-site-export.zip', 'application/zip' );
36
+ downloadjs( blob, fileName + '.zip', 'application/zip' );
28
37
  } catch ( errorResponse ) {
29
38
  let error = {};
30
39
  try {
@@ -44,7 +53,9 @@ export default function SiteExport() {
44
53
  role="menuitem"
45
54
  icon={ download }
46
55
  onClick={ handleExport }
47
- info={ __( 'Download your templates and styles as a theme.' ) }
56
+ info={ __(
57
+ 'Download your theme with updated templates and styles.'
58
+ ) }
48
59
  >
49
60
  { _x( 'Export', 'site exporter menu item' ) }
50
61
  </MenuItem>
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { ActionItem } from '@wordpress/interface';
5
5
  import { compose } from '@wordpress/compose';
6
+ import { MenuItem } from '@wordpress/components';
6
7
  import { withPluginContext } from '@wordpress/plugins';
7
8
 
8
9
  /**
@@ -64,6 +65,7 @@ import { withPluginContext } from '@wordpress/plugins';
64
65
  export default compose(
65
66
  withPluginContext( ( context, ownProps ) => {
66
67
  return {
68
+ as: ownProps.as ?? MenuItem,
67
69
  icon: ownProps.icon || context.icon,
68
70
  name: 'core/edit-site/plugin-more-menu',
69
71
  };
@@ -163,3 +163,48 @@ body.is-navigation-sidebar-open {
163
163
  }
164
164
  }
165
165
  }
166
+
167
+ // Button text label styles
168
+
169
+ .show-icon-labels .edit-site-header {
170
+ .components-button.has-icon {
171
+ width: auto;
172
+
173
+ // Hide the button icons when labels are set to display...
174
+ svg {
175
+ display: none;
176
+ }
177
+ // ... and display labels.
178
+ &::after {
179
+ content: attr(aria-label);
180
+ }
181
+ &[aria-disabled="true"] {
182
+ background-color: transparent;
183
+ }
184
+ }
185
+ .is-tertiary {
186
+ &:active {
187
+ box-shadow: 0 0 0 1.5px var(--wp-admin-theme-color);
188
+ background-color: transparent;
189
+ }
190
+ }
191
+ // Some margins and padding have to be adjusted so the buttons can still fit on smaller screens.
192
+ .edit-site-save-button__button {
193
+ padding-left: 6px;
194
+ padding-right: 6px;
195
+ margin-right: $grid-unit-05;
196
+ }
197
+ .block-editor-post-preview__button-toggle {
198
+ margin-right: $grid-unit-05;
199
+ }
200
+ // The inserter and the template details toggle have custom labels, different from their aria-label, so we don't want to display both.
201
+ .edit-site-header-toolbar__inserter-toggle.edit-site-header-toolbar__inserter-toggle,
202
+ .edit-site-document-actions__get-info.edit-site-document-actions__get-info.edit-site-document-actions__get-info {
203
+ &::after {
204
+ content: none;
205
+ }
206
+
207
+ height: 36px;
208
+ padding: 0 6px;
209
+ }
210
+ }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { useState } from '@wordpress/element';
6
- import { useDispatch, useSelect } from '@wordpress/data';
6
+ import { useDispatch } from '@wordpress/data';
7
7
  import {
8
8
  Button,
9
9
  Flex,
@@ -19,7 +19,6 @@ export default function RenameMenuItem( { template, onClose } ) {
19
19
  const [ title, setTitle ] = useState( () => template.title.rendered );
20
20
  const [ isModalOpen, setIsModalOpen ] = useState( false );
21
21
 
22
- const { getLastEntitySaveError } = useSelect( coreStore );
23
22
  const { editEntityRecord, saveEditedEntityRecord } = useDispatch(
24
23
  coreStore
25
24
  );
@@ -48,19 +47,10 @@ export default function RenameMenuItem( { template, onClose } ) {
48
47
  await saveEditedEntityRecord(
49
48
  'postType',
50
49
  template.type,
51
- template.id
50
+ template.id,
51
+ { throwOnError: true }
52
52
  );
53
53
 
54
- const lastError = getLastEntitySaveError(
55
- 'postType',
56
- template.type,
57
- template.id
58
- );
59
-
60
- if ( lastError ) {
61
- throw lastError;
62
- }
63
-
64
54
  createSuccessNotice( __( 'Entity renamed.' ), {
65
55
  type: 'snackbar',
66
56
  } );
@@ -0,0 +1,24 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+ import { ___unstablePreferencesModalBaseOption as BaseOption } from '@wordpress/interface';
6
+ import { store as preferencesStore } from '@wordpress/preferences';
7
+
8
+ export default function EnableFeature( props ) {
9
+ const { featureName, ...remainingProps } = props;
10
+ const isChecked = useSelect(
11
+ ( select ) =>
12
+ !! select( preferencesStore ).get( 'core/edit-site', featureName ),
13
+ [ featureName ]
14
+ );
15
+ const { toggle } = useDispatch( preferencesStore );
16
+ const onChange = () => toggle( 'core/edit-site', featureName );
17
+ return (
18
+ <BaseOption
19
+ onChange={ onChange }
20
+ isChecked={ isChecked }
21
+ { ...remainingProps }
22
+ />
23
+ );
24
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ PreferencesModal,
6
+ PreferencesModalTabs,
7
+ PreferencesModalSection,
8
+ } from '@wordpress/interface';
9
+ import { useMemo } from '@wordpress/element';
10
+ import { __ } from '@wordpress/i18n';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import EnableFeature from './enable-feature';
16
+
17
+ export default function EditSitePreferencesModal( {
18
+ isModalActive,
19
+ toggleModal,
20
+ } ) {
21
+ const sections = useMemo( () => [
22
+ {
23
+ name: 'general',
24
+ tabLabel: __( 'General' ),
25
+ content: (
26
+ <PreferencesModalSection
27
+ title={ __( 'Appearance' ) }
28
+ description={ __(
29
+ 'Customize options related to the block editor interface and editing flow.'
30
+ ) }
31
+ >
32
+ <EnableFeature
33
+ featureName="focusMode"
34
+ help={ __(
35
+ 'Highlights the current block and fades other content.'
36
+ ) }
37
+ label={ __( 'Spotlight mode' ) }
38
+ />
39
+ <EnableFeature
40
+ featureName="showIconLabels"
41
+ label={ __( 'Show button text labels' ) }
42
+ help={ __( 'Show text instead of icons on buttons' ) }
43
+ />
44
+ </PreferencesModalSection>
45
+ ),
46
+ },
47
+ {
48
+ name: 'blocks',
49
+ tabLabel: __( 'Blocks' ),
50
+ content: (
51
+ <PreferencesModalSection
52
+ title={ __( 'Block interactions' ) }
53
+ description={ __(
54
+ 'Customize how you interact with blocks in the block library and editing canvas.'
55
+ ) }
56
+ >
57
+ <EnableFeature
58
+ featureName="keepCaretInsideBlock"
59
+ help={ __(
60
+ 'Aids screen readers by stopping text caret from leaving blocks.'
61
+ ) }
62
+ label={ __( 'Contain text cursor inside block' ) }
63
+ />
64
+ </PreferencesModalSection>
65
+ ),
66
+ },
67
+ ] );
68
+ if ( ! isModalActive ) {
69
+ return null;
70
+ }
71
+ return (
72
+ <PreferencesModal closeModal={ toggleModal }>
73
+ <PreferencesModalTabs sections={ sections } />
74
+ </PreferencesModal>
75
+ );
76
+ }
@@ -14,6 +14,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
14
14
  */
15
15
  import DefaultSidebar from './default-sidebar';
16
16
  import GlobalStylesSidebar from './global-styles-sidebar';
17
+ import NavigationMenuSidebar from './navigation-menu-sidebar';
17
18
  import { STORE_NAME } from '../../store/constants';
18
19
  import SettingsHeader from './settings-header';
19
20
  import TemplateCard from './template-card';
@@ -57,6 +58,16 @@ export function SidebarComplementaryAreaFills() {
57
58
  if ( ! isEditorSidebarOpened ) {
58
59
  sidebarName = hasBlockSelection ? SIDEBAR_BLOCK : SIDEBAR_TEMPLATE;
59
60
  }
61
+
62
+ // Conditionally include NavMenu sidebar in Plugin only.
63
+ // Optimise for dead code elimination.
64
+ // See https://github.com/WordPress/gutenberg/blob/trunk/docs/how-to-guides/feature-flags.md#dead-code-elimination.
65
+ let MaybeNavigationMenuSidebar = 'Fragment';
66
+
67
+ if ( process.env.IS_GUTENBERG_PLUGIN ) {
68
+ MaybeNavigationMenuSidebar = NavigationMenuSidebar;
69
+ }
70
+
60
71
  return (
61
72
  <>
62
73
  <DefaultSidebar
@@ -77,6 +88,7 @@ export function SidebarComplementaryAreaFills() {
77
88
  ) }
78
89
  </DefaultSidebar>
79
90
  <GlobalStylesSidebar />
91
+ <MaybeNavigationMenuSidebar />
80
92
  </>
81
93
  );
82
94
  }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { FlexBlock, Flex } from '@wordpress/components';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { navigation } from '@wordpress/icons';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import DefaultSidebar from '../default-sidebar';
12
+ import NavigationInspector from './navigation-inspector';
13
+
14
+ export default function NavigationMenuSidebar() {
15
+ return (
16
+ <DefaultSidebar
17
+ className="edit-site-navigation-menu-sidebar"
18
+ identifier="edit-site/navigation-menu"
19
+ title={ __( 'Navigation Menus' ) }
20
+ icon={ navigation }
21
+ closeLabel={ __( 'Close navigation menu sidebar' ) }
22
+ panelClassName="edit-site-navigation-menu-sidebar__panel"
23
+ header={
24
+ <Flex>
25
+ <FlexBlock>
26
+ <strong>{ __( 'Navigation Menus' ) }</strong>
27
+ </FlexBlock>
28
+ </Flex>
29
+ }
30
+ >
31
+ <NavigationInspector />
32
+ </DefaultSidebar>
33
+ );
34
+ }
@@ -0,0 +1,224 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { useState, useEffect } from '@wordpress/element';
6
+ import { SelectControl } from '@wordpress/components';
7
+ import { store as coreStore, useEntityBlockEditor } from '@wordpress/core-data';
8
+ import {
9
+ store as blockEditorStore,
10
+ BlockEditorProvider,
11
+ } from '@wordpress/block-editor';
12
+ import { speak } from '@wordpress/a11y';
13
+ import { useInstanceId } from '@wordpress/compose';
14
+ import { __ } from '@wordpress/i18n';
15
+
16
+ /**
17
+ * Internal dependencies
18
+ */
19
+ import NavigationMenu from './navigation-menu';
20
+
21
+ const NAVIGATION_MENUS_QUERY = [ { per_page: -1, status: 'publish' } ];
22
+
23
+ export default function NavigationInspector() {
24
+ const {
25
+ selectedNavigationBlockId,
26
+ clientIdToRef,
27
+ navigationMenus,
28
+ isResolvingNavigationMenus,
29
+ hasResolvedNavigationMenus,
30
+ firstNavigationBlockId,
31
+ } = useSelect( ( select ) => {
32
+ const {
33
+ __experimentalGetActiveBlockIdByBlockNames,
34
+ __experimentalGetGlobalBlocksByName,
35
+ getBlock,
36
+ } = select( blockEditorStore );
37
+
38
+ const { getEntityRecords, hasFinishedResolution, isResolving } = select(
39
+ coreStore
40
+ );
41
+
42
+ const navigationMenusQuery = [
43
+ 'postType',
44
+ 'wp_navigation',
45
+ NAVIGATION_MENUS_QUERY[ 0 ],
46
+ ];
47
+
48
+ // Get the active Navigation block (if present).
49
+ const selectedNavId = __experimentalGetActiveBlockIdByBlockNames(
50
+ 'core/navigation'
51
+ );
52
+
53
+ // Get all Navigation blocks currently within the editor canvas.
54
+ const navBlockIds = __experimentalGetGlobalBlocksByName(
55
+ 'core/navigation'
56
+ );
57
+ const idToRef = {};
58
+ navBlockIds.forEach( ( id ) => {
59
+ idToRef[ id ] = getBlock( id )?.attributes?.ref;
60
+ } );
61
+ return {
62
+ selectedNavigationBlockId: selectedNavId,
63
+ firstNavigationBlockId: navBlockIds?.[ 0 ],
64
+ clientIdToRef: idToRef,
65
+ navigationMenus: getEntityRecords( ...navigationMenusQuery ),
66
+ isResolvingNavigationMenus: isResolving(
67
+ 'getEntityRecords',
68
+ navigationMenusQuery
69
+ ),
70
+ hasResolvedNavigationMenus: hasFinishedResolution(
71
+ 'getEntityRecords',
72
+ navigationMenusQuery
73
+ ),
74
+ };
75
+ }, [] );
76
+
77
+ const navMenuListId = useInstanceId(
78
+ NavigationMenu,
79
+ 'edit-site-navigation-inspector-menu'
80
+ );
81
+
82
+ const firstNavRefInTemplate = clientIdToRef[ firstNavigationBlockId ];
83
+ const firstNavigationMenuRef = navigationMenus?.[ 0 ]?.id;
84
+
85
+ // Default Navigation Menu is either:
86
+ // - the Navigation Menu referenced by the first Nav block within the template.
87
+ // - the first of the available Navigation Menus (`wp_navigation`) posts.
88
+ const defaultNavigationMenuId =
89
+ firstNavRefInTemplate || firstNavigationMenuRef;
90
+
91
+ // The Navigation Menu manually selected by the user within the Nav inspector.
92
+ const [ currentMenuId, setCurrentMenuId ] = useState(
93
+ firstNavRefInTemplate
94
+ );
95
+
96
+ // If a Nav block is selected within the canvas then set the
97
+ // Navigation Menu referenced by it's `ref` attribute to be
98
+ // active within the Navigation sidebar.
99
+ useEffect( () => {
100
+ if ( selectedNavigationBlockId ) {
101
+ setCurrentMenuId( clientIdToRef[ selectedNavigationBlockId ] );
102
+ }
103
+ }, [ selectedNavigationBlockId ] );
104
+
105
+ let options = [];
106
+ if ( navigationMenus ) {
107
+ options = navigationMenus.map( ( { id, title } ) => ( {
108
+ value: id,
109
+ label: title.rendered,
110
+ } ) );
111
+ }
112
+
113
+ const [ innerBlocks, onInput, onChange ] = useEntityBlockEditor(
114
+ 'postType',
115
+ 'wp_navigation',
116
+ { id: currentMenuId || defaultNavigationMenuId }
117
+ );
118
+
119
+ const { isLoadingInnerBlocks, hasLoadedInnerBlocks } = useSelect(
120
+ ( select ) => {
121
+ const { isResolving, hasFinishedResolution } = select( coreStore );
122
+ return {
123
+ isLoadingInnerBlocks: isResolving( 'getEntityRecord', [
124
+ 'postType',
125
+ 'wp_navigation',
126
+ currentMenuId || defaultNavigationMenuId,
127
+ ] ),
128
+ hasLoadedInnerBlocks: hasFinishedResolution(
129
+ 'getEntityRecord',
130
+ [
131
+ 'postType',
132
+ 'wp_navigation',
133
+ currentMenuId || defaultNavigationMenuId,
134
+ ]
135
+ ),
136
+ };
137
+ },
138
+ [ currentMenuId, defaultNavigationMenuId ]
139
+ );
140
+
141
+ const isLoading = ! ( hasResolvedNavigationMenus && hasLoadedInnerBlocks );
142
+
143
+ const hasMoreThanOneNavigationMenu = navigationMenus?.length > 1;
144
+
145
+ const hasNavigationMenus = !! navigationMenus?.length;
146
+
147
+ // Entity block editor will return entities that are not currently published.
148
+ // Guard by only allowing their usage if there are published Nav Menus.
149
+ const publishedInnerBlocks = hasNavigationMenus ? innerBlocks : [];
150
+
151
+ const hasInnerBlocks = !! publishedInnerBlocks?.length;
152
+
153
+ useEffect( () => {
154
+ if ( isResolvingNavigationMenus ) {
155
+ speak( 'Loading Navigation sidebar menus.' );
156
+ }
157
+
158
+ if ( hasResolvedNavigationMenus ) {
159
+ speak( 'Navigation sidebar menus have loaded.' );
160
+ }
161
+ }, [ isResolvingNavigationMenus, hasResolvedNavigationMenus ] );
162
+
163
+ useEffect( () => {
164
+ if ( isLoadingInnerBlocks ) {
165
+ speak( 'Loading Navigation sidebar selected menu items.' );
166
+ }
167
+
168
+ if ( hasLoadedInnerBlocks ) {
169
+ speak( 'Navigation sidebar selected menu items have loaded.' );
170
+ }
171
+ }, [ isLoadingInnerBlocks, hasLoadedInnerBlocks ] );
172
+
173
+ return (
174
+ <div className="edit-site-navigation-inspector">
175
+ { hasResolvedNavigationMenus && ! hasNavigationMenus && (
176
+ <p className="edit-site-navigation-inspector__empty-msg">
177
+ { __( 'There are no Navigation Menus.' ) }
178
+ </p>
179
+ ) }
180
+
181
+ { ! hasResolvedNavigationMenus && (
182
+ <div className="edit-site-navigation-inspector__placeholder" />
183
+ ) }
184
+ { hasResolvedNavigationMenus && hasMoreThanOneNavigationMenu && (
185
+ <SelectControl
186
+ aria-controls={
187
+ // aria-controls should only apply when referenced element is in DOM
188
+ hasLoadedInnerBlocks ? navMenuListId : undefined
189
+ }
190
+ value={ currentMenuId || defaultNavigationMenuId }
191
+ options={ options }
192
+ onChange={ ( newMenuId ) =>
193
+ setCurrentMenuId( Number( newMenuId ) )
194
+ }
195
+ />
196
+ ) }
197
+ { isLoading && (
198
+ <>
199
+ <div className="edit-site-navigation-inspector__placeholder is-child" />
200
+ <div className="edit-site-navigation-inspector__placeholder is-child" />
201
+ <div className="edit-site-navigation-inspector__placeholder is-child" />
202
+ </>
203
+ ) }
204
+ { hasInnerBlocks && ! isLoading && (
205
+ <BlockEditorProvider
206
+ value={ publishedInnerBlocks }
207
+ onChange={ onChange }
208
+ onInput={ onInput }
209
+ >
210
+ <NavigationMenu
211
+ id={ navMenuListId }
212
+ innerBlocks={ publishedInnerBlocks }
213
+ />
214
+ </BlockEditorProvider>
215
+ ) }
216
+
217
+ { ! hasInnerBlocks && ! isLoading && (
218
+ <p className="edit-site-navigation-inspector__empty-msg">
219
+ { __( 'Navigation Menu is empty.' ) }
220
+ </p>
221
+ ) }
222
+ </div>
223
+ );
224
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ __experimentalListView as ListView,
6
+ store as blockEditorStore,
7
+ } from '@wordpress/block-editor';
8
+ import { useEffect } from '@wordpress/element';
9
+ import { useDispatch } from '@wordpress/data';
10
+
11
+ const ALLOWED_BLOCKS = {
12
+ 'core/navigation': [
13
+ 'core/navigation-link',
14
+ 'core/search',
15
+ 'core/social-links',
16
+ 'core/page-list',
17
+ 'core/spacer',
18
+ 'core/home-link',
19
+ 'core/site-title',
20
+ 'core/site-logo',
21
+ 'core/navigation-submenu',
22
+ ],
23
+ 'core/social-links': [ 'core/social-link' ],
24
+ 'core/navigation-submenu': [
25
+ 'core/navigation-link',
26
+ 'core/navigation-submenu',
27
+ ],
28
+ 'core/navigation-link': [
29
+ 'core/navigation-link',
30
+ 'core/navigation-submenu',
31
+ ],
32
+ };
33
+
34
+ export default function NavigationMenu( { innerBlocks, id } ) {
35
+ const { updateBlockListSettings } = useDispatch( blockEditorStore );
36
+
37
+ //TODO: Block settings are normally updated as a side effect of rendering InnerBlocks in BlockList
38
+ //Think through a better way of doing this, possible with adding allowed blocks to block library metadata
39
+ useEffect( () => {
40
+ updateBlockListSettings( '', {
41
+ allowedBlocks: ALLOWED_BLOCKS[ 'core/navigation' ],
42
+ } );
43
+ innerBlocks.forEach( ( block ) => {
44
+ if ( ALLOWED_BLOCKS[ block.name ] ) {
45
+ updateBlockListSettings( block.clientId, {
46
+ allowedBlocks: ALLOWED_BLOCKS[ block.name ],
47
+ } );
48
+ }
49
+ } );
50
+ }, [ updateBlockListSettings, innerBlocks ] );
51
+ return (
52
+ <>
53
+ <ListView
54
+ id={ id }
55
+ showNestedBlocks
56
+ expandNested={ false }
57
+ __experimentalFeatures
58
+ __experimentalPersistentListViewFeatures
59
+ />
60
+ </>
61
+ );
62
+ }
@@ -0,0 +1,42 @@
1
+ @keyframes loadingpulse {
2
+ 0% {
3
+ opacity: 1;
4
+ }
5
+ 50% {
6
+ opacity: 0.5;
7
+ }
8
+ 100% {
9
+ opacity: 1;
10
+ }
11
+ }
12
+
13
+ .edit-site-navigation-inspector {
14
+ padding: $grid-unit-20;
15
+
16
+ .block-editor-list-view-leaf .block-editor-list-view-block-contents {
17
+ align-items: flex-start;
18
+ white-space: normal;
19
+ }
20
+
21
+ .block-editor-list-view-block__title {
22
+ margin-top: 3px;
23
+ }
24
+
25
+ .block-editor-list-view-block__menu-cell {
26
+ padding-right: 0;
27
+ }
28
+ }
29
+
30
+
31
+ .edit-site-navigation-inspector__placeholder {
32
+ padding: $grid-unit-10;
33
+ margin: $grid-unit-10;
34
+ background-color: $gray-100;
35
+ animation: loadingpulse 1s linear infinite;
36
+ animation-delay: 0.5s; // avoid animating for fast network responses
37
+
38
+ &.is-child {
39
+ margin-left: $grid-unit-30;
40
+ width: 50%;
41
+ }
42
+ }
@@ -80,7 +80,7 @@
80
80
  padding: 0 $grid-unit-10;
81
81
  height: $grid-unit-30;
82
82
  border-radius: $radius-block-ui;
83
- background-color: $black;
83
+ background-color: $gray-900;
84
84
  color: $white;
85
85
  align-items: center;
86
86
  font-size: $helptext-font-size;
@@ -13,6 +13,15 @@ export default function ConvertToRegularBlocks( { clientId } ) {
13
13
  const { getBlocks } = useSelect( blockEditorStore );
14
14
  const { replaceBlocks } = useDispatch( blockEditorStore );
15
15
 
16
+ const canRemove = useSelect(
17
+ ( select ) => select( blockEditorStore ).canRemoveBlock( clientId ),
18
+ [ clientId ]
19
+ );
20
+
21
+ if ( ! canRemove ) {
22
+ return null;
23
+ }
24
+
16
25
  return (
17
26
  <BlockSettingsMenuControls>
18
27
  { ( { onClose } ) => (
package/src/index.js CHANGED
@@ -61,6 +61,7 @@ export function reinitializeEditor( target, settings ) {
61
61
  editorMode: 'visual',
62
62
  fixedToolbar: false,
63
63
  focusMode: false,
64
+ keepCaretInsideBlock: false,
64
65
  welcomeGuide: true,
65
66
  welcomeGuideStyles: true,
66
67
  } );
@@ -333,11 +333,11 @@ export const revertTemplate = (
333
333
  }
334
334
 
335
335
  try {
336
- const templateEntity = registry
336
+ const templateEntityConfig = registry
337
337
  .select( coreStore )
338
- .getEntity( 'postType', template.type );
338
+ .getEntityConfig( 'postType', template.type );
339
339
 
340
- if ( ! templateEntity ) {
340
+ if ( ! templateEntityConfig ) {
341
341
  registry
342
342
  .dispatch( noticesStore )
343
343
  .createErrorNotice(
@@ -350,7 +350,7 @@ export const revertTemplate = (
350
350
  }
351
351
 
352
352
  const fileTemplatePath = addQueryArgs(
353
- `${ templateEntity.baseURL }/${ template.id }`,
353
+ `${ templateEntityConfig.baseURL }/${ template.id }`,
354
354
  { context: 'edit', source: 'theme' }
355
355
  );
356
356