@wordpress/block-library 7.3.2 → 7.3.5

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 (129) hide show
  1. package/build/comment-template/hooks.js +11 -3
  2. package/build/comment-template/hooks.js.map +1 -1
  3. package/build/comments-pagination/edit.js +18 -1
  4. package/build/comments-pagination/edit.js.map +1 -1
  5. package/build/comments-query-loop/edit.js +2 -2
  6. package/build/comments-query-loop/edit.js.map +1 -1
  7. package/build/comments-title/edit.js +151 -0
  8. package/build/comments-title/edit.js.map +1 -0
  9. package/build/comments-title/index.js +101 -0
  10. package/build/comments-title/index.js.map +1 -0
  11. package/build/index.js +4 -2
  12. package/build/index.js.map +1 -1
  13. package/build/navigation/edit/index.js +17 -1
  14. package/build/navigation/edit/index.js.map +1 -1
  15. package/build/navigation/edit/inner-blocks.js +5 -7
  16. package/build/navigation/edit/inner-blocks.js.map +1 -1
  17. package/build/navigation/edit/navigation-menu-selector.js +7 -2
  18. package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
  19. package/build/navigation-link/edit.js +29 -30
  20. package/build/navigation-link/edit.js.map +1 -1
  21. package/build/navigation-submenu/edit.js +14 -14
  22. package/build/navigation-submenu/edit.js.map +1 -1
  23. package/build/post-comments/edit.js +141 -35
  24. package/build/post-comments/edit.js.map +1 -1
  25. package/build/post-comments/index.js +2 -1
  26. package/build/post-comments/index.js.map +1 -1
  27. package/build/post-comments-form/edit.js +22 -1
  28. package/build/post-comments-form/edit.js.map +1 -1
  29. package/build/post-comments-form/index.js +1 -0
  30. package/build/post-comments-form/index.js.map +1 -1
  31. package/build/post-content/edit.js +1 -1
  32. package/build/post-content/edit.js.map +1 -1
  33. package/build/post-excerpt/edit.js +1 -1
  34. package/build/post-excerpt/edit.js.map +1 -1
  35. package/build/query-no-results/edit.js +1 -1
  36. package/build/query-no-results/edit.js.map +1 -1
  37. package/build-module/comment-template/hooks.js +11 -3
  38. package/build-module/comment-template/hooks.js.map +1 -1
  39. package/build-module/comments-pagination/edit.js +19 -2
  40. package/build-module/comments-pagination/edit.js.map +1 -1
  41. package/build-module/comments-query-loop/edit.js +2 -2
  42. package/build-module/comments-query-loop/edit.js.map +1 -1
  43. package/build-module/comments-title/edit.js +135 -0
  44. package/build-module/comments-title/edit.js.map +1 -0
  45. package/build-module/comments-title/index.js +88 -0
  46. package/build-module/comments-title/index.js.map +1 -0
  47. package/build-module/index.js +3 -2
  48. package/build-module/index.js.map +1 -1
  49. package/build-module/navigation/edit/index.js +17 -1
  50. package/build-module/navigation/edit/index.js.map +1 -1
  51. package/build-module/navigation/edit/inner-blocks.js +5 -7
  52. package/build-module/navigation/edit/inner-blocks.js.map +1 -1
  53. package/build-module/navigation/edit/navigation-menu-selector.js +6 -2
  54. package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
  55. package/build-module/navigation-link/edit.js +29 -30
  56. package/build-module/navigation-link/edit.js.map +1 -1
  57. package/build-module/navigation-submenu/edit.js +14 -14
  58. package/build-module/navigation-submenu/edit.js.map +1 -1
  59. package/build-module/post-comments/edit.js +143 -38
  60. package/build-module/post-comments/edit.js.map +1 -1
  61. package/build-module/post-comments/index.js +2 -1
  62. package/build-module/post-comments/index.js.map +1 -1
  63. package/build-module/post-comments-form/edit.js +21 -1
  64. package/build-module/post-comments-form/edit.js.map +1 -1
  65. package/build-module/post-comments-form/index.js +1 -0
  66. package/build-module/post-comments-form/index.js.map +1 -1
  67. package/build-module/post-content/edit.js +1 -1
  68. package/build-module/post-content/edit.js.map +1 -1
  69. package/build-module/post-excerpt/edit.js +1 -1
  70. package/build-module/post-excerpt/edit.js.map +1 -1
  71. package/build-module/query-no-results/edit.js +1 -1
  72. package/build-module/query-no-results/edit.js.map +1 -1
  73. package/build-style/comment-content/style-rtl.css +81 -0
  74. package/build-style/comment-content/style.css +81 -0
  75. package/build-style/comments-title/editor-rtl.css +79 -0
  76. package/build-style/comments-title/editor.css +79 -0
  77. package/build-style/cover/style-rtl.css +1 -1
  78. package/build-style/cover/style.css +1 -1
  79. package/build-style/editor-rtl.css +12 -0
  80. package/build-style/editor.css +12 -0
  81. package/build-style/latest-posts/style-rtl.css +2 -0
  82. package/build-style/latest-posts/style.css +4 -0
  83. package/build-style/post-comments/editor-rtl.css +79 -0
  84. package/build-style/post-comments/editor.css +79 -0
  85. package/build-style/post-comments/style-rtl.css +6 -4
  86. package/build-style/post-comments/style.css +6 -4
  87. package/build-style/post-comments-form/editor-rtl.css +79 -0
  88. package/build-style/post-comments-form/editor.css +79 -0
  89. package/build-style/post-comments-form/style-rtl.css +9 -0
  90. package/build-style/post-comments-form/style.css +9 -0
  91. package/build-style/style-rtl.css +18 -5
  92. package/build-style/style.css +20 -5
  93. package/package.json +10 -10
  94. package/src/comment-author-name/index.php +7 -5
  95. package/src/comment-content/index.php +25 -3
  96. package/src/comment-content/style.scss +5 -0
  97. package/src/comment-edit-link/index.php +1 -4
  98. package/src/comment-reply-link/index.php +1 -4
  99. package/src/comment-template/hooks.js +13 -1
  100. package/src/comment-template/index.php +13 -4
  101. package/src/comments-pagination/edit.js +23 -0
  102. package/src/comments-query-loop/edit.js +2 -0
  103. package/src/comments-title/block.json +70 -0
  104. package/src/comments-title/edit.js +213 -0
  105. package/src/comments-title/editor.scss +4 -0
  106. package/src/comments-title/index.js +18 -0
  107. package/src/comments-title/index.php +75 -0
  108. package/src/cover/index.php +1 -1
  109. package/src/cover/style.scss +1 -1
  110. package/src/editor.scss +3 -0
  111. package/src/index.js +4 -1
  112. package/src/latest-posts/style.scss +4 -0
  113. package/src/navigation/edit/index.js +24 -0
  114. package/src/navigation/edit/inner-blocks.js +5 -7
  115. package/src/navigation/edit/navigation-menu-selector.js +15 -9
  116. package/src/navigation-link/edit.js +40 -43
  117. package/src/navigation-submenu/edit.js +13 -17
  118. package/src/post-comments/block.json +2 -1
  119. package/src/post-comments/edit.js +204 -44
  120. package/src/post-comments/editor.scss +3 -0
  121. package/src/post-comments/style.scss +6 -7
  122. package/src/post-comments-form/block.json +1 -0
  123. package/src/post-comments-form/edit.js +39 -2
  124. package/src/post-comments-form/editor.scss +3 -0
  125. package/src/post-comments-form/index.php +4 -1
  126. package/src/post-comments-form/style.scss +11 -0
  127. package/src/post-content/edit.js +15 -1
  128. package/src/post-excerpt/edit.js +14 -1
  129. package/src/query-no-results/edit.js +1 -1
