@wordpress/block-library 6.0.7 → 6.0.11

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 (193) hide show
  1. package/build/cover/edit.js +8 -3
  2. package/build/cover/edit.js.map +1 -1
  3. package/build/cover/transforms.js +2 -0
  4. package/build/cover/transforms.js.map +1 -1
  5. package/build/gallery/edit.js +1 -1
  6. package/build/gallery/edit.js.map +1 -1
  7. package/build/gallery/v1/update-gallery-modal.js +1 -1
  8. package/build/gallery/v1/update-gallery-modal.js.map +1 -1
  9. package/build/index.js +4 -3
  10. package/build/index.js.map +1 -1
  11. package/build/navigation/deprecated.js +127 -19
  12. package/build/navigation/deprecated.js.map +1 -1
  13. package/build/navigation/edit/index.js +59 -33
  14. package/build/navigation/edit/index.js.map +1 -1
  15. package/build/navigation/edit/inner-blocks.js +1 -1
  16. package/build/navigation/edit/inner-blocks.js.map +1 -1
  17. package/build/navigation/edit/navigation-menu-selector.js +2 -2
  18. package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
  19. package/build/navigation/edit/placeholder/index.js +16 -48
  20. package/build/navigation/edit/placeholder/index.js.map +1 -1
  21. package/build/navigation/edit/responsive-wrapper.js +5 -2
  22. package/build/navigation/edit/responsive-wrapper.js.map +1 -1
  23. package/build/navigation/edit/unsaved-inner-blocks.js +4 -35
  24. package/build/navigation/edit/unsaved-inner-blocks.js.map +1 -1
  25. package/build/navigation/edit/use-create-navigation-menu.js +50 -0
  26. package/build/navigation/edit/use-create-navigation-menu.js.map +1 -0
  27. package/build/navigation/edit/use-generate-default-navigation-title.js +73 -0
  28. package/build/navigation/edit/use-generate-default-navigation-title.js.map +1 -0
  29. package/build/navigation/index.js +1 -1
  30. package/build/navigation/save.js +2 -2
  31. package/build/navigation/save.js.map +1 -1
  32. package/build/navigation/use-navigation-menu.js +19 -8
  33. package/build/navigation/use-navigation-menu.js.map +1 -1
  34. package/build/navigation-area/edit.js +5 -0
  35. package/build/navigation-area/edit.js.map +1 -1
  36. package/build/page-list/edit.js +40 -42
  37. package/build/page-list/edit.js.map +1 -1
  38. package/build/pattern/index.js +1 -1
  39. package/build/post-featured-image/edit.js +53 -23
  40. package/build/post-featured-image/edit.js.map +1 -1
  41. package/build/post-terms/index.js +1 -1
  42. package/build/post-title/edit.js +2 -2
  43. package/build/post-title/edit.js.map +1 -1
  44. package/build/query-pagination-next/index.js +1 -1
  45. package/build/query-pagination-previous/index.js +1 -1
  46. package/build/query-title/index.js +1 -1
  47. package/build/site-logo/index.js +1 -1
  48. package/build/site-tagline/index.js +1 -1
  49. package/build/site-title/index.js +1 -1
  50. package/build/template-part/edit/placeholder/index.js +1 -1
  51. package/build/template-part/edit/placeholder/index.js.map +1 -1
  52. package/build/template-part/index.js +2 -1
  53. package/build/template-part/index.js.map +1 -1
  54. package/build-module/cover/edit.js +8 -3
  55. package/build-module/cover/edit.js.map +1 -1
  56. package/build-module/cover/transforms.js +2 -0
  57. package/build-module/cover/transforms.js.map +1 -1
  58. package/build-module/gallery/edit.js +1 -1
  59. package/build-module/gallery/edit.js.map +1 -1
  60. package/build-module/gallery/v1/update-gallery-modal.js +1 -1
  61. package/build-module/gallery/v1/update-gallery-modal.js.map +1 -1
  62. package/build-module/index.js +4 -3
  63. package/build-module/index.js.map +1 -1
  64. package/build-module/navigation/deprecated.js +127 -19
  65. package/build-module/navigation/deprecated.js.map +1 -1
  66. package/build-module/navigation/edit/index.js +60 -33
  67. package/build-module/navigation/edit/index.js.map +1 -1
  68. package/build-module/navigation/edit/inner-blocks.js +1 -1
  69. package/build-module/navigation/edit/inner-blocks.js.map +1 -1
  70. package/build-module/navigation/edit/navigation-menu-selector.js +2 -2
  71. package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
  72. package/build-module/navigation/edit/placeholder/index.js +15 -45
  73. package/build-module/navigation/edit/placeholder/index.js.map +1 -1
  74. package/build-module/navigation/edit/responsive-wrapper.js +5 -2
  75. package/build-module/navigation/edit/responsive-wrapper.js.map +1 -1
  76. package/build-module/navigation/edit/unsaved-inner-blocks.js +6 -35
  77. package/build-module/navigation/edit/unsaved-inner-blocks.js.map +1 -1
  78. package/build-module/navigation/edit/use-create-navigation-menu.js +36 -0
  79. package/build-module/navigation/edit/use-create-navigation-menu.js.map +1 -0
  80. package/build-module/navigation/edit/use-generate-default-navigation-title.js +57 -0
  81. package/build-module/navigation/edit/use-generate-default-navigation-title.js.map +1 -0
  82. package/build-module/navigation/index.js +1 -1
  83. package/build-module/navigation/save.js +2 -2
  84. package/build-module/navigation/save.js.map +1 -1
  85. package/build-module/navigation/use-navigation-menu.js +19 -8
  86. package/build-module/navigation/use-navigation-menu.js.map +1 -1
  87. package/build-module/navigation-area/edit.js +4 -0
  88. package/build-module/navigation-area/edit.js.map +1 -1
  89. package/build-module/page-list/edit.js +41 -43
  90. package/build-module/page-list/edit.js.map +1 -1
  91. package/build-module/pattern/index.js +1 -1
  92. package/build-module/post-featured-image/edit.js +55 -26
  93. package/build-module/post-featured-image/edit.js.map +1 -1
  94. package/build-module/post-terms/index.js +1 -1
  95. package/build-module/post-title/edit.js +2 -2
  96. package/build-module/post-title/edit.js.map +1 -1
  97. package/build-module/query-pagination-next/index.js +1 -1
  98. package/build-module/query-pagination-previous/index.js +1 -1
  99. package/build-module/query-title/index.js +1 -1
  100. package/build-module/site-logo/index.js +1 -1
  101. package/build-module/site-tagline/index.js +1 -1
  102. package/build-module/site-title/index.js +1 -1
  103. package/build-module/template-part/edit/placeholder/index.js +2 -2
  104. package/build-module/template-part/edit/placeholder/index.js.map +1 -1
  105. package/build-module/template-part/index.js +2 -1
  106. package/build-module/template-part/index.js.map +1 -1
  107. package/build-style/code/theme-rtl.css +1 -1
  108. package/build-style/code/theme.css +1 -1
  109. package/build-style/cover/style-rtl.css +8 -2
  110. package/build-style/cover/style.css +8 -2
  111. package/build-style/editor-rtl.css +104 -53
  112. package/build-style/editor.css +104 -53
  113. package/build-style/gallery/editor-rtl.css +1 -0
  114. package/build-style/gallery/editor.css +1 -0
  115. package/build-style/navigation/style-rtl.css +41 -3
  116. package/build-style/navigation/style.css +41 -3
  117. package/build-style/post-comments-form/style-rtl.css +18 -0
  118. package/build-style/post-comments-form/style.css +18 -0
  119. package/build-style/post-featured-image/editor-rtl.css +100 -16
  120. package/build-style/post-featured-image/editor.css +100 -16
  121. package/build-style/site-logo/editor-rtl.css +2 -2
  122. package/build-style/site-logo/editor.css +2 -2
  123. package/build-style/social-links/editor-rtl.css +1 -35
  124. package/build-style/social-links/editor.css +1 -35
  125. package/build-style/style-rtl.css +67 -27
  126. package/build-style/style.css +67 -27
  127. package/build-style/theme-rtl.css +1 -1
  128. package/build-style/theme.css +1 -1
  129. package/package.json +8 -8
  130. package/src/calendar/index.php +3 -3
  131. package/src/code/theme.scss +1 -1
  132. package/src/cover/edit.js +8 -1
  133. package/src/cover/style.scss +9 -2
  134. package/src/cover/transforms.js +2 -0
  135. package/src/gallery/edit.js +1 -1
  136. package/src/gallery/editor.scss +1 -0
  137. package/src/gallery/index.php +1 -1
  138. package/src/gallery/v1/update-gallery-modal.js +1 -1
  139. package/src/home-link/index.php +1 -1
  140. package/src/image/index.php +1 -1
  141. package/src/index.js +28 -26
  142. package/src/navigation/block.json +1 -1
  143. package/src/navigation/deprecated.js +115 -13
  144. package/src/navigation/edit/index.js +68 -36
  145. package/src/navigation/edit/inner-blocks.js +2 -1
  146. package/src/navigation/edit/navigation-menu-selector.js +2 -2
  147. package/src/navigation/edit/placeholder/index.js +16 -62
  148. package/src/navigation/edit/responsive-wrapper.js +8 -1
  149. package/src/navigation/edit/unsaved-inner-blocks.js +6 -57
  150. package/src/navigation/edit/use-create-navigation-menu.js +39 -0
  151. package/src/navigation/edit/use-generate-default-navigation-title.js +79 -0
  152. package/src/navigation/index.php +171 -25
  153. package/src/navigation/save.js +2 -2
  154. package/src/navigation/style.scss +57 -5
  155. package/src/navigation/use-navigation-menu.js +20 -9
  156. package/src/navigation-area/edit.js +5 -0
  157. package/src/navigation-area/index.php +2 -1
  158. package/src/navigation-link/index.php +1 -1
  159. package/src/navigation-submenu/index.php +2 -8
  160. package/src/page-list/edit.js +35 -44
  161. package/src/page-list/index.php +10 -5
  162. package/src/pattern/block.json +1 -1
  163. package/src/post-comments-form/style.scss +20 -1
  164. package/src/post-featured-image/edit.js +58 -26
  165. package/src/post-featured-image/editor.scss +124 -20
  166. package/src/post-terms/block.json +1 -1
  167. package/src/post-title/edit.js +2 -2
  168. package/src/query-pagination-next/block.json +1 -1
  169. package/src/query-pagination-previous/block.json +1 -1
  170. package/src/query-title/block.json +1 -1
  171. package/src/site-logo/block.json +1 -1
  172. package/src/site-logo/editor.scss +3 -2
  173. package/src/site-tagline/block.json +1 -1
  174. package/src/site-title/block.json +1 -1
  175. package/src/social-links/editor.scss +1 -47
  176. package/src/style.scss +0 -1
  177. package/src/table-of-contents/index.php +1 -1
  178. package/src/template-part/block.json +2 -1
  179. package/src/template-part/edit/placeholder/index.js +2 -2
  180. package/src/template-part/index.php +2 -1
  181. package/build/navigation/edit/navigation-menu-name-modal.js +0 -55
  182. package/build/navigation/edit/navigation-menu-name-modal.js.map +0 -1
  183. package/build/navigation/edit/navigation-menu-publish-button.js +0 -53
  184. package/build/navigation/edit/navigation-menu-publish-button.js.map +0 -1
  185. package/build-module/navigation/edit/navigation-menu-name-modal.js +0 -47
  186. package/build-module/navigation/edit/navigation-menu-name-modal.js.map +0 -1
  187. package/build-module/navigation/edit/navigation-menu-publish-button.js +0 -40
  188. package/build-module/navigation/edit/navigation-menu-publish-button.js.map +0 -1
  189. package/build-style/navigation-submenu/style-rtl.css +0 -97
  190. package/build-style/navigation-submenu/style.css +0 -97
  191. package/src/navigation/edit/navigation-menu-name-modal.js +0 -69
  192. package/src/navigation/edit/navigation-menu-publish-button.js +0 -57
  193. package/src/navigation-submenu/style.scss +0 -25
