@wordpress/block-library 9.33.2-next.36001005c.0 → 9.34.0

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 (173) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/accordion/block.json +1 -1
  3. package/build/accordion/edit.js +11 -9
  4. package/build/accordion/edit.js.map +2 -2
  5. package/build/accordion-heading/block.json +1 -1
  6. package/build/accordion-item/block.json +2 -2
  7. package/build/accordion-panel/block.json +1 -1
  8. package/build/breadcrumbs/block.json +3 -4
  9. package/build/breadcrumbs/edit.js +43 -77
  10. package/build/breadcrumbs/edit.js.map +2 -2
  11. package/build/buttons/transforms.js +1 -0
  12. package/build/buttons/transforms.js.map +2 -2
  13. package/build/categories/edit.js +8 -4
  14. package/build/categories/edit.js.map +2 -2
  15. package/build/code/transforms.js +2 -0
  16. package/build/code/transforms.js.map +2 -2
  17. package/build/home-link/block.json +2 -1
  18. package/build/image/view.js +4 -1
  19. package/build/image/view.js.map +2 -2
  20. package/build/latest-comments/block.json +4 -3
  21. package/build/latest-comments/deprecated.js +56 -0
  22. package/build/latest-comments/deprecated.js.map +7 -0
  23. package/build/latest-comments/edit.js +16 -10
  24. package/build/latest-comments/edit.js.map +2 -2
  25. package/build/latest-comments/index.js +3 -1
  26. package/build/latest-comments/index.js.map +3 -3
  27. package/build/math/deprecated.js +54 -0
  28. package/build/math/deprecated.js.map +7 -0
  29. package/build/math/edit.js +1 -0
  30. package/build/math/edit.js.map +2 -2
  31. package/build/math/index.js +3 -1
  32. package/build/math/index.js.map +3 -3
  33. package/build/math/save.js +2 -3
  34. package/build/math/save.js.map +2 -2
  35. package/build/navigation/menu-items-to-blocks.js +8 -3
  36. package/build/navigation/menu-items-to-blocks.js.map +2 -2
  37. package/build/navigation/view.js +2 -2
  38. package/build/navigation/view.js.map +2 -2
  39. package/build/navigation-link/link-ui/page-creator.js +20 -0
  40. package/build/navigation-link/link-ui/page-creator.js.map +3 -3
  41. package/build/post-date/block.json +1 -1
  42. package/build/post-date/edit.js +11 -5
  43. package/build/post-date/edit.js.map +3 -3
  44. package/build/post-date/variations.js +4 -7
  45. package/build/post-date/variations.js.map +2 -2
  46. package/build/post-template/edit.js +13 -1
  47. package/build/post-template/edit.js.map +2 -2
  48. package/build/query/index.js +11 -1
  49. package/build/query/index.js.map +2 -2
  50. package/build/query/variations.js +16 -11
  51. package/build/query/variations.js.map +2 -2
  52. package/build/search/view.js +4 -4
  53. package/build/search/view.js.map +2 -2
  54. package/build/terms-query/edit/inspector-controls/index.js +1 -1
  55. package/build/terms-query/edit/inspector-controls/index.js.map +2 -2
  56. package/build/terms-query/edit/inspector-controls/inherit-control.js +2 -4
  57. package/build/terms-query/edit/inspector-controls/inherit-control.js.map +2 -2
  58. package/build/utils/get-transformed-attributes.js +1 -10
  59. package/build/utils/get-transformed-attributes.js.map +2 -2
  60. package/build-module/accordion/block.json +1 -1
  61. package/build-module/accordion/edit.js +11 -9
  62. package/build-module/accordion/edit.js.map +2 -2
  63. package/build-module/accordion-heading/block.json +1 -1
  64. package/build-module/accordion-item/block.json +2 -2
  65. package/build-module/accordion-panel/block.json +1 -1
  66. package/build-module/breadcrumbs/block.json +3 -4
  67. package/build-module/breadcrumbs/edit.js +44 -78
  68. package/build-module/breadcrumbs/edit.js.map +2 -2
  69. package/build-module/buttons/transforms.js +1 -0
  70. package/build-module/buttons/transforms.js.map +2 -2
  71. package/build-module/categories/edit.js +8 -4
  72. package/build-module/categories/edit.js.map +2 -2
  73. package/build-module/code/transforms.js +2 -0
  74. package/build-module/code/transforms.js.map +2 -2
  75. package/build-module/home-link/block.json +2 -1
  76. package/build-module/image/view.js +4 -1
  77. package/build-module/image/view.js.map +2 -2
  78. package/build-module/latest-comments/block.json +4 -3
  79. package/build-module/latest-comments/deprecated.js +36 -0
  80. package/build-module/latest-comments/deprecated.js.map +7 -0
  81. package/build-module/latest-comments/edit.js +17 -10
  82. package/build-module/latest-comments/edit.js.map +2 -2
  83. package/build-module/latest-comments/index.js +3 -1
  84. package/build-module/latest-comments/index.js.map +2 -2
  85. package/build-module/math/deprecated.js +34 -0
  86. package/build-module/math/deprecated.js.map +7 -0
  87. package/build-module/math/edit.js +1 -0
  88. package/build-module/math/edit.js.map +2 -2
  89. package/build-module/math/index.js +3 -1
  90. package/build-module/math/index.js.map +2 -2
  91. package/build-module/math/save.js +2 -3
  92. package/build-module/math/save.js.map +2 -2
  93. package/build-module/navigation/menu-items-to-blocks.js +8 -3
  94. package/build-module/navigation/menu-items-to-blocks.js.map +2 -2
  95. package/build-module/navigation/view.js +2 -2
  96. package/build-module/navigation/view.js.map +2 -2
  97. package/build-module/navigation-link/link-ui/page-creator.js +21 -1
  98. package/build-module/navigation-link/link-ui/page-creator.js.map +2 -2
  99. package/build-module/post-date/block.json +1 -1
  100. package/build-module/post-date/edit.js +11 -5
  101. package/build-module/post-date/edit.js.map +2 -2
  102. package/build-module/post-date/variations.js +4 -7
  103. package/build-module/post-date/variations.js.map +2 -2
  104. package/build-module/post-template/edit.js +13 -1
  105. package/build-module/post-template/edit.js.map +2 -2
  106. package/build-module/query/index.js +11 -1
  107. package/build-module/query/index.js.map +2 -2
  108. package/build-module/query/variations.js +16 -11
  109. package/build-module/query/variations.js.map +2 -2
  110. package/build-module/search/view.js +4 -4
  111. package/build-module/search/view.js.map +2 -2
  112. package/build-module/terms-query/edit/inspector-controls/index.js +1 -1
  113. package/build-module/terms-query/edit/inspector-controls/index.js.map +2 -2
  114. package/build-module/terms-query/edit/inspector-controls/inherit-control.js +2 -4
  115. package/build-module/terms-query/edit/inspector-controls/inherit-control.js.map +2 -2
  116. package/build-module/utils/get-transformed-attributes.js +1 -10
  117. package/build-module/utils/get-transformed-attributes.js.map +2 -2
  118. package/build-style/editor-rtl.css +5 -0
  119. package/build-style/editor.css +6 -0
  120. package/build-style/math/editor-rtl.css +49 -0
  121. package/build-style/math/editor.css +50 -0
  122. package/build-style/math/style-rtl.css +4 -0
  123. package/build-style/math/style.css +4 -0
  124. package/build-style/style-rtl.css +5 -0
  125. package/build-style/style.css +5 -0
  126. package/package.json +37 -37
  127. package/src/accordion/block.json +1 -1
  128. package/src/accordion/edit.js +16 -16
  129. package/src/accordion-heading/block.json +1 -1
  130. package/src/accordion-item/block.json +2 -2
  131. package/src/accordion-panel/block.json +1 -1
  132. package/src/breadcrumbs/block.json +3 -4
  133. package/src/breadcrumbs/edit.js +96 -132
  134. package/src/breadcrumbs/index.php +203 -50
  135. package/src/buttons/transforms.js +1 -0
  136. package/src/categories/edit.js +10 -6
  137. package/src/categories/index.php +1 -1
  138. package/src/code/transforms.js +2 -0
  139. package/src/editor.scss +1 -0
  140. package/src/home-link/block.json +2 -1
  141. package/src/image/index.php +9 -9
  142. package/src/image/view.js +11 -1
  143. package/src/latest-comments/block.json +4 -3
  144. package/src/latest-comments/deprecated.js +37 -0
  145. package/src/latest-comments/edit.js +17 -10
  146. package/src/latest-comments/index.js +2 -0
  147. package/src/latest-comments/index.php +11 -2
  148. package/src/math/deprecated.js +44 -0
  149. package/src/math/edit.js +1 -0
  150. package/src/math/editor.scss +7 -0
  151. package/src/math/index.js +2 -0
  152. package/src/math/save.js +6 -5
  153. package/src/math/style.scss +4 -0
  154. package/src/navigation/index.php +7 -7
  155. package/src/navigation/menu-items-to-blocks.js +12 -2
  156. package/src/navigation/test/menu-items-to-blocks.js +144 -0
  157. package/src/navigation/view.js +2 -2
  158. package/src/navigation-link/link-ui/page-creator.js +25 -2
  159. package/src/post-date/block.json +1 -1
  160. package/src/post-date/edit.js +15 -10
  161. package/src/post-date/variations.js +2 -5
  162. package/src/post-template/edit.js +13 -1
  163. package/src/query/index.js +10 -0
  164. package/src/query/variations.js +17 -11
  165. package/src/query-pagination-next/index.php +1 -1
  166. package/src/query-pagination-previous/index.php +1 -1
  167. package/src/search/index.php +2 -2
  168. package/src/search/view.js +4 -4
  169. package/src/style.scss +1 -0
  170. package/src/term-template/index.php +8 -2
  171. package/src/terms-query/edit/inspector-controls/index.js +2 -2
  172. package/src/terms-query/edit/inspector-controls/inherit-control.js +1 -3
  173. package/src/utils/get-transformed-attributes.js +5 -16