@@ -0,0 +1,213 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import {
10
+ AlignmentControl,
11
+ BlockControls,
12
+ useBlockProps,
13
+ PlainText,
14
+ InspectorControls,
15
+ } from '@wordpress/block-editor';
16
+ import { __ } from '@wordpress/i18n';
17
+ import { useEntityProp } from '@wordpress/core-data';
18
+ import {
19
+ PanelBody,
20
+ ToggleControl,
21
+ __experimentalToggleGroupControl as ToggleGroupControl,
22
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
23
+ } from '@wordpress/components';
24
+ import { useState, useEffect } from '@wordpress/element';
25
+ import apiFetch from '@wordpress/api-fetch';
26
+ import { addQueryArgs } from '@wordpress/url';
27
+
28
+ /**
29
+ * Internal dependencies
30
+ */
31
+ import HeadingLevelDropdown from '../heading/heading-level-dropdown';
32
+
33
+ export default function Edit( {
34
+ attributes: {
35
+ textAlign,
36
+ singleCommentLabel,
37
+ multipleCommentsLabel,
38
+ showPostTitle,
39
+ showCommentsCount,
40
+ level,
41
+ },
42
+ setAttributes,
43
+ context: { postType, postId },
44
+ } ) {
45
+ const TagName = 'h' + level;
46
+ const [ commentsCount, setCommentsCount ] = useState();
47
+ const [ editingMode, setEditingMode ] = useState( 'plural' );
48
+ const [ rawTitle ] = useEntityProp( 'postType', postType, 'title', postId );
49
+ const isSiteEditor = typeof postId === 'undefined';
50
+ const blockProps = useBlockProps( {
51
+ className: classnames( {
52
+ [ `has-text-align-${ textAlign }` ]: textAlign,
53
+ } ),
54
+ } );
55
+
56
+ useEffect( () => {
57
+ if ( isSiteEditor ) {
58
+ setCommentsCount( 3 );
59
+ return;
60
+ }
61
+ const currentPostId = postId;
62
+ apiFetch( {
63
+ path: addQueryArgs( '/wp/v2/comments', {
64
+ post: postId,
65
+ _fields: 'id',
66
+ } ),
67
+ method: 'HEAD',
68
+ parse: false,
69
+ } )
70
+ .then( ( res ) => {
71
+ // Stale requests will have the `currentPostId` of an older closure.
72
+ if ( currentPostId === postId ) {
73
+ setCommentsCount(
74
+ parseInt( res.headers.get( 'X-WP-Total' ) )
75
+ );
76
+ }
77
+ } )
78
+ .catch( () => {
79
+ setCommentsCount( 0 );
80
+ } );
81
+ }, [ postId ] );
82
+
83
+ const blockControls = (
84
+ <BlockControls group="block">
85
+ <AlignmentControl
86
+ value={ textAlign }
87
+ onChange={ ( newAlign ) =>
88
+ setAttributes( { textAlign: newAlign } )
89
+ }
90
+ />
91
+ <HeadingLevelDropdown
92
+ selectedLevel={ level }
93
+ onChange={ ( newLevel ) =>
94
+ setAttributes( { level: newLevel } )
95
+ }
96
+ />
97
+ </BlockControls>
98
+ );
99
+
100
+ const inspectorControls = (
101
+ <InspectorControls>
102
+ <PanelBody title={ __( 'Settings' ) }>
103
+ { isSiteEditor && (
104
+ <ToggleGroupControl
105
+ label={ __( 'Editing mode' ) }
106
+ onChange={ setEditingMode }
107
+ value={ editingMode }
108
+ >
109
+ <ToggleGroupControlOption
110
+ label={ __( 'Singular' ) }
111
+ value="singular"
112
+ />
113
+ <ToggleGroupControlOption
114
+ label={ __( 'Plural' ) }
115
+ value="plural"
116
+ />
117
+ </ToggleGroupControl>
118
+ ) }
119
+ <ToggleControl
120
+ label={ __( 'Show post title' ) }
121
+ checked={ showPostTitle }
122
+ onChange={ ( value ) =>
123
+ setAttributes( { showPostTitle: value } )
124
+ }
125
+ />
126
+ <ToggleControl
127
+ label={ __( 'Show comments count' ) }
128
+ checked={ showCommentsCount }
129
+ onChange={ ( value ) =>
130
+ setAttributes( { showCommentsCount: value } )
131
+ }
132
+ />
133
+ </PanelBody>
134
+ </InspectorControls>
135
+ );
136
+
137
+ const postTitle = isSiteEditor ? __( '"Post Title"' ) : `"${ rawTitle }"`;
138
+
139
+ const singlePlaceholder = showPostTitle
140
+ ? __( 'One response to ' )
141
+ : __( 'One response' );
142
+
143
+ const singlePlaceholderNoCount = showPostTitle
144
+ ? __( 'Response to ' )
145
+ : __( 'Response' );
146
+
147
+ const multiplePlaceholder = showPostTitle
148
+ ? __( 'responses to ' )
149
+ : __( 'responses' );
150
+
151
+ const multiplePlaceholderNoCount = showPostTitle
152
+ ? __( 'Responses to ' )
153
+ : __( 'Responses' );
154
+
155
+ return (
156
+ <>
157
+ { blockControls }
158
+ { inspectorControls }
159
+ <TagName { ...blockProps }>
160
+ { editingMode === 'singular' || commentsCount === 1 ? (
161
+ <>
162
+ <PlainText
163
+ __experimentalVersion={ 2 }
164
+ tagName="span"
165
+ aria-label={
166
+ showCommentsCount
167
+ ? singlePlaceholder
168
+ : singlePlaceholderNoCount
169
+ }
170
+ placeholder={
171
+ showCommentsCount
172
+ ? singlePlaceholder
173
+ : singlePlaceholderNoCount
174
+ }
175
+ value={ singleCommentLabel }
176
+ onChange={ ( newLabel ) =>
177
+ setAttributes( {
178
+ singleCommentLabel: newLabel,
179
+ } )
180
+ }
181
+ />
182
+ { showPostTitle ? postTitle : null }
183
+ </>
184
+ ) : (
185
+ <>
186
+ { showCommentsCount ? commentsCount : null }
187
+ <PlainText
188
+ __experimentalVersion={ 2 }
189
+ tagName="span"
190
+ aria-label={
191
+ showCommentsCount
192
+ ? ` ${ multiplePlaceholder }`
193
+ : multiplePlaceholderNoCount
194
+ }
195
+ placeholder={
196
+ showCommentsCount
197
+ ? ` ${ multiplePlaceholder }`
198
+ : multiplePlaceholderNoCount
199
+ }
200
+ value={ multipleCommentsLabel }
201
+ onChange={ ( newLabel ) =>
202
+ setAttributes( {
203
+ multipleCommentsLabel: newLabel,
204
+ } )
205
+ }
206
+ />
207
+ { showPostTitle ? postTitle : null }
208
+ </>
209
+ ) }
210
+ </TagName>
211
+ </>
212
+ );
213
+ }
@@ -0,0 +1,4 @@
1
+
2
+ .wp-block-comments-title.has-background {
3
+ padding: inherit;
4
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { commentTitle as icon } from '@wordpress/icons';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import metadata from './block.json';
10
+ import edit from './edit';
11
+
12
+ const { name } = metadata;
13
+ export { metadata, name };
14
+
15
+ export const settings = {
16
+ icon,
17
+ edit,
18
+ };
@@ -0,0 +1,75 @@
1
+ <?php
2
+ /**
3
+ * Server-side rendering of the `core/comments-title` block.
4
+ *
5
+ * @package WordPress
6
+ */
7
+
8
+ /**
9
+ * Renders the `core/comments-title` block on the server.
10
+ *
11
+ * @param array $attributes Block attributes.
12
+ *
13
+ * @return string Return the post comments title.
14
+ */
15
+ function render_block_core_comments_title( $attributes ) {
16
+
17
+ $align_class_name = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}";
18
+ $show_post_title = ! empty( $attributes['showPostTitle'] ) && $attributes['showPostTitle'];
19
+ $show_comments_count = ! empty( $attributes['showCommentsCount'] ) && $attributes['showCommentsCount'];
20
+ $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) );
21
+ $post_title = $show_post_title ? sprintf( '"%1$s"', get_the_title() ) : null;
22
+ $comments_count = number_format_i18n( get_comments_number() );
23
+ $tag_name = 'h2';
24
+ if ( isset( $attributes['level'] ) ) {
25
+ $tag_name = 'h' . $attributes['level'];
26
+ }
27
+
28
+ if ( '0' === $comments_count ) {
29
+ return;
30
+ }
31
+
32
+ $single_default_comment_label = $show_post_title ? __( 'Response to' ) : __( 'Response' );
33
+ if ( $show_comments_count ) {
34
+ $single_default_comment_label = $show_post_title ? __( 'One response to' ) : __( 'One response' );
35
+ }
36
+ $single_comment_label = ! empty( $attributes['singleCommentLabel'] ) ? $attributes['singleCommentLabel'] : $single_default_comment_label;
37
+
38
+ $multiple_default_comment_label = $show_post_title ? __( 'Responses to' ) : __( 'Responses' );
39
+ if ( $show_comments_count ) {
40
+ $multiple_default_comment_label = $show_post_title ? __( 'responses to' ) : __( 'responses' );
41
+ }
42
+
43
+ $multiple_comment_label = ! empty( $attributes['multipleCommentsLabel'] ) ? $attributes['multipleCommentsLabel'] : $multiple_default_comment_label;
44
+
45
+ $comments_title = '%1$s %2$s %3$s';
46
+
47
+ $comments_title = sprintf(
48
+ $comments_title,
49
+ // If there is only one comment, only display the label.
50
+ '1' !== $comments_count && $show_comments_count ? $comments_count : null,
51
+ '1' === $comments_count ? $single_comment_label : $multiple_comment_label,
52
+ $post_title
53
+ );
54
+
55
+ return sprintf(
56
+ '<%1$s id="comments" %2$s>%3$s</%1$s>',
57
+ $tag_name,
58
+ $wrapper_attributes,
59
+ $comments_title
60
+ );
61
+ }
62
+
63
+ /**
64
+ * Registers the `core/comments-title` block on the server.
65
+ */
66
+ function register_block_core_comments_title() {
67
+ register_block_type_from_metadata(
68
+ __DIR__ . '/comments-title',
69
+ array(
70
+ 'render_callback' => 'render_block_core_comments_title',
71
+ )
72
+ );
73
+ }
74
+
75
+ add_action( 'init', 'register_block_core_comments_title' );
@@ -40,7 +40,7 @@ function render_block_core_cover( $attributes, $content ) {
40
40
  $object_position = '';
41
41
  if ( isset( $attributes['focalPoint'] ) ) {
42
42
  $object_position = round( $attributes['focalPoint']['x'] * 100 ) . '%' . ' ' .
43
- round( $attributes['focalPoint']['x'] * 100 ) . '%';
43
+ round( $attributes['focalPoint']['y'] * 100 ) . '%';
44
44
  }
45
45
 
46
46
  $image_template = '<img
@@ -18,7 +18,7 @@
18
18
  // Mobile Safari does not support fixed background attachment properly.
19
19
  // See also https://stackoverflow.com/questions/24154666/background-size-cover-not-working-on-ios
20
20
  // Chrome on Android does not appear to support the attachment at all: https://issuetracker.google.com/issues/36908439
21
- @supports (-webkit-overflow-scrolling: touch) {
21
+ @supports (-webkit-touch-callout: inherit) {
22
22
  background-attachment: scroll;
23
23
  }
24
24
 
package/src/editor.scss CHANGED
@@ -10,6 +10,7 @@
10
10
  @import "./comments-query-loop/editor.scss";
11
11
  @import "./comments-pagination/editor.scss";
12
12
  @import "./comments-pagination-numbers/editor.scss";
13
+ @import "./comments-title/editor.scss";
13
14
  @import "./cover/editor.scss";
14
15
  @import "./embed/editor.scss";
15
16
  @import "./file/editor.scss";
@@ -48,6 +49,8 @@
48
49
  @import "./query-pagination/editor.scss";
49
50
  @import "./query-pagination-numbers/editor.scss";
50
51
  @import "./post-featured-image/editor.scss";
52
+ @import "./post-comments/editor.scss";
53
+ @import "./post-comments-form/editor.scss";
51
54
 
52
55
  :root .editor-styles-wrapper {
53
56
  @include background-colors-deprecated();
package/src/index.js CHANGED
@@ -35,6 +35,7 @@ import * as commentsQueryLoop from './comments-query-loop';
35
35
  import * as commentsPagination from './comments-pagination';
36
36
  import * as commentsPaginationNext from './comments-pagination-next';
37
37
  import * as commentsPaginationNumbers from './comments-pagination-numbers';
38
+ import * as commentsTitle from './comments-title';
38
39
  import * as cover from './cover';
39
40
  import * as embed from './embed';
40
41
  import * as file from './file';
@@ -212,12 +213,15 @@ export const __experimentalGetCoreBlocks = () => [
212
213
  commentEditLink,
213
214
  commentReplyLink,
214
215
  commentTemplate,
216
+ commentsTitle,
215
217
  commentsQueryLoop,
216
218
  commentsPagination,
217
219
  commentsPaginationNext,
218
220
  commentsPaginationNumbers,
219
221
  commentsPaginationPrevious,
222
+
220
223
  postComments,
224
+ postCommentsForm,
221
225
  homeLink,
222
226
  logInOut,
223
227
  termDescription,
@@ -278,7 +282,6 @@ export const __experimentalRegisterExperimentalCoreBlocks = process.env
278
282
  navigationArea,
279
283
  postComment,
280
284
  postCommentsCount,
281
- postCommentsForm,
282
285
  postCommentsLink,
283
286
  ]
284
287
  : [] ),
@@ -63,10 +63,14 @@
63
63
  &.alignleft {
64
64
  /*rtl:ignore*/
65
65
  margin-right: 1em;
66
+ /*rtl:ignore*/
67
+ float: left;
66
68
  }
67
69
  &.alignright {
68
70
  /*rtl:ignore*/
69
71
  margin-left: 1em;
72
+ /*rtl:ignore*/
73
+ float: right;
70
74
  }
71
75
  &.aligncenter {
72
76
  margin-bottom: 1em;
@@ -523,6 +523,11 @@ function Navigation( {
523
523
  ref,
524
524
  ] );
525
525
 
526
+ const navigationSelectorRef = useRef();
527
+ const [
528
+ shouldFocusNavigationSelector,
529
+ setShouldFocusNavigationSelector,
530
+ ] = useState( false );
526
531
  const handleSelectNavigation = useCallback(
527
532
  ( navPostOrClassicMenu ) => {
528
533
  if ( ! navPostOrClassicMenu ) {
@@ -538,10 +543,28 @@ function Navigation( {
538
543
  } else {
539
544
  handleUpdateMenu( navPostOrClassicMenu.id );
540
545
  }
546
+ setShouldFocusNavigationSelector( true );
541
547
  },
542
548
  [ convert, handleUpdateMenu ]
543
549
  );
544
550
 
551
+ // Focus support after menu selection.
552
+ useEffect( () => {
553
+ if (
554
+ isDraftNavigationMenu ||
555
+ ! isEntityAvailable ||
556
+ ! shouldFocusNavigationSelector
557
+ ) {
558
+ return;
559
+ }
560
+ navigationSelectorRef?.current?.focus();
561
+ setShouldFocusNavigationSelector( false );
562
+ }, [
563
+ isDraftNavigationMenu,
564
+ isEntityAvailable,
565
+ shouldFocusNavigationSelector,
566
+ ] );
567
+
545
568
  const resetToEmptyBlock = useCallback( () => {
546
569
  registry.batch( () => {
547
570
  if ( navigationArea ) {
@@ -663,6 +686,7 @@ function Navigation( {
663
686
  { ! isDraftNavigationMenu && isEntityAvailable && (
664
687
  <ToolbarGroup className="wp-block-navigation__toolbar-menu-selector">
665
688
  <NavigationMenuSelector
689
+ ref={ navigationSelectorRef }
666
690
  currentMenuId={ ref }
667
691
  clientId={ clientId }
668
692
  onSelect={ handleSelectNavigation }
@@ -44,12 +44,12 @@ export default function NavigationInnerBlocks( {
44
44
  } ) {
45
45
  const {
46
46
  isImmediateParentOfSelectedBlock,
47
- selectedBlockHasDescendants,
47
+ selectedBlockHasChildren,
48
48
  isSelected,
49
49
  } = useSelect(
50
50
  ( select ) => {
51
51
  const {
52
- getClientIdsOfDescendants,
52
+ getBlockCount,
53
53
  hasSelectedInnerBlock,
54
54
  getSelectedBlockClientId,
55
55
  } = select( blockEditorStore );
@@ -60,9 +60,7 @@ export default function NavigationInnerBlocks( {
60
60
  clientId,
61
61
  false
62
62
  ),
63
- selectedBlockHasDescendants: !! getClientIdsOfDescendants( [
64
- selectedBlockId,
65
- ] )?.length,
63
+ selectedBlockHasChildren: !! getBlockCount( selectedBlockId ),
66
64
 
67
65
  // This prop is already available but computing it here ensures it's
68
66
  // fresh compared to isImmediateParentOfSelectedBlock.
@@ -93,7 +91,7 @@ export default function NavigationInnerBlocks( {
93
91
  // appender.
94
92
  const parentOrChildHasSelection =
95
93
  isSelected ||
96
- ( isImmediateParentOfSelectedBlock && ! selectedBlockHasDescendants );
94
+ ( isImmediateParentOfSelectedBlock && ! selectedBlockHasChildren );
97
95
 
98
96
  const placeholder = useMemo( () => <PlaceholderPreview />, [] );
99
97
 
@@ -127,7 +125,7 @@ export default function NavigationInnerBlocks( {
127
125
  renderAppender:
128
126
  isSelected ||
129
127
  ( isImmediateParentOfSelectedBlock &&
130
- ! selectedBlockHasDescendants ) ||
128
+ ! selectedBlockHasChildren ) ||
131
129
  // Show the appender while dragging to allow inserting element between item and the appender.
132
130
  parentOrChildHasSelection
133
131
  ? InnerBlocks.ButtonBlockAppender
@@ -10,7 +10,7 @@ import {
10
10
  import { __, sprintf } from '@wordpress/i18n';
11
11
  import { decodeEntities } from '@wordpress/html-entities';
12
12
  import { addQueryArgs } from '@wordpress/url';
13
- import { useCallback, useMemo } from '@wordpress/element';
13
+ import { forwardRef, useCallback, useMemo } from '@wordpress/element';
14
14
 
15
15
  /**
16
16
  * Internal dependencies
@@ -18,14 +18,17 @@ import { useCallback, useMemo } from '@wordpress/element';
18
18
  import useNavigationMenu from '../use-navigation-menu';
19
19
  import useNavigationEntities from '../use-navigation-entities';
20
20
 
21
- export default function NavigationMenuSelector( {
22
- currentMenuId,
23
- onSelect,
24
- onCreateNew,
25
- showManageActions = false,
26
- actionLabel,
27
- toggleProps = {},
28
- } ) {
21
+ function NavigationMenuSelector(
22
+ {
23
+ currentMenuId,
24
+ onSelect,
25
+ onCreateNew,
26
+ showManageActions = false,
27
+ actionLabel,
28
+ toggleProps = {},
29
+ },
30
+ forwardedRef
31
+ ) {
29
32
  /* translators: %s: The name of a menu. */
30
33
  const createActionLabel = __( "Create from '%s'" );
31
34
 
@@ -92,6 +95,7 @@ export default function NavigationMenuSelector( {
92
95
 
93
96
  return (
94
97
  <ToolbarDropdownMenu
98
+ ref={ forwardedRef }
95
99
  label={ __( 'Select Menu' ) }
96
100
  text={ __( 'Select Menu' ) }
97
101
  icon={ null }
@@ -152,3 +156,5 @@ export default function NavigationMenuSelector( {
152
156
  </ToolbarDropdownMenu>
153
157
  );
154
158
  }
159
+
160
+ export default forwardRef( NavigationMenuSelector );
@@ -342,7 +342,35 @@ function navStripHTML( html ) {
342
342
  * Add transforms to Link Control
343
343
  */
344
344
 
345
- function LinkControlTransforms( { block, transforms, replace } ) {
345
+ function LinkControlTransforms( { clientId, replace } ) {
346
+ const { getBlock, blockTransforms } = useSelect(
347
+ ( select ) => {
348
+ const {
349
+ getBlock: _getBlock,
350
+ getBlockRootClientId,
351
+ getBlockTransformItems,
352
+ } = select( blockEditorStore );
353
+
354
+ return {
355
+ getBlock: _getBlock,
356
+ blockTransforms: getBlockTransformItems(
357
+ [ _getBlock( clientId ) ],
358
+ getBlockRootClientId( clientId )
359
+ ),
360
+ };
361
+ },
362
+ [ clientId ]
363
+ );
364
+
365
+ const featuredBlocks = [
366
+ 'core/site-logo',
367
+ 'core/social-links',
368
+ 'core/search',
369
+ ];
370
+ const transforms = blockTransforms.filter( ( item ) => {
371
+ return featuredBlocks.includes( item.name );
372
+ } );
373
+
346
374
  if ( ! transforms?.length ) {
347
375
  return null;
348
376
  }
@@ -359,8 +387,11 @@ function LinkControlTransforms( { block, transforms, replace } ) {
359
387
  key={ `transform-${ index }` }
360
388
  onClick={ () =>
361
389
  replace(
362
- block.clientId,
363
- switchToBlockType( block, item.name )
390
+ clientId,
391
+ switchToBlockType(
392
+ getBlock( clientId ),
393
+ item.name
394
+ )
364
395
  )
365
396
  }
366
397
  className="link-control-transform__item"
@@ -421,30 +452,20 @@ export default function NavigationLinkEdit( {
421
452
  isAtMaxNesting,
422
453
  isTopLevelLink,
423
454
  isParentOfSelectedBlock,
424
- hasDescendants,
455
+ hasChildren,
425
456
  userCanCreatePages,
426
457
  userCanCreatePosts,
427
- thisBlock,
428
- blockTransforms,
429
458
  } = useSelect(
430
459
  ( select ) => {
431
460
  const {
432
- getBlock,
433
461
  getBlocks,
462
+ getBlockCount,
434
463
  getBlockName,
435
464
  getBlockRootClientId,
436
- getClientIdsOfDescendants,
437
465
  hasSelectedInnerBlock,
438
- getSelectedBlockClientId,
439
466
  getBlockParentsByBlockName,
440
- getBlockTransformItems,
441
467
  } = select( blockEditorStore );
442
468
 
443
- const selectedBlockId = getSelectedBlockClientId();
444
-
445
- const descendants = getClientIdsOfDescendants( [ clientId ] )
446
- .length;
447
-
448
469
  return {
449
470
  innerBlocks: getBlocks( clientId ),
450
471
  isAtMaxNesting:
@@ -459,14 +480,7 @@ export default function NavigationLinkEdit( {
459
480
  clientId,
460
481
  true
461
482
  ),
462
- isImmediateParentOfSelectedBlock: hasSelectedInnerBlock(
463
- clientId,
464
- false
465
- ),
466
- hasDescendants: !! descendants,
467
- selectedBlockHasDescendants: !! getClientIdsOfDescendants( [
468
- selectedBlockId,
469
- ] )?.length,
483
+ hasChildren: !! getBlockCount( clientId ),
470
484
  userCanCreatePages: select( coreStore ).canUser(
471
485
  'create',
472
486
  'pages'
@@ -475,11 +489,6 @@ export default function NavigationLinkEdit( {
475
489
  'create',
476
490
  'posts'
477
491
  ),
478
- thisBlock: getBlock( clientId ),
479
- blockTransforms: getBlockTransformItems(
480
- [ getBlock( clientId ) ],
481
- getBlockRootClientId( clientId )
482
- ),
483
492
  };
484
493
  },
485
494
  [ clientId ]
@@ -506,15 +515,6 @@ export default function NavigationLinkEdit( {
506
515
  replaceBlock( clientId, newSubmenu );
507
516
  }
508
517
 
509
- const featuredBlocks = [
510
- 'core/site-logo',
511
- 'core/social-links',
512
- 'core/search',
513
- ];
514
- const featuredTransforms = blockTransforms.filter( ( item ) => {
515
- return featuredBlocks.includes( item.name );
516
- } );
517
-
518
518
  useEffect( () => {
519
519
  // Show the LinkControl on mount if the URL is empty
520
520
  // ( When adding a new menu item)
@@ -524,7 +524,7 @@ export default function NavigationLinkEdit( {
524
524
  setIsLinkOpen( true );
525
525
  }
526
526
  // If block has inner blocks, transform to Submenu.
527
- if ( hasDescendants ) {
527
+ if ( hasChildren ) {
528
528
  transformToSubmenu();
529
529
  }
530
530
  }, [] );
@@ -634,7 +634,7 @@ export default function NavigationLinkEdit( {
634
634
  'is-editing': isSelected || isParentOfSelectedBlock,
635
635
  'is-dragging-within': isDraggingWithin,
636
636
  'has-link': !! url,
637
- 'has-child': hasDescendants,
637
+ 'has-child': hasChildren,
638
638
  'has-text-color': !! textColor || !! customTextColor,
639
639
  [ getColorClassName( 'color', textColor ) ]: !! textColor,
640
640
  'has-background': !! backgroundColor || customBackgroundColor,
@@ -860,10 +860,7 @@ export default function NavigationLinkEdit( {
860
860
  ! url
861
861
  ? () => (
862
862
  <LinkControlTransforms
863
- block={ thisBlock }
864
- transforms={
865
- featuredTransforms
866
- }
863
+ clientId={ clientId }
867
864
  replace={ replaceBlock }
868
865
  />
869
866
  )