@@ -7,18 +7,16 @@ import classnames from 'classnames';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { useInnerBlocksProps } from '@wordpress/block-editor';
10
- import { serialize } from '@wordpress/blocks';
11
10
  import { Disabled, Spinner } from '@wordpress/components';
12
11
  import { store as coreStore } from '@wordpress/core-data';
13
- import { useDispatch, useSelect } from '@wordpress/data';
14
- import { useCallback, useContext, useEffect, useRef } from '@wordpress/element';
15
- import { __, sprintf } from '@wordpress/i18n';
12
+ import { useSelect } from '@wordpress/data';
13
+ import { useContext, useEffect, useRef } from '@wordpress/element';
16
14
 
17
15
  /**
18
16
  * Internal dependencies
19
17
  */
20
18
  import useNavigationMenu from '../use-navigation-menu';
21
- import useTemplatePartAreaLabel from '../use-template-part-area-label';
19
+ import useCreateNavigationMenu from './use-create-navigation-menu';
22
20
 
23
21
  const NOOP = () => {};
24
22
  const EMPTY_OBJECT = {};
@@ -51,7 +49,6 @@ export default function UnsavedInnerBlocks( {
51
49
  onChange: NOOP,
52
50
  onInput: NOOP,
53
51
  } );
54
- const { saveEntityRecord } = useDispatch( coreStore );
55
52
 