@@ -250,12 +250,12 @@ function block_core_image_render_lightbox( $block_content, $block ) {
250
250
  // Image.
251
251
  $processor->next_tag( 'img' );
252
252
  $processor->set_attribute( 'data-wp-init', 'callbacks.setButtonStyles' );
253
- $processor->set_attribute( 'data-wp-on-async--load', 'callbacks.setButtonStyles' );
254
- $processor->set_attribute( 'data-wp-on-async-window--resize', 'callbacks.setButtonStyles' );
253
+ $processor->set_attribute( 'data-wp-on--load', 'callbacks.setButtonStyles' );
254
+ $processor->set_attribute( 'data-wp-on-window--resize', 'callbacks.setButtonStyles' );
255
255
  // Sets an event callback on the `img` because the `figure` element can also
256
256
  // contain a caption, and we don't want to trigger the lightbox when the
257
257
  // caption is clicked.
258
- $processor->set_attribute( 'data-wp-on-async--click', 'actions.showLightbox' );
258
+ $processor->set_attribute( 'data-wp-on--click', 'actions.showLightbox' );
259
259
  $processor->set_attribute( 'data-wp-class--hide', 'state.isContentHidden' );
260
260
  $processor->set_attribute( 'data-wp-class--show', 'state.isContentVisible' );
261
261
 
@@ -273,7 +273,7 @@ function block_core_image_render_lightbox( $block_content, $block ) {
273
273
  aria-haspopup="dialog"
274
274
  aria-label="' . esc_attr( $aria_label ) . '"
275
275
  data-wp-init="callbacks.initTriggerButton"
276
- data-wp-on-async--click="actions.showLightbox"
276
+ data-wp-on--click="actions.showLightbox"
277
277
  data-wp-style--right="state.imageButtonRight"
278
278
  data-wp-style--top="state.imageButtonTop"
279
279
  >
@@ -324,12 +324,12 @@ function block_core_image_print_lightbox_overlay() {
324
324
  data-wp-class--show-closing-animation="state.overlayOpened"
325
325
  data-wp-watch="callbacks.setOverlayFocus"
326
326
  data-wp-on--keydown="actions.handleKeydown"
327
- data-wp-on-async--touchstart="actions.handleTouchStart"
327
+ data-wp-on--touchstart="actions.handleTouchStart"
328
328
  data-wp-on--touchmove="actions.handleTouchMove"
329
- data-wp-on-async--touchend="actions.handleTouchEnd"
330
- data-wp-on-async--click="actions.hideLightbox"
331
- data-wp-on-async-window--resize="callbacks.setOverlayStyles"
332
- data-wp-on-async-window--scroll="actions.handleScroll"
329
+ data-wp-on--touchend="actions.handleTouchEnd"
330
+ data-wp-on--click="actions.hideLightbox"
331
+ data-wp-on-window--resize="callbacks.setOverlayStyles"
332
+ data-wp-on-window--scroll="actions.handleScroll"
333
333
  data-wp-bind--style="state.overlayStyles"
334
334
  tabindex="-1"
335
335
  >
package/src/image/view.js CHANGED
@@ -356,9 +356,19 @@ const { state, actions, callbacks } = store(
356
356
  `;
357
357
  },
358
358
  setButtonStyles() {
359
- const { imageId } = getContext();
360
359
  const { ref } = getElement();
361
360
 
361
+ // This guard prevents errors in images with the `srcset`
362
+ // attribute, which can dispatch `load` events even after DOM
363
+ // removal. Preact doesn't automatically clean up `load` event
364
+ // listeners on unmounted `img` elements (see
365
+ // https://github.com/preactjs/preact/issues/3141).
366
+ if ( ! ref ) {
367
+ return;
368
+ }
369
+
370
+ const { imageId } = getContext();
371
+
362
372
  state.metadata[ imageId ].imageRef = ref;
363
373
  state.metadata[ imageId ].currentSrc = ref.currentSrc;
364
374
 
@@ -22,9 +22,10 @@
22
22
  "type": "boolean",
23
23
  "default": true
24
24
  },
25
- "displayExcerpt": {
26
- "type": "boolean",
27
- "default": true
25
+ "displayContent": {
26
+ "type": "string",
27
+ "default": "excerpt",
28
+ "enum": [ "none", "excerpt", "full" ]
28
29
  }
29
30
  },
30
31
  "supports": {
@@ -0,0 +1,37 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+
5
+ const v1 = {
6
+ attributes: {
7
+ commentsToShow: {
8
+ type: 'number',
9
+ default: 5,
10
+ minimum: 1,
11
+ maximum: 100,
12
+ },
13
+ displayAvatar: {
14
+ type: 'boolean',
15
+ default: true,
16
+ },
17
+ displayDate: {
18
+ type: 'boolean',
19
+ default: true,
20
+ },
21
+ displayExcerpt: {
22
+ type: 'boolean',
23
+ default: true,
24
+ },
25
+ },
26
+ isEligible( attributes ) {
27
+ return attributes?.displayExcerpt === false;
28
+ },
29
+ migrate( attributes ) {
30
+ return {
31
+ ...attributes,
32
+ displayContent: attributes.displayExcerpt ? 'excerpt' : 'none',
33
+ };
34
+ },
35
+ };
36
+
37
+ export default [ v1 ];
@@ -5,6 +5,7 @@ import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
5
5
  import {
6
6
  Disabled,
7
7
  RangeControl,
8
+ SelectControl,
8
9
  ToggleControl,
9
10
  __experimentalToolsPanel as ToolsPanel,
10
11
  __experimentalToolsPanelItem as ToolsPanelItem,
@@ -31,7 +32,7 @@ const MIN_COMMENTS = 1;
31
32
  const MAX_COMMENTS = 100;
32
33
 
33
34
  export default function LatestComments( { attributes, setAttributes } ) {
34
- const { commentsToShow, displayAvatar, displayDate, displayExcerpt } =
35
+ const { commentsToShow, displayAvatar, displayDate, displayContent } =
35
36
  attributes;
36
37
 
37
38
  const serverSideAttributes = {
@@ -54,7 +55,7 @@ export default function LatestComments( { attributes, setAttributes } ) {
54
55
  commentsToShow: 5,
55
56
  displayAvatar: true,
56
57
  displayDate: true,
57
- displayExcerpt: true,
58
+ displayContent: 'excerpt',
58
59
  } );
59
60
  } }
60
61
  dropdownMenuProps={ dropdownMenuProps }
@@ -98,20 +99,26 @@ export default function LatestComments( { attributes, setAttributes } ) {
98
99
  </ToolsPanelItem>
99
100
 
100
101
  <ToolsPanelItem
101
- hasValue={ () => ! displayExcerpt }
102
- label={ __( 'Display excerpt' ) }
102
+ hasValue={ () => displayContent !== 'excerpt' }
103
+ label={ __( 'Display content' ) }
103
104
  onDeselect={ () =>
104
- setAttributes( { displayExcerpt: true } )
105
+ setAttributes( { displayContent: 'excerpt' } )
105
106
  }
106
107
  isShownByDefault
107
108
  >
108
- <ToggleControl
109
+ <SelectControl
109
110
  __nextHasNoMarginBottom
110
- label={ __( 'Display excerpt' ) }
111
- checked={ displayExcerpt }
112
- onChange={ () =>
111
+ __next40pxDefaultSize
112
+ label={ __( 'Display content' ) }
113
+ value={ displayContent }
114
+ options={ [
115
+ { label: __( 'No content' ), value: 'none' },
116
+ { label: __( 'Excerpt' ), value: 'excerpt' },
117
+ { label: __( 'Full content' ), value: 'full' },
118
+ ] }
119
+ onChange={ ( value ) =>
113
120
  setAttributes( {
114
- displayExcerpt: ! displayExcerpt,
121
+ displayContent: value,
115
122
  } )
116
123
  }
117
124
  />
@@ -9,6 +9,7 @@ import { comment as icon } from '@wordpress/icons';
9
9
  import initBlock from '../utils/init-block';
10
10
  import metadata from './block.json';
11
11
  import edit from './edit';
12
+ import deprecated from './deprecated';
12
13
 
13
14
  const { name } = metadata;
14
15
 
@@ -18,6 +19,7 @@ export const settings = {
18
19
  icon,
19
20
  example: {},
20
21
  edit,
22
+ deprecated,
21
23
  };
22
24
 
23
25
  export const init = () => initBlock( { name, metadata, settings } );
@@ -43,6 +43,13 @@ function wp_latest_comments_draft_or_post_title( $post = 0 ) {
43
43
  * @return string Returns the post content with latest comments added.
44
44
  */
45
45
  function render_block_core_latest_comments( $attributes ) {
46
+ // Handle backward compatibility: check for old displayExcerpt attribute
47
+ if ( isset( $attributes['displayExcerpt'] ) ) {
48
+ $display_content = $attributes['displayExcerpt'] ? 'excerpt' : 'none';
49
+ } else {
50
+ $display_content = isset( $attributes['displayContent'] ) ? $attributes['displayContent'] : 'excerpt';
51
+ }
52
+
46
53
  $comments = get_comments(
47
54
  /** This filter is documented in wp-includes/widgets/class-wp-widget-recent-comments.php */
48
55
  apply_filters(
@@ -112,7 +119,9 @@ function render_block_core_latest_comments( $attributes ) {
112
119
  );
113
120
  }
114
121
  $list_items_markup .= '</footer>';
115
- if ( $attributes['displayExcerpt'] ) {
122
+ if ( 'full' === $display_content ) {
123
+ $list_items_markup .= '<div class="wp-block-latest-comments__comment-excerpt">' . wpautop( get_comment_text( $comment ) ) . '</div>';
124
+ } elseif ( 'excerpt' === $display_content ) {
116
125
  $list_items_markup .= '<div class="wp-block-latest-comments__comment-excerpt">' . wpautop( get_comment_excerpt( $comment ) ) . '</div>';
117
126
  }
118
127
  $list_items_markup .= '</article></li>';
@@ -126,7 +135,7 @@ function render_block_core_latest_comments( $attributes ) {
126
135
  if ( $attributes['displayDate'] ) {
127
136
  $classnames[] = 'has-dates';
128
137
  }
129
- if ( $attributes['displayExcerpt'] ) {
138
+ if ( 'none' !== $display_content ) {
130
139
  $classnames[] = 'has-excerpts';
131
140
  }
132
141
  if ( empty( $comments ) ) {
@@ -0,0 +1,44 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useBlockProps } from '@wordpress/block-editor';
5
+
6
+ // v1: Add a wrapper div around the math element.
7
+ const v1 = {
8
+ attributes: {
9
+ latex: {
10
+ type: 'string',
11
+ role: 'content',
12
+ },
13
+ mathML: {
14
+ type: 'string',
15
+ source: 'html',
16
+ selector: 'math',
17
+ },
18
+ },
19
+ save( { attributes } ) {
20
+ const { latex, mathML } = attributes;
21
+
22
+ if ( ! latex ) {
23
+ return null;
24
+ }
25
+
26
+ return (
27
+ <math
28
+ { ...useBlockProps.save() }
29
+ display="block"
30
+ dangerouslySetInnerHTML={ { __html: mathML } }
31
+ />
32
+ );
33
+ },
34
+ };
35
+
36
+ /**
37
+ * New deprecations need to be placed first
38
+ * for them to have higher priority.
39
+ *
40
+ * Old deprecations may need to be updated as well.
41
+ *
42
+ * See block-deprecation.md
43
+ */
44
+ export default [ v1 ];
package/src/math/edit.js CHANGED
@@ -82,6 +82,7 @@ export default function MathEdit( { attributes, setAttributes, isSelected } ) {
82
82
  label={ __( 'LaTeX math syntax' ) }
83
83
  hideLabelFromVision
84
84
  value={ latex }
85
+ className="wp-block-math__textarea-control"
85
86
  onChange={ ( newLatex ) => {
86
87
  if ( ! latexToMathML ) {
87
88
  setAttributes( { latex: newLatex } );
@@ -0,0 +1,7 @@
1
+ @use "@wordpress/base-styles/variables" as *;
2
+
3
+ .wp-block-math__textarea-control textarea {
4
+ font-family: $font-family-mono;
5
+ /*rtl:ignore*/
6
+ direction: ltr;
7
+ }
package/src/math/index.js CHANGED
@@ -10,6 +10,7 @@ import initBlock from '../utils/init-block';
10
10
  import edit from './edit';
11
11
  import metadata from './block.json';
12
12
  import save from './save';
13
+ import deprecated from './deprecated';
13
14
 
14
15
  const { name } = metadata;
15
16
 
@@ -26,6 +27,7 @@ export const settings = {
26
27
  },
27
28
  edit,
28
29
  save,
30
+ deprecated,
29
31
  };
30
32
 
31
33
  export const init = () => initBlock( { name, metadata, settings } );
package/src/math/save.js CHANGED
@@ -11,10 +11,11 @@ export default function save( { attributes } ) {
11
11
  }
12
12
 
13
13
  return (
14
- <math
15
- { ...useBlockProps.save() }
16
- display="block"
17
- dangerouslySetInnerHTML={ { __html: mathML } }
18
- />
14
+ <div { ...useBlockProps.save() }>
15
+ <math
16
+ display="block"
17
+ dangerouslySetInnerHTML={ { __html: mathML } }
18
+ />
19
+ </div>
19
20
  );
20
21
  }
@@ -0,0 +1,4 @@
1
+ .wp-block-math {
2
+ overflow-x: auto;
3
+ overflow-y: hidden;
4
+ }
@@ -497,7 +497,7 @@ class WP_Navigation_Block_Renderer {
497
497
  $close_button_directives = '';
498
498
  if ( $is_interactive ) {
499
499
  $open_button_directives = '
500
- data-wp-on-async--click="actions.openMenuOnClick"
500
+ data-wp-on--click="actions.openMenuOnClick"
501
501
  data-wp-on--keydown="actions.handleMenuKeydown"
502
502
  ';
503
503
  $responsive_container_directives = '
@@ -505,7 +505,7 @@ class WP_Navigation_Block_Renderer {
505
505
  data-wp-class--is-menu-open="state.isMenuOpen"
506
506
  data-wp-watch="callbacks.initMenu"
507
507
  data-wp-on--keydown="actions.handleMenuKeydown"
508
- data-wp-on-async--focusout="actions.handleMenuFocusout"
508
+ data-wp-on--focusout="actions.handleMenuFocusout"
509
509
  tabindex="-1"
510
510
  ';
511
511
  $responsive_dialog_directives = '
@@ -514,7 +514,7 @@ class WP_Navigation_Block_Renderer {
514
514
  data-wp-bind--role="state.roleAttribute"
515
515
  ';
516
516
  $close_button_directives = '
517
- data-wp-on-async--click="actions.closeMenuOnClick"
517
+ data-wp-on--click="actions.closeMenuOnClick"
518
518
  ';
519
519
  $responsive_container_content_directives = '
520
520
  data-wp-watch="callbacks.focusFirstElement"
@@ -830,8 +830,8 @@ function block_core_navigation_add_directives_to_submenu( $tags, $block_attribut
830
830
  $tags->set_attribute( 'tabindex', '-1' );
831
831
 
832
832
  if ( ! isset( $block_attributes['openSubmenusOnClick'] ) || false === $block_attributes['openSubmenusOnClick'] ) {
833
- $tags->set_attribute( 'data-wp-on-async--mouseenter', 'actions.openMenuOnHover' );
834
- $tags->set_attribute( 'data-wp-on-async--mouseleave', 'actions.closeMenuOnHover' );
833
+ $tags->set_attribute( 'data-wp-on--mouseenter', 'actions.openMenuOnHover' );
834
+ $tags->set_attribute( 'data-wp-on--mouseleave', 'actions.closeMenuOnHover' );
835
835
  }
836
836
 
837
837
  // Add directives to the toggle submenu button.
@@ -841,7 +841,7 @@ function block_core_navigation_add_directives_to_submenu( $tags, $block_attribut
841
841
  'class_name' => 'wp-block-navigation-submenu__toggle',
842
842
  )
843
843
  ) ) {
844
- $tags->set_attribute( 'data-wp-on-async--click', 'actions.toggleMenuOnClick' );
844
+ $tags->set_attribute( 'data-wp-on--click', 'actions.toggleMenuOnClick' );
845
845
  $tags->set_attribute( 'data-wp-bind--aria-expanded', 'state.isMenuOpen' );
846
846
  // The `aria-expanded` attribute for SSR is already added in the submenu block.
847
847
  }
@@ -852,7 +852,7 @@ function block_core_navigation_add_directives_to_submenu( $tags, $block_attribut
852
852
  'class_name' => 'wp-block-navigation__submenu-container',
853
853
  )
854
854
  ) ) {
855
- $tags->set_attribute( 'data-wp-on-async--focus', 'actions.openMenuOnFocus' );
855
+ $tags->set_attribute( 'data-wp-on--focus', 'actions.openMenuOnFocus' );
856
856
  }
857
857
 
858
858
  // Iterate through subitems if exist.
@@ -4,6 +4,11 @@
4
4
  import { createBlock, parse } from '@wordpress/blocks';
5
5
  import { applyFilters } from '@wordpress/hooks';
6
6
 
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { buildNavigationLinkEntityBinding } from '../navigation-link/shared/use-entity-binding';
11
+
7
12
  /**
8
13
  * Convert a flat menu item structure to a nested blocks structure.
9
14
  *
@@ -145,12 +150,14 @@ function menuItemToBlockAttributes(
145
150
  object = 'tag';
146
151
  }
147
152
 
153
+ const inferredKind = menuItemTypeField?.replace( '_', '-' ) || 'custom';
154
+
148
155
  return {
149
156
  label: menuItemTitleField?.rendered || '',
150
157
  ...( object?.length && {
151
158
  type: object,
152
159
  } ),
153
- kind: menuItemTypeField?.replace( '_', '-' ) || 'custom',
160
+ kind: inferredKind,
154
161
  url: url || '',
155
162
  ...( xfn?.length &&
156
163
  xfn.join( ' ' ).trim() && {
@@ -165,8 +172,11 @@ function menuItemToBlockAttributes(
165
172
  title: attr_title,
166
173
  } ),
167
174
  ...( object_id &&
168
- 'custom' !== object && {
175
+ ( inferredKind === 'post-type' || inferredKind === 'taxonomy' ) && {
169
176
  id: object_id,
177
+ metadata: {
178
+ bindings: buildNavigationLinkEntityBinding( inferredKind ),
179
+ },
170
180
  } ),
171
181
  /* eslint-enable camelcase */
172
182
  ...( description?.length && {
@@ -371,4 +371,148 @@ describe( 'converting menu items to blocks', () => {
371
371
  const { innerBlocks: actual } = menuItemsToBlocks( [] );
372
372
  expect( actual ).toEqual( [] );
373
373
  } );
374
+
375
+ it( 'adds entity bindings for non-custom menu items', () => {
376
+ const { innerBlocks: actual } = menuItemsToBlocks( [
377
+ {
378
+ id: 1,
379
+ title: {
380
+ raw: 'Page Item',
381
+ rendered: 'Page Item',
382
+ },
383
+ url: 'http://localhost:8889/page-item/',
384
+ attr_title: '',
385
+ description: '',
386
+ type: 'post_type',
387
+ type_label: 'Page',
388
+ object: 'page',
389
+ object_id: 123,
390
+ parent: 0,
391
+ menu_order: 1,
392
+ target: '',
393
+ classes: [ '' ],
394
+ xfn: [ '' ],
395
+ },
396
+ {
397
+ id: 2,
398
+ title: {
399
+ raw: 'Category Item',
400
+ rendered: 'Category Item',
401
+ },
402
+ url: 'http://localhost:8889/category/category-item/',
403
+ attr_title: '',
404
+ description: '',
405
+ type: 'taxonomy',
406
+ type_label: 'Category',
407
+ object: 'category',
408
+ object_id: 456,
409
+ parent: 0,
410
+ menu_order: 2,
411
+ target: '',
412
+ classes: [ '' ],
413
+ xfn: [ '' ],
414
+ },
415
+ {
416
+ id: 3,
417
+ title: {
418
+ raw: 'Custom Item',
419
+ rendered: 'Custom Item',
420
+ },
421
+ url: 'http://localhost:8889/custom-link/',
422
+ attr_title: '',
423
+ description: '',
424
+ type: 'custom',
425
+ type_label: 'Custom Link',
426
+ object: 'custom',
427
+ parent: 0,
428
+ menu_order: 3,
429
+ target: '',
430
+ classes: [ '' ],
431
+ xfn: [ '' ],
432
+ },
433
+ ] );
434
+
435
+ expect( actual ).toEqual( [
436
+ expect.objectContaining( {
437
+ name: 'core/navigation-link',
438
+ attributes: expect.objectContaining( {
439
+ label: 'Page Item',
440
+ id: 123,
441
+ metadata: {
442
+ bindings: {
443
+ url: {
444
+ source: 'core/post-data',
445
+ args: {
446
+ field: 'link',
447
+ },
448
+ },
449
+ },
450
+ },
451
+ } ),
452
+ innerBlocks: [],
453
+ } ),
454
+ expect.objectContaining( {
455
+ name: 'core/navigation-link',
456
+ attributes: expect.objectContaining( {
457
+ label: 'Category Item',
458
+ id: 456,
459
+ metadata: {
460
+ bindings: {
461
+ url: {
462
+ source: 'core/term-data',
463
+ args: {
464
+ field: 'link',
465
+ },
466
+ },
467
+ },
468
+ },
469
+ } ),
470
+ innerBlocks: [],
471
+ } ),
472
+ expect.objectContaining( {
473
+ name: 'core/navigation-link',
474
+ attributes: expect.objectContaining( {
475
+ label: 'Custom Item',
476
+ // Custom items should NOT have id, metadata, or bindings
477
+ } ),
478
+ innerBlocks: [],
479
+ } ),
480
+ ] );
481
+
482
+ // Verify custom item does NOT have bindings
483
+ expect( actual[ 2 ].attributes ).not.toHaveProperty( 'id' );
484
+ expect( actual[ 2 ].attributes ).not.toHaveProperty( 'metadata' );
485
+ } );
486
+
487
+ it( 'does not add bindings for invalid kinds even when object_id is present', () => {
488
+ const { innerBlocks: actual } = menuItemsToBlocks( [
489
+ {
490
+ id: 10,
491
+ title: {
492
+ raw: 'Invalid Kind Item',
493
+ rendered: 'Invalid Kind Item',
494
+ },
495
+ url: 'http://localhost:8889/invalid-kind-item/',
496
+ attr_title: '',
497
+ description: '',
498
+ type: 'invalid', // becomes inferred kind 'invalid'
499
+ type_label: 'Invalid',
500
+ object: 'page',
501
+ object_id: 999,
502
+ parent: 0,
503
+ menu_order: 1,
504
+ target: '',
505
+ classes: [ '' ],
506
+ xfn: [ '' ],
507
+ },
508
+ ] );
509
+
510
+ expect( actual ).toHaveLength( 1 );
511
+ expect( actual[ 0 ].name ).toBe( 'core/navigation-link' );
512
+ // Should not set id or metadata when kind is not supported
513
+ expect( actual[ 0 ].attributes ).not.toHaveProperty( 'id' );
514
+ expect( actual[ 0 ].attributes ).not.toHaveProperty( 'metadata' );
515
+ // Label should still be set correctly
516
+ expect( actual[ 0 ].attributes.label ).toBe( 'Invalid Kind Item' );
517
+ } );
374
518
  } );
@@ -144,7 +144,7 @@ const { state, actions } = store(
144
144
  }
145
145
  }
146
146
  } ),
147
- handleMenuFocusout( event ) {
147
+ handleMenuFocusout: withSyncEvent( ( event ) => {
148
148
  const { modal, type } = getContext();
149
149
  // If focus is outside modal, and in the document, close menu
150
150
  // event.target === The element losing focus
@@ -162,7 +162,7 @@ const { state, actions } = store(
162
162
  actions.closeMenu( 'click' );
163
163
  actions.closeMenu( 'focus' );
164
164
  }
165
- },
165
+ } ),
166
166
 
167
167
  openMenu( menuOpenedOn = 'click' ) {
168
168
  const { type } = getContext();
@@ -9,9 +9,10 @@ import {
9
9
  __experimentalVStack as VStack,
10
10
  __experimentalHStack as HStack,
11
11
  } from '@wordpress/components';
12
- import { __ } from '@wordpress/i18n';
12
+ import { __, sprintf } from '@wordpress/i18n';
13
13
  import { useSelect, useDispatch } from '@wordpress/data';
14
14
  import { store as coreStore } from '@wordpress/core-data';
15
+ import { store as noticesStore } from '@wordpress/notices';
15
16
  import { decodeEntities } from '@wordpress/html-entities';
16
17
  import { useState } from '@wordpress/element';
17
18
 
@@ -57,6 +58,8 @@ export function LinkUIPageCreator( {
57
58
  );
58
59
 
59
60
  const { saveEntityRecord } = useDispatch( coreStore );
61
+ const { createSuccessNotice, createErrorNotice } =
62
+ useDispatch( noticesStore );
60
63
 
61
64
  async function createPage( event ) {
62
65
  event.preventDefault();
@@ -85,10 +88,30 @@ export function LinkUIPageCreator( {
85
88
  kind: 'post-type',
86
89
  };
87
90
 
91
+ // Show success notice
92
+ createSuccessNotice(
93
+ sprintf(
94
+ // translators: %s: the name of the new page being created.
95
+ __( '%s page created successfully.' ),
96
+ decodeEntities( savedRecord.title.rendered )
97
+ ),
98
+ {
99
+ type: 'snackbar',
100
+ id: 'page-created-success',
101
+ }
102
+ );
103
+
88
104
  onPageCreated( pageLink );
89
105
  }
90
106
  } catch ( error ) {
91
- // Error handling is done via the data store selectors
107
+ // Show error notice
108
+ createErrorNotice(
109
+ __( 'Failed to create page. Please try again.' ),
110
+ {
111
+ type: 'snackbar',
112
+ id: 'page-created-error',
113
+ }
114
+ );
92
115
  }
93
116
  }
94
117
 
@@ -4,7 +4,7 @@
4
4
  "name": "core/post-date",
5
5
  "title": "Date",
6
6
  "category": "theme",
7
- "description": "Display the publish date for an entry such as a post or page.",
7
+ "description": "Display a custom date.",
8
8
  "textdomain": "default",
9
9
  "attributes": {
10
10
  "datetime": {