56
53
  const {
57
54
  isSaving,
@@ -83,29 +80,7 @@ export default function UnsavedInnerBlocks( {
83
80
 
84
81
  const { hasResolvedNavigationMenus, navigationMenus } = useNavigationMenu();
85
82
 
86
- const createNavigationMenu = useCallback(
87
- async ( title ) => {
88
- const record = {
89
- title,
90
- content: serialize( blocks ),
91
- status: 'draft',
92
- };
93
-
94
- const navigationMenu = await saveEntityRecord(
95
- 'postType',
96
- 'wp_navigation',
97
- record
98
- );
99
-
100
- return navigationMenu;
101
- },
102
- [ blocks, serialize, saveEntityRecord ]
103
- );
104
-
105
- // Because we can't conditionally call hooks, pass an undefined client id
106
- // arg to bypass the expensive `useTemplateArea` code. The hook will return
107
- // early.
108
- const area = useTemplatePartAreaLabel( isDisabled ? undefined : clientId );
83
+ const createNavigationMenu = useCreateNavigationMenu( clientId );
109
84
 
110
85
  // Automatically save the uncontrolled blocks.
111
86
  useEffect( async () => {
@@ -134,33 +109,7 @@ export default function UnsavedInnerBlocks( {
134
109
  }
135
110
 
136
111
  savingLock.current = true;
137
- const title = area
138
- ? sprintf(
139
- // translators: %s: the name of a menu (e.g. Header navigation).
140
- __( '%s navigation' ),
141
- area
142
- )
143
- : // translators: 'navigation' as in website navigation.
144
- __( 'Navigation' );
145
-
146
- // Determine how many menus start with the automatic title.
147
- const matchingMenuTitleCount = [
148
- ...draftNavigationMenus,
149
- ...navigationMenus,
150
- ].reduce(
151
- ( count, menu ) =>
152
- menu?.title?.raw?.startsWith( title ) ? count + 1 : count,
153
- 0
154
- );
155
-
156
- // Append a number to the end of the title if a menu with
157
- // the same name exists.
158
- const titleWithCount =
159
- matchingMenuTitleCount > 0
160
- ? `${ title } ${ matchingMenuTitleCount + 1 }`
161
- : title;
162
-
163
- const menu = await createNavigationMenu( titleWithCount );
112
+ const menu = await createNavigationMenu( null, blocks );
164
113
  onSave( menu );
165
114
  savingLock.current = false;
166
115
  }, [
@@ -172,7 +121,7 @@ export default function UnsavedInnerBlocks( {
172
121
  navigationMenus,
173
122
  hasSelection,
174
123
  createNavigationMenu,
175
- area,
124
+ blocks,
176
125
  ] );
177
126
 
178
127
  return (
@@ -0,0 +1,39 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { serialize } from '@wordpress/blocks';
5
+ import { store as coreStore } from '@wordpress/core-data';
6
+ import { useDispatch } from '@wordpress/data';
7
+ import { useCallback } from '@wordpress/element';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import useGenerateDefaultNavigationTitle from './use-generate-default-navigation-title';
13
+
14
+ export default function useCreateNavigationMenu( clientId ) {
15
+ const { saveEntityRecord } = useDispatch( coreStore );
16
+ const generateDefaultTitle = useGenerateDefaultNavigationTitle( clientId );
17
+
18
+ // This callback uses data from the two placeholder steps and only creates
19
+ // a new navigation menu when the user completes the final step.
20
+ return useCallback(
21
+ async ( title = null, blocks = [] ) => {
22
+ if ( ! title ) {
23
+ title = await generateDefaultTitle();
24
+ }
25
+ const record = {
26
+ title,
27
+ content: serialize( blocks ),
28
+ status: 'publish',
29
+ };
30
+
31
+ return await saveEntityRecord(
32
+ 'postType',
33
+ 'wp_navigation',
34
+ record
35
+ );
36
+ },
37
+ [ serialize, saveEntityRecord ]
38
+ );
39
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { Disabled } from '@wordpress/components';
5
+ import { store as coreStore } from '@wordpress/core-data';
6
+ import { useRegistry } from '@wordpress/data';
7
+ import { useContext, useCallback } from '@wordpress/element';
8
+ import { __, sprintf } from '@wordpress/i18n';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import useTemplatePartAreaLabel from '../use-template-part-area-label';
14
+
15
+ const DRAFT_MENU_PARAMS = [
16
+ 'postType',
17
+ 'wp_navigation',
18
+ { status: 'draft', per_page: -1 },
19
+ ];
20
+
21
+ const PUBLISHED_MENU_PARAMS = [
22
+ 'postType',
23
+ 'wp_navigation',
24
+ { per_page: -1, status: 'publish' },
25
+ ];
26
+
27
+ export default function useGenerateDefaultNavigationTitle( clientId ) {
28
+ // The block will be disabled in a block preview, use this as a way of
29
+ // avoiding the side-effects of this component for block previews.
30
+ const isDisabled = useContext( Disabled.Context );
31
+
32
+ // Because we can't conditionally call hooks, pass an undefined client id
33
+ // arg to bypass the expensive `useTemplateArea` code. The hook will return
34
+ // early.
35
+ const area = useTemplatePartAreaLabel( isDisabled ? undefined : clientId );
36
+
37
+ const registry = useRegistry();
38
+ return useCallback( async () => {
39
+ // Ensure other navigation menus have loaded so an
40
+ // accurate name can be created.
41
+ if ( isDisabled ) {
42
+ return '';
43
+ }
44
+ const { getEntityRecords } = registry.resolveSelect( coreStore );
45
+
46
+ const [ draftNavigationMenus, navigationMenus ] = await Promise.all( [
47
+ getEntityRecords( ...DRAFT_MENU_PARAMS ),
48
+ getEntityRecords( ...PUBLISHED_MENU_PARAMS ),
49
+ ] );
50
+
51
+ const title = area
52
+ ? sprintf(
53
+ // translators: %s: the name of a menu (e.g. Header navigation).
54
+ __( '%s navigation' ),
55
+ area
56
+ )
57
+ : // translators: 'navigation' as in website navigation.
58
+ __( 'Navigation' );
59
+
60
+ // Determine how many menus start with the automatic title.
61
+ const matchingMenuTitleCount = [
62
+ ...draftNavigationMenus,
63
+ ...navigationMenus,
64
+ ].reduce(
65
+ ( count, menu ) =>
66
+ menu?.title?.raw?.startsWith( title ) ? count + 1 : count,
67
+ 0
68
+ );
69
+
70
+ // Append a number to the end of the title if a menu with
71
+ // the same name exists.
72
+ const titleWithCount =
73
+ matchingMenuTitleCount > 0
74
+ ? `${ title } ${ matchingMenuTitleCount + 1 }`
75
+ : title;
76
+
77
+ return titleWithCount || '';
78
+ }, [ isDisabled, area ] );
79
+ }
@@ -2,20 +2,23 @@
2
2
  /**
3
3
  * Server-side rendering of the `core/navigation` block.
4
4
  *
5
- * @package gutenberg
5
+ * @package WordPress
6
6
  */
7
7
 
8
8
  /**
9
9
  * Build an array with CSS classes and inline styles defining the colors
10
10
  * which will be applied to the navigation markup in the front-end.
11
11
  *
12
- * @param array $attributes Navigation block attributes.
12
+ * @param array $attributes Navigation block attributes.
13
+ *
13
14
  * @return array Colors CSS classes and inline styles.
14
15
  */
15
16
  function block_core_navigation_build_css_colors( $attributes ) {
16
17
  $colors = array(
17
- 'css_classes' => array(),
18
- 'inline_styles' => '',
18
+ 'css_classes' => array(),
19
+ 'inline_styles' => '',
20
+ 'overlay_css_classes' => array(),
21
+ 'overlay_inline_styles' => '',
19
22
  );
20
23
 
21
24
  // Text color.
@@ -54,6 +57,42 @@ function block_core_navigation_build_css_colors( $attributes ) {
54
57
  $colors['inline_styles'] .= sprintf( 'background-color: %s;', $attributes['customBackgroundColor'] );
55
58
  }
56
59
 
60
+ // Overlay text color.
61
+ $has_named_overlay_text_color = array_key_exists( 'overlayTextColor', $attributes );
62
+ $has_custom_overlay_text_color = array_key_exists( 'customOverlayTextColor', $attributes );
63
+
64
+ // If has overlay text color.
65
+ if ( $has_custom_overlay_text_color || $has_named_overlay_text_color ) {
66
+ // Add has-text-color class.
67
+ $colors['overlay_css_classes'][] = 'has-text-color';
68
+ }
69
+
70
+ if ( $has_named_overlay_text_color ) {
71
+ // Add the overlay color class.
72
+ $colors['overlay_css_classes'][] = sprintf( 'has-%s-color', $attributes['overlayTextColor'] );
73
+ } elseif ( $has_custom_overlay_text_color ) {
74
+ // Add the custom overlay color inline style.
75
+ $colors['overlay_inline_styles'] .= sprintf( 'color: %s;', $attributes['customOverlayTextColor'] );
76
+ }
77
+
78
+ // Overlay background color.
79
+ $has_named_overlay_background_color = array_key_exists( 'overlayBackgroundColor', $attributes );
80
+ $has_custom_overlay_background_color = array_key_exists( 'customOverlayBackgroundColor', $attributes );
81
+
82
+ // If has overlay background color.
83
+ if ( $has_custom_overlay_background_color || $has_named_overlay_background_color ) {
84
+ // Add has-background class.
85
+ $colors['overlay_css_classes'][] = 'has-background';
86
+ }
87
+
88
+ if ( $has_named_overlay_background_color ) {
89
+ // Add the overlay background-color class.
90
+ $colors['overlay_css_classes'][] = sprintf( 'has-%s-background-color', $attributes['overlayBackgroundColor'] );
91
+ } elseif ( $has_custom_overlay_background_color ) {
92
+ // Add the custom overlay background-color inline style.
93
+ $colors['overlay_inline_styles'] .= sprintf( 'background-color: %s;', $attributes['customOverlayBackgroundColor'] );
94
+ }
95
+
57
96
  return $colors;
58
97
  }
59
98
 
@@ -61,7 +100,8 @@ function block_core_navigation_build_css_colors( $attributes ) {
61
100
  * Build an array with CSS classes and inline styles defining the font sizes
62
101
  * which will be applied to the navigation markup in the front-end.
63
102
  *
64
- * @param array $attributes Navigation block attributes.
103
+ * @param array $attributes Navigation block attributes.
104
+ *
65
105
  * @return array Font size CSS classes and inline styles.
66
106
  */
67
107
  function block_core_navigation_build_css_font_sizes( $attributes ) {
@@ -94,6 +134,100 @@ function block_core_navigation_render_submenu_icon() {
94
134
  return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
95
135
  }
96
136
 
137
+
138
+ /**
139
+ * Finds the first non-empty `wp_navigation` Post.
140
+ *
141
+ * @return WP_Post|null the first non-empty Navigation or null.
142
+ */
143
+ function block_core_navigation_get_first_non_empty_navigation() {
144
+ // Order and orderby args set to mirror those in `wp_get_nav_menus`
145
+ // see:
146
+ // - https://github.com/WordPress/wordpress-develop/blob/ba943e113d3b31b121f77a2d30aebe14b047c69d/src/wp-includes/nav-menu.php#L613-L619.
147
+ // - https://developer.wordpress.org/reference/classes/wp_query/#order-orderby-parameters.
148
+ $navigation_posts = get_posts(
149
+ array(
150
+ 'post_type' => 'wp_navigation',
151
+ 'order' => 'ASC',
152
+ 'orderby' => 'name',
153
+ 'posts_per_page' => 1, // only the first post.
154
+ 's' => '<!-- wp:', // look for block indicators to ensure we only include non-empty Navigations.
155
+ )
156
+ );
157
+ return count( $navigation_posts ) ? $navigation_posts[0] : null;
158
+
159
+ }
160
+
161
+ /**
162
+ * Filter out empty "null" blocks from the block list.
163
+ * 'parse_blocks' includes a null block with '\n\n' as the content when
164
+ * it encounters whitespace. This is not a bug but rather how the parser
165
+ * is designed.
166
+ *
167
+ * @param array $parsed_blocks the parsed blocks to be normalized.
168
+ * @return array the normalized parsed blocks.
169
+ */
170
+ function block_core_navigation_filter_out_empty_blocks( $parsed_blocks ) {
171
+ $filtered = array_filter(
172
+ $parsed_blocks,
173
+ function( $block ) {
174
+ return isset( $block['blockName'] );
175
+ }
176
+ );
177
+
178
+ // Reset keys.
179
+ return array_values( $filtered );
180
+ }
181
+
182
+ /**
183
+ * Retrieves the appropriate fallback to be used on the front of the
184
+ * site when there is no menu assigned to the Nav block.
185
+ *
186
+ * This aims to mirror how the fallback mechanic for wp_nav_menu works.
187
+ * See https://developer.wordpress.org/reference/functions/wp_nav_menu/#more-information.
188
+ *
189
+ * @return array the array of blocks to be used as a fallback.
190
+ */
191
+ function block_core_navigation_get_fallback_blocks() {
192
+ $page_list_fallback = array(
193
+ array(
194
+ 'blockName' => 'core/page-list',
195
+ 'attrs' => array(
196
+ '__unstableMaxPages' => 4,
197
+ ),
198
+ ),
199
+ );
200
+
201
+ $registry = WP_Block_Type_Registry::get_instance();
202
+
203
+ // If `core/page-list` is not registered then return empty blocks.
204
+ $fallback_blocks = $registry->is_registered( 'core/page-list' ) ? $page_list_fallback : array();
205
+
206
+ // Default to a list of Pages.
207
+
208
+ $navigation_post = block_core_navigation_get_first_non_empty_navigation();
209
+
210
+ // Prefer using the first non-empty Navigation as fallback if available.
211
+ if ( $navigation_post ) {
212
+ $maybe_fallback = block_core_navigation_filter_out_empty_blocks( parse_blocks( $navigation_post->post_content ) );
213
+
214
+ // Normalizing blocks may result in an empty array of blocks if they were all `null` blocks.
215
+ // In this case default to the (Page List) fallback.
216
+ $fallback_blocks = ! empty( $maybe_fallback ) ? $maybe_fallback : $fallback_blocks;
217
+ }
218
+
219
+ /**
220
+ * Filters the fallback experience for the Navigation block.
221
+ *
222
+ * Returning a falsey value will opt out of the fallback and cause the block not to render.
223
+ * To customise the blocks provided return an array of blocks - these should be valid
224
+ * children of the `core/navigation` block.
225
+ *
226
+ * @param array[] default fallback blocks provided by the default block mechanic.
227
+ */
228
+ return apply_filters( 'block_core_navigation_render_fallback', $fallback_blocks );
229
+ }
230
+
97
231
  /**
98
232
  * Renders the `core/navigation` block on server.
99
233
  *
@@ -104,6 +238,11 @@ function block_core_navigation_render_submenu_icon() {
104
238
  * @return string Returns the post content with the legacy widget added.
105
239
  */
106
240
  function render_block_core_navigation( $attributes, $content, $block ) {
241
+
242
+ // Flag used to indicate whether the rendered output is considered to be
243
+ // a fallback (i.e. the block has no menu associated with it).
244
+ $is_fallback = false;
245
+
107
246
  /**
108
247
  * Deprecated:
109
248
  * The rgbTextColor and rgbBackgroundColor attributes
@@ -145,17 +284,13 @@ function render_block_core_navigation( $attributes, $content, $block ) {
145
284
  $inner_blocks = new WP_Block_List( $parsed_blocks, $attributes );
146
285
  }
147
286
 
148
- if ( ! empty( $block->context['navigationArea'] ) ) {
149
- $area = $block->context['navigationArea'];
150
- $mapping = get_option( 'wp_navigation_areas', array() );
151
- if ( ! empty( $mapping[ $area ] ) ) {
152
- $attributes['navigationMenuId'] = $mapping[ $area ];
153
- }
287
+ // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
288
+ if ( array_key_exists( 'navigationMenuId', $attributes ) ) {
289
+ $attributes['ref'] = $attributes['navigationMenuId'];
154
290
  }
155
-
156
291
  // Load inner blocks from the navigation post.
157
- if ( array_key_exists( 'navigationMenuId', $attributes ) ) {
158
- $navigation_post = get_post( $attributes['navigationMenuId'] );
292
+ if ( array_key_exists( 'ref', $attributes ) ) {
293
+ $navigation_post = get_post( $attributes['ref'] );
159
294
  if ( ! isset( $navigation_post ) ) {
160
295
  return '';
161
296
  }
@@ -164,20 +299,26 @@ function render_block_core_navigation( $attributes, $content, $block ) {
164
299
 
165
300
  // 'parse_blocks' includes a null block with '\n\n' as the content when
166
301
  // it encounters whitespace. This code strips it.
167
- $compacted_blocks = array_filter(
168
- $parsed_blocks,
169
- function( $block ) {
170
- return isset( $block['blockName'] );
171
- }
172
- );
302
+ $compacted_blocks = block_core_navigation_filter_out_empty_blocks( $parsed_blocks );
173
303
 
174
304
  // TODO - this uses the full navigation block attributes for the
175
305
  // context which could be refined.
176
306
  $inner_blocks = new WP_Block_List( $compacted_blocks, $attributes );
177
307
  }
178
308
 
309
+ // If there are no inner blocks then fallback to rendering an appropriate fallback.
179
310
  if ( empty( $inner_blocks ) ) {
180
- return '';
311
+ $is_fallback = true; // indicate we are rendering the fallback.
312
+
313
+ $fallback_blocks = block_core_navigation_get_fallback_blocks();
314
+
315
+ // Fallback my have been filtered so do basic test for validity.
316
+ if ( empty( $fallback_blocks ) || ! is_array( $fallback_blocks ) ) {
317
+ return '';
318
+ }
319
+
320
+ $inner_blocks = new WP_Block_List( $fallback_blocks, $attributes );
321
+
181
322
  }
182
323
 
183
324
  // Restore legacy classnames for submenu positioning.
@@ -196,7 +337,8 @@ function render_block_core_navigation( $attributes, $content, $block ) {
196
337
  $colors['css_classes'],
197
338
  $font_sizes['css_classes'],
198
339
  $is_responsive_menu ? array( 'is-responsive' ) : array(),
199
- $layout_class ? array( $layout_class ) : array()
340
+ $layout_class ? array( $layout_class ) : array(),
341
+ $is_fallback ? array( 'is-fallback' ) : array()
200
342
  );
201
343
 
202
344
  $inner_blocks_html = '';
@@ -247,6 +389,7 @@ function render_block_core_navigation( $attributes, $content, $block ) {
247
389
  $responsive_container_classes = array(
248
390
  'wp-block-navigation__responsive-container',
249
391
  $is_hidden_by_default ? 'hidden-by-default' : '',
392
+ implode( ' ', $colors['overlay_css_classes'] ),
250
393
  );
251
394
  $open_button_classes = array(
252
395
  'wp-block-navigation__responsive-container-open',
@@ -255,7 +398,7 @@ function render_block_core_navigation( $attributes, $content, $block ) {
255
398
 
256
399
  $responsive_container_markup = sprintf(
257
400
  '<button aria-expanded="false" aria-haspopup="true" aria-label="%3$s" class="%6$s" data-micromodal-trigger="modal-%1$s"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg></button>
258
- <div class="%5$s" id="modal-%1$s">
401
+ <div class="%5$s" style="%7$s" id="modal-%1$s">
259
402
  <div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
260
403
  <div class="wp-block-navigation__responsive-dialog" role="dialog" aria-modal="true" aria-labelledby="modal-%1$s-title" >
261
404
  <button aria-label="%4$s" data-micromodal-close class="wp-block-navigation__responsive-container-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg></button>
@@ -270,7 +413,8 @@ function render_block_core_navigation( $attributes, $content, $block ) {
270
413
  __( 'Open menu' ), // Open button label.
271
414
  __( 'Close menu' ), // Close button label.
272
415
  implode( ' ', $responsive_container_classes ),
273
- implode( ' ', $open_button_classes )
416
+ implode( ' ', $open_button_classes ),
417
+ $colors['overlay_inline_styles']
274
418
  );
275
419
 
276
420
  return sprintf(
@@ -283,8 +427,8 @@ function render_block_core_navigation( $attributes, $content, $block ) {
283
427
  /**
284
428
  * Register the navigation block.
285
429
  *
286
- * @uses render_block_core_navigation()
287
430
  * @throws WP_Error An WP_Error exception parsing the block definition.
431
+ * @uses render_block_core_navigation()
288
432
  */
289
433
  function register_block_core_navigation() {
290
434
  register_block_type_from_metadata(
@@ -301,6 +445,7 @@ add_action( 'init', 'register_block_core_navigation' );
301
445
  * Filter that changes the parsed attribute values of navigation blocks contain typographic presets to contain the values directly.
302
446
  *
303
447
  * @param array $parsed_block The block being rendered.
448
+ *
304
449
  * @return array The block being rendered without typographic presets.
305
450
  */
306
451
  function block_core_navigation_typographic_presets_backcompatibility( $parsed_block ) {
@@ -324,6 +469,7 @@ function block_core_navigation_typographic_presets_backcompatibility( $parsed_bl
324
469
  }
325
470
  }
326
471
  }
472
+
327
473
  return $parsed_block;
328
474
  }
329
475
 
@@ -4,8 +4,8 @@
4
4
  import { InnerBlocks } from '@wordpress/block-editor';
5
5
 
6
6
  export default function save( { attributes } ) {
7
- if ( attributes.navigationMenuId ) {
8
- // Avoid rendering inner blocks when a navigationMenuId is defined.
7
+ if ( attributes.ref ) {
8
+ // Avoid rendering inner blocks when a ref is defined.
9
9
  // When this id is defined the inner blocks are loaded from the
10
10
  // `wp_navigation` entity rather than the hard-coded block html.
11
11
  return;
@@ -78,10 +78,11 @@
78
78
 
79
79
  // Submenu indicator.
80
80
  .wp-block-navigation__submenu-icon {
81
- align-self: center;
82
- height: inherit;
81
+ align-self: center; // This one affects nested submenu indicators.
83
82
  line-height: 0;
84
- margin-left: 6px;
83
+ display: inline-block;
84
+ vertical-align: middle;
85
+ font-size: inherit;
85
86
 
86
87
  // Affect the button as well.
87
88
  padding: 0;
@@ -89,9 +90,16 @@
89
90
  color: currentColor;
90
91
  border: none;
91
92
 
93
+ // Scale to font size.
94
+ margin-left: 0.25em;
95
+ width: 0.6em;
96
+ height: 0.6em;
97
+
92
98
  svg {
93
99
  display: inline-block;
94
100
  stroke: currentColor;
101
+ width: inherit;
102
+ height: inherit;
95
103
  }
96
104
  }
97
105
  }
@@ -219,6 +227,36 @@
219
227
  }
220
228
  }
221
229
 
230
+ // General submenu colors.
231
+ // These styles are stored here as opposed to in the separate submenu block,
232
+ // so that they can affect both submenus and page lists with submenu items both.
233
+ .wp-block-navigation-submenu {
234
+ position: relative;
235
+ display: flex;
236
+
237
+ .wp-block-navigation__submenu-icon svg {
238
+ stroke: currentColor;
239
+ }
240
+ }
241
+
242
+ button.wp-block-navigation-item__content {
243
+ background-color: transparent;
244
+ border: none;
245
+ color: currentColor;
246
+ font-size: inherit;
247
+ font-family: inherit;
248
+ line-height: inherit;
249
+
250
+ // Buttons default to center alignment. This becomes visible
251
+ // when a menu item label is long enough to wrap.
252
+ text-align: left;
253
+ }
254
+
255
+ .wp-block-navigation-submenu__toggle {
256
+ cursor: pointer;
257
+ }
258
+
259
+
222
260
  /**
223
261
  * Margins
224
262
  */
@@ -325,6 +363,13 @@
325
363
  }
326
364
  }
327
365
 
366
+ // Allow menu items to be spaced out by space-between when only navigation links are present.
367
+ .wp-block-navigation__container:only-child,
368
+ .wp-block-page-list:only-child {
369
+ flex-grow: 1;
370
+ }
371
+
372
+
328
373
  /**
329
374
  * Mobile menu.
330
375
  */
@@ -345,6 +390,13 @@
345
390
  align-items: var(--layout-align, initial);
346
391
  }
347
392
 
393
+ // If the responsive wrapper is present but overlay is not open,
394
+ // overlay styles shouldn't apply.
395
+ &:not(.is-menu-open.is-menu-open) {
396
+ color: inherit !important;
397
+ background-color: inherit !important;
398
+ }
399
+
348
400
  // Overlay menu.
349
401
  // Provide an opinionated default style for menu items inside.
350
402
  // Inherit as much as we can regarding colors, fonts, sizes,
@@ -432,9 +484,9 @@
432
484
 
433
485
  // Remove background colors for items inside the overlay menu.
434
486
  // Has to be !important to override global styles.
435
- // @todo: We should revisit this so that the overlay colors can be applied, instead of the background.
436
487
  .wp-block-navigation-item .wp-block-navigation__submenu-container,
437
- .wp-block-navigation-item {
488
+ .wp-block-navigation-item,
489
+ .wp-block-page-list {
438
490
  color: inherit !important;
439
491
  background: transparent !important;
440
492
  }