@wordpress/block-library 9.40.2-next.v.202602241322.0 → 9.40.2

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 (226) hide show
  1. package/build/comment-reply-link/edit.cjs +2 -1
  2. package/build/comment-reply-link/edit.cjs.map +2 -2
  3. package/build/comments/edit/placeholder.cjs +2 -1
  4. package/build/comments/edit/placeholder.cjs.map +2 -2
  5. package/build/cover/edit/index.cjs +39 -26
  6. package/build/cover/edit/index.cjs.map +2 -2
  7. package/build/cover/embed-video-utils.cjs +8 -6
  8. package/build/cover/embed-video-utils.cjs.map +2 -2
  9. package/build/embed/embed-preview.cjs +2 -1
  10. package/build/embed/embed-preview.cjs.map +2 -2
  11. package/build/html/block.json +2 -1
  12. package/build/html/modal.cjs +147 -230
  13. package/build/html/modal.cjs.map +3 -3
  14. package/build/icon/block.json +3 -12
  15. package/build/image/image.cjs +1 -1
  16. package/build/image/image.cjs.map +2 -2
  17. package/build/latest-comments/deprecated.cjs +33 -0
  18. package/build/latest-comments/deprecated.cjs.map +2 -2
  19. package/build/navigation/edit/index.cjs +123 -119
  20. package/build/navigation/edit/index.cjs.map +3 -3
  21. package/build/navigation/edit/navigation-menu-selector.cjs +2 -1
  22. package/build/navigation/edit/navigation-menu-selector.cjs.map +2 -2
  23. package/build/navigation/view.cjs +9 -2
  24. package/build/navigation/view.cjs.map +2 -2
  25. package/build/navigation-link/edit.cjs +2 -1
  26. package/build/navigation-link/edit.cjs.map +2 -2
  27. package/build/navigation-link/shared/controls.cjs +29 -52
  28. package/build/navigation-link/shared/controls.cjs.map +3 -3
  29. package/build/navigation-link/shared/use-handle-link-change.cjs +19 -3
  30. package/build/navigation-link/shared/use-handle-link-change.cjs.map +3 -3
  31. package/build/navigation-link/shared/use-link-preview.cjs +8 -9
  32. package/build/navigation-link/shared/use-link-preview.cjs.map +2 -2
  33. package/build/navigation-submenu/edit.cjs +8 -22
  34. package/build/navigation-submenu/edit.cjs.map +2 -2
  35. package/build/nextpage/block.json +0 -1
  36. package/build/page-list-item/edit.cjs +6 -3
  37. package/build/page-list-item/edit.cjs.map +2 -2
  38. package/build/paragraph/edit.cjs +1 -1
  39. package/build/paragraph/edit.cjs.map +1 -1
  40. package/build/post-navigation-link/block.json +3 -1
  41. package/build/post-navigation-link/edit.cjs +36 -2
  42. package/build/post-navigation-link/edit.cjs.map +3 -3
  43. package/build/post-navigation-link/index.cjs +0 -2
  44. package/build/post-navigation-link/index.cjs.map +3 -3
  45. package/build/post-title/block.json +3 -1
  46. package/build/post-title/deprecated.cjs +1 -82
  47. package/build/post-title/deprecated.cjs.map +3 -3
  48. package/build/post-title/edit.cjs +36 -10
  49. package/build/post-title/edit.cjs.map +3 -3
  50. package/build/query-title/block.json +3 -1
  51. package/build/query-title/deprecated.cjs +1 -70
  52. package/build/query-title/deprecated.cjs.map +3 -3
  53. package/build/query-title/edit.cjs +35 -17
  54. package/build/query-title/edit.cjs.map +3 -3
  55. package/build/shortcode/block.json +2 -1
  56. package/build/site-tagline/block.json +4 -6
  57. package/build/site-tagline/deprecated.cjs +1 -66
  58. package/build/site-tagline/deprecated.cjs.map +3 -3
  59. package/build/site-tagline/edit.cjs +28 -14
  60. package/build/site-tagline/edit.cjs.map +3 -3
  61. package/build/site-title/block.json +3 -1
  62. package/build/site-title/deprecated.cjs +1 -79
  63. package/build/site-title/deprecated.cjs.map +3 -3
  64. package/build/site-title/edit.cjs +30 -14
  65. package/build/site-title/edit.cjs.map +3 -3
  66. package/build/tabs-menu-item/block.json +26 -1
  67. package/build/tabs-menu-item/controls.cjs +100 -2
  68. package/build/tabs-menu-item/controls.cjs.map +3 -3
  69. package/build/tabs-menu-item/edit.cjs +65 -6
  70. package/build/tabs-menu-item/edit.cjs.map +2 -2
  71. package/build/tabs-menu-item/save.cjs +15 -1
  72. package/build/tabs-menu-item/save.cjs.map +2 -2
  73. package/build-module/comment-reply-link/edit.mjs +3 -2
  74. package/build-module/comment-reply-link/edit.mjs.map +2 -2
  75. package/build-module/comments/edit/placeholder.mjs +3 -2
  76. package/build-module/comments/edit/placeholder.mjs.map +2 -2
  77. package/build-module/cover/edit/index.mjs +47 -29
  78. package/build-module/cover/edit/index.mjs.map +2 -2
  79. package/build-module/cover/embed-video-utils.mjs +7 -5
  80. package/build-module/cover/embed-video-utils.mjs.map +2 -2
  81. package/build-module/embed/embed-preview.mjs +2 -1
  82. package/build-module/embed/embed-preview.mjs.map +2 -2
  83. package/build-module/html/block.json +2 -1
  84. package/build-module/html/modal.mjs +149 -232
  85. package/build-module/html/modal.mjs.map +2 -2
  86. package/build-module/icon/block.json +3 -12
  87. package/build-module/image/image.mjs +1 -1
  88. package/build-module/image/image.mjs.map +2 -2
  89. package/build-module/latest-comments/deprecated.mjs +33 -0
  90. package/build-module/latest-comments/deprecated.mjs.map +2 -2
  91. package/build-module/navigation/edit/index.mjs +123 -119
  92. package/build-module/navigation/edit/index.mjs.map +2 -2
  93. package/build-module/navigation/edit/navigation-menu-selector.mjs +2 -1
  94. package/build-module/navigation/edit/navigation-menu-selector.mjs.map +2 -2
  95. package/build-module/navigation/view.mjs +9 -2
  96. package/build-module/navigation/view.mjs.map +2 -2
  97. package/build-module/navigation-link/edit.mjs +2 -1
  98. package/build-module/navigation-link/edit.mjs.map +2 -2
  99. package/build-module/navigation-link/shared/controls.mjs +29 -53
  100. package/build-module/navigation-link/shared/controls.mjs.map +2 -2
  101. package/build-module/navigation-link/shared/use-handle-link-change.mjs +19 -3
  102. package/build-module/navigation-link/shared/use-handle-link-change.mjs.map +2 -2
  103. package/build-module/navigation-link/shared/use-link-preview.mjs +8 -9
  104. package/build-module/navigation-link/shared/use-link-preview.mjs.map +2 -2
  105. package/build-module/navigation-submenu/edit.mjs +9 -23
  106. package/build-module/navigation-submenu/edit.mjs.map +2 -2
  107. package/build-module/nextpage/block.json +0 -1
  108. package/build-module/page-list-item/edit.mjs +6 -3
  109. package/build-module/page-list-item/edit.mjs.map +2 -2
  110. package/build-module/paragraph/edit.mjs +2 -2
  111. package/build-module/paragraph/edit.mjs.map +1 -1
  112. package/build-module/post-navigation-link/block.json +3 -1
  113. package/build-module/post-navigation-link/edit.mjs +30 -3
  114. package/build-module/post-navigation-link/edit.mjs.map +2 -2
  115. package/build-module/post-navigation-link/index.mjs +0 -2
  116. package/build-module/post-navigation-link/index.mjs.map +2 -2
  117. package/build-module/post-title/block.json +3 -1
  118. package/build-module/post-title/deprecated.mjs +1 -82
  119. package/build-module/post-title/deprecated.mjs.map +2 -2
  120. package/build-module/post-title/edit.mjs +27 -10
  121. package/build-module/post-title/edit.mjs.map +2 -2
  122. package/build-module/query-title/block.json +3 -1
  123. package/build-module/query-title/deprecated.mjs +1 -70
  124. package/build-module/query-title/deprecated.mjs.map +2 -2
  125. package/build-module/query-title/edit.mjs +36 -17
  126. package/build-module/query-title/edit.mjs.map +2 -2
  127. package/build-module/shortcode/block.json +2 -1
  128. package/build-module/site-tagline/block.json +4 -6
  129. package/build-module/site-tagline/deprecated.mjs +1 -66
  130. package/build-module/site-tagline/deprecated.mjs.map +2 -2
  131. package/build-module/site-tagline/edit.mjs +29 -14
  132. package/build-module/site-tagline/edit.mjs.map +2 -2
  133. package/build-module/site-title/block.json +3 -1
  134. package/build-module/site-title/deprecated.mjs +1 -79
  135. package/build-module/site-title/deprecated.mjs.map +2 -2
  136. package/build-module/site-title/edit.mjs +31 -14
  137. package/build-module/site-title/edit.mjs.map +2 -2
  138. package/build-module/tabs-menu-item/block.json +26 -1
  139. package/build-module/tabs-menu-item/controls.mjs +104 -3
  140. package/build-module/tabs-menu-item/controls.mjs.map +2 -2
  141. package/build-module/tabs-menu-item/edit.mjs +66 -6
  142. package/build-module/tabs-menu-item/edit.mjs.map +2 -2
  143. package/build-module/tabs-menu-item/save.mjs +15 -1
  144. package/build-module/tabs-menu-item/save.mjs.map +2 -2
  145. package/build-style/editor-rtl.css +30 -6
  146. package/build-style/editor.css +30 -6
  147. package/build-style/html/editor-rtl.css +10 -6
  148. package/build-style/html/editor.css +10 -6
  149. package/build-style/icon/editor-rtl.css +5 -0
  150. package/build-style/icon/editor.css +5 -0
  151. package/build-style/navigation/style-rtl.css +15 -1
  152. package/build-style/navigation/style.css +15 -1
  153. package/build-style/navigation-link/editor-rtl.css +10 -0
  154. package/build-style/navigation-link/editor.css +10 -0
  155. package/build-style/navigation-overlay-close/style-rtl.css +3 -3
  156. package/build-style/navigation-overlay-close/style.css +3 -3
  157. package/build-style/style-rtl.css +30 -7
  158. package/build-style/style.css +30 -7
  159. package/build-style/tabs-menu-item/editor-rtl.css +5 -0
  160. package/build-style/tabs-menu-item/editor.css +5 -0
  161. package/build-style/tabs-menu-item/style-rtl.css +12 -3
  162. package/build-style/tabs-menu-item/style.css +12 -3
  163. package/package.json +38 -38
  164. package/src/accordion-item/index.php +17 -5
  165. package/src/comment-reply-link/edit.js +5 -2
  166. package/src/comments/edit/placeholder.js +5 -2
  167. package/src/cover/edit/index.js +72 -35
  168. package/src/cover/embed-video-utils.js +9 -7
  169. package/src/cover/index.php +8 -0
  170. package/src/details/index.php +47 -0
  171. package/src/embed/embed-preview.js +6 -5
  172. package/src/html/block.json +2 -1
  173. package/src/html/editor.scss +15 -5
  174. package/src/html/modal.js +32 -99
  175. package/src/icon/block.json +3 -12
  176. package/src/icon/editor.scss +5 -0
  177. package/src/icon/index.php +3 -1
  178. package/src/image/image.js +14 -15
  179. package/src/image/index.php +7 -5
  180. package/src/latest-comments/deprecated.js +33 -0
  181. package/src/navigation/edit/index.js +134 -130
  182. package/src/navigation/edit/navigation-menu-selector.js +2 -1
  183. package/src/navigation/index.php +62 -9
  184. package/src/navigation/style.scss +17 -1
  185. package/src/navigation/view.js +14 -2
  186. package/src/navigation-link/edit.js +1 -0
  187. package/src/navigation-link/editor.scss +18 -0
  188. package/src/navigation-link/shared/controls.js +35 -62
  189. package/src/navigation-link/shared/test/controls.js +5 -5
  190. package/src/navigation-link/shared/test/use-handle-link-change.test.js +212 -0
  191. package/src/navigation-link/shared/test/use-link-preview.test.js +19 -1
  192. package/src/navigation-link/shared/use-handle-link-change.js +36 -9
  193. package/src/navigation-link/shared/use-link-preview.js +14 -15
  194. package/src/navigation-overlay-close/style.scss +3 -3
  195. package/src/navigation-submenu/edit.js +11 -28
  196. package/src/nextpage/block.json +0 -1
  197. package/src/page-list-item/edit.js +8 -7
  198. package/src/paragraph/edit.js +2 -2
  199. package/src/post-featured-image/index.php +4 -2
  200. package/src/post-navigation-link/block.json +3 -1
  201. package/src/post-navigation-link/edit.js +35 -2
  202. package/src/post-navigation-link/index.js +0 -2
  203. package/src/post-title/block.json +3 -1
  204. package/src/post-title/deprecated.js +1 -86
  205. package/src/post-title/edit.js +18 -2
  206. package/src/query-title/block.json +3 -1
  207. package/src/query-title/deprecated.js +1 -74
  208. package/src/query-title/edit.js +27 -11
  209. package/src/shortcode/block.json +2 -1
  210. package/src/site-tagline/block.json +4 -6
  211. package/src/site-tagline/deprecated.js +1 -70
  212. package/src/site-tagline/edit.js +22 -9
  213. package/src/site-title/block.json +3 -1
  214. package/src/site-title/deprecated.js +1 -83
  215. package/src/site-title/edit.js +22 -9
  216. package/src/tabs-menu-item/block.json +26 -1
  217. package/src/tabs-menu-item/controls.js +108 -0
  218. package/src/tabs-menu-item/edit.js +79 -6
  219. package/src/tabs-menu-item/editor.scss +6 -0
  220. package/src/tabs-menu-item/save.js +26 -1
  221. package/src/tabs-menu-item/style.scss +14 -3
  222. package/build/post-navigation-link/deprecated.cjs +0 -100
  223. package/build/post-navigation-link/deprecated.cjs.map +0 -7
  224. package/build-module/post-navigation-link/deprecated.mjs +0 -69
  225. package/build-module/post-navigation-link/deprecated.mjs.map +0 -7
  226. package/src/post-navigation-link/deprecated.js +0 -72
@@ -952,16 +952,7 @@ function Navigation( {
952
952
 
953
953
  if ( hasUnsavedBlocks && ! isCreatingNavigationMenu ) {
954
954
  return (
955
- <TagName
956
- { ...blockProps }
957
- aria-describedby={
958
- ! isPlaceholder ? accessibleDescriptionId : undefined
959
- }
960
- >
961
- <AccessibleDescription id={ accessibleDescriptionId }>
962
- { __( 'Unsaved Navigation Menu.' ) }
963
- </AccessibleDescription>
964
-
955
+ <>
965
956
  <MenuInspectorControls
966
957
  clientId={ clientId }
967
958
  createNavigationMenuIsSuccess={
@@ -978,26 +969,36 @@ function Navigation( {
978
969
  blockEditingMode={ blockEditingMode }
979
970
  />
980
971
  { blockEditingMode === 'default' && stylingInspectorControls }
981
- <ResponsiveWrapper
982
- id={ clientId }
983
- onToggle={ setResponsiveMenuVisibility }
984
- isOpen={ isResponsiveMenuOpen }
985
- hasIcon={ hasIcon }
986
- icon={ icon }
987
- isResponsive={ isResponsive }
988
- isHiddenByDefault={ isHiddenByDefault }
989
- overlayBackgroundColor={ overlayBackgroundColor }
990
- overlayTextColor={ overlayTextColor }
991
- overlay={ overlay }
992
- onNavigateToEntityRecord={ onNavigateToEntityRecord }
972
+ <TagName
973
+ { ...blockProps }
974
+ aria-describedby={
975
+ ! isPlaceholder ? accessibleDescriptionId : undefined
976
+ }
993
977
  >
994
- <UnsavedInnerBlocks
995
- createNavigationMenu={ createNavigationMenu }
996
- blocks={ uncontrolledInnerBlocks }
997
- hasSelection={ isSelected || isInnerBlockSelected }
998
- />
999
- </ResponsiveWrapper>
1000
- </TagName>
978
+ <AccessibleDescription id={ accessibleDescriptionId }>
979
+ { __( 'Unsaved Navigation Menu.' ) }
980
+ </AccessibleDescription>
981
+ <ResponsiveWrapper
982
+ id={ clientId }
983
+ onToggle={ setResponsiveMenuVisibility }
984
+ isOpen={ isResponsiveMenuOpen }
985
+ hasIcon={ hasIcon }
986
+ icon={ icon }
987
+ isResponsive={ isResponsive }
988
+ isHiddenByDefault={ isHiddenByDefault }
989
+ overlayBackgroundColor={ overlayBackgroundColor }
990
+ overlayTextColor={ overlayTextColor }
991
+ overlay={ overlay }
992
+ onNavigateToEntityRecord={ onNavigateToEntityRecord }
993
+ >
994
+ <UnsavedInnerBlocks
995
+ createNavigationMenu={ createNavigationMenu }
996
+ blocks={ uncontrolledInnerBlocks }
997
+ hasSelection={ isSelected || isInnerBlockSelected }
998
+ />
999
+ </ResponsiveWrapper>
1000
+ </TagName>
1001
+ </>
1001
1002
  );
1002
1003
  }
1003
1004
 
@@ -1005,7 +1006,7 @@ function Navigation( {
1005
1006
  // TODO - the user should be able to select a new one?
1006
1007
  if ( ref && isNavigationMenuMissing ) {
1007
1008
  return (
1008
- <TagName { ...blockProps }>
1009
+ <>
1009
1010
  <MenuInspectorControls
1010
1011
  clientId={ clientId }
1011
1012
  createNavigationMenuIsSuccess={
@@ -1021,10 +1022,12 @@ function Navigation( {
1021
1022
  isLoading={ isLoading }
1022
1023
  blockEditingMode={ blockEditingMode }
1023
1024
  />
1024
- <DeletedNavigationWarning
1025
- onCreateNew={ createUntitledEmptyNavigationMenu }
1026
- />
1027
- </TagName>
1025
+ <TagName { ...blockProps }>
1026
+ <DeletedNavigationWarning
1027
+ onCreateNew={ createUntitledEmptyNavigationMenu }
1028
+ />
1029
+ </TagName>
1030
+ </>
1028
1031
  );
1029
1032
  }
1030
1033
 
@@ -1074,105 +1077,106 @@ function Navigation( {
1074
1077
  }
1075
1078
 
1076
1079
  return (
1077
- <EntityProvider kind="postType" type="wp_navigation" id={ ref }>
1078
- <RecursionProvider uniqueId={ recursionId }>
1079
- <MenuInspectorControls
1080
- clientId={ clientId }
1081
- createNavigationMenuIsSuccess={
1082
- createNavigationMenuIsSuccess
1083
- }
1084
- createNavigationMenuIsError={ createNavigationMenuIsError }
1085
- currentMenuId={ ref }
1086
- isNavigationMenuMissing={ isNavigationMenuMissing }
1087
- isManageMenusButtonDisabled={ isManageMenusButtonDisabled }
1088
- onCreateNew={ createUntitledEmptyNavigationMenu }
1089
- onSelectClassicMenu={ onSelectClassicMenu }
1090
- onSelectNavigationMenu={ onSelectNavigationMenu }
1091
- isLoading={ isLoading }
1092
- blockEditingMode={ blockEditingMode }
1093
- />
1094
- { blockEditingMode === 'default' && stylingInspectorControls }
1095
- { blockEditingMode === 'contentOnly' && isEntityAvailable && (
1096
- <NavigationAddPageButton clientId={ clientId } />
1097
- ) }
1098
- { blockEditingMode === 'default' && isEntityAvailable && (
1099
- <InspectorControls group="advanced">
1100
- { hasResolvedCanUserUpdateNavigationMenu &&
1101
- canUserUpdateNavigationMenu && (
1102
- <NavigationMenuNameControl />
1103
- ) }
1104
- { hasResolvedCanUserDeleteNavigationMenu &&
1105
- canUserDeleteNavigationMenu && (
1106
- <NavigationMenuDeleteControl
1107
- onDelete={ () => {
1108
- replaceInnerBlocks( clientId, [] );
1109
- showNavigationMenuStatusNotice(
1110
- __(
1111
- 'Navigation Menu successfully deleted.'
1112
- )
1113
- );
1114
- } }
1115
- />
1116
- ) }
1117
- <ManageMenusButton
1118
- disabled={ isManageMenusButtonDisabled }
1119
- className="wp-block-navigation-manage-menus-button"
1120
- />
1121
- </InspectorControls>
1122
- ) }
1123
-
1124
- <TagName
1125
- { ...blockProps }
1126
- aria-describedby={
1127
- ! isPlaceholder && ! isLoading
1128
- ? accessibleDescriptionId
1129
- : undefined
1130
- }
1131
- >
1132
- { isLoading && ! isHiddenByDefault && (
1133
- <div className="wp-block-navigation__loading-indicator-container">
1134
- <Spinner className="wp-block-navigation__loading-indicator" />
1135
- </div>
1136
- ) }
1137
-
1138
- { ( ! isLoading || isHiddenByDefault ) && (
1139
- <>
1140
- <AccessibleMenuDescription
1141
- id={ accessibleDescriptionId }
1142
- />
1143
- <ResponsiveWrapper
1144
- id={ clientId }
1145
- onToggle={ setResponsiveMenuVisibility }
1146
- hasIcon={ hasIcon }
1147
- icon={ icon }
1148
- isOpen={ isResponsiveMenuOpen }
1149
- isResponsive={ isResponsive }
1150
- isHiddenByDefault={ isHiddenByDefault }
1151
- overlayBackgroundColor={
1152
- overlayBackgroundColor
1153
- }
1154
- overlayTextColor={ overlayTextColor }
1155
- overlay={ overlay }
1156
- onNavigateToEntityRecord={
1157
- onNavigateToEntityRecord
1158
- }
1159
- >
1160
- { isEntityAvailable && (
1161
- <NavigationInnerBlocks
1162
- clientId={ clientId }
1163
- hasCustomPlaceholder={
1164
- !! CustomPlaceholder
1165
- }
1166
- templateLock={ templateLock }
1167
- orientation={ orientation }
1080
+ <>
1081
+ <MenuInspectorControls
1082
+ clientId={ clientId }
1083
+ createNavigationMenuIsSuccess={ createNavigationMenuIsSuccess }
1084
+ createNavigationMenuIsError={ createNavigationMenuIsError }
1085
+ currentMenuId={ ref }
1086
+ isNavigationMenuMissing={ isNavigationMenuMissing }
1087
+ isManageMenusButtonDisabled={ isManageMenusButtonDisabled }
1088
+ onCreateNew={ createUntitledEmptyNavigationMenu }
1089
+ onSelectClassicMenu={ onSelectClassicMenu }
1090
+ onSelectNavigationMenu={ onSelectNavigationMenu }
1091
+ isLoading={ isLoading }
1092
+ blockEditingMode={ blockEditingMode }
1093
+ />
1094
+ { blockEditingMode === 'default' && stylingInspectorControls }
1095
+ <EntityProvider kind="postType" type="wp_navigation" id={ ref }>
1096
+ <RecursionProvider uniqueId={ recursionId }>
1097
+ { blockEditingMode === 'contentOnly' &&
1098
+ isEntityAvailable && (
1099
+ <NavigationAddPageButton clientId={ clientId } />
1100
+ ) }
1101
+ { blockEditingMode === 'default' && isEntityAvailable && (
1102
+ <InspectorControls group="advanced">
1103
+ { hasResolvedCanUserUpdateNavigationMenu &&
1104
+ canUserUpdateNavigationMenu && (
1105
+ <NavigationMenuNameControl />
1106
+ ) }
1107
+ { hasResolvedCanUserDeleteNavigationMenu &&
1108
+ canUserDeleteNavigationMenu && (
1109
+ <NavigationMenuDeleteControl
1110
+ onDelete={ () => {
1111
+ replaceInnerBlocks( clientId, [] );
1112
+ showNavigationMenuStatusNotice(
1113
+ __(
1114
+ 'Navigation Menu successfully deleted.'
1115
+ )
1116
+ );
1117
+ } }
1168
1118
  />
1169
1119
  ) }
1170
- </ResponsiveWrapper>
1171
- </>
1120
+ <ManageMenusButton
1121
+ disabled={ isManageMenusButtonDisabled }
1122
+ className="wp-block-navigation-manage-menus-button"
1123
+ />
1124
+ </InspectorControls>
1172
1125
  ) }
1173
- </TagName>
1174
- </RecursionProvider>
1175
- </EntityProvider>
1126
+
1127
+ <TagName
1128
+ { ...blockProps }
1129
+ aria-describedby={
1130
+ ! isPlaceholder && ! isLoading
1131
+ ? accessibleDescriptionId
1132
+ : undefined
1133
+ }
1134
+ >
1135
+ { isLoading && ! isHiddenByDefault && (
1136
+ <div className="wp-block-navigation__loading-indicator-container">
1137
+ <Spinner className="wp-block-navigation__loading-indicator" />
1138
+ </div>
1139
+ ) }
1140
+
1141
+ { ( ! isLoading || isHiddenByDefault ) && (
1142
+ <>
1143
+ <AccessibleMenuDescription
1144
+ id={ accessibleDescriptionId }
1145
+ />
1146
+ <ResponsiveWrapper
1147
+ id={ clientId }
1148
+ onToggle={ setResponsiveMenuVisibility }
1149
+ hasIcon={ hasIcon }
1150
+ icon={ icon }
1151
+ isOpen={ isResponsiveMenuOpen }
1152
+ isResponsive={ isResponsive }
1153
+ isHiddenByDefault={ isHiddenByDefault }
1154
+ overlayBackgroundColor={
1155
+ overlayBackgroundColor
1156
+ }
1157
+ overlayTextColor={ overlayTextColor }
1158
+ overlay={ overlay }
1159
+ onNavigateToEntityRecord={
1160
+ onNavigateToEntityRecord
1161
+ }
1162
+ >
1163
+ { isEntityAvailable && (
1164
+ <NavigationInnerBlocks
1165
+ clientId={ clientId }
1166
+ hasCustomPlaceholder={
1167
+ !! CustomPlaceholder
1168
+ }
1169
+ templateLock={ templateLock }
1170
+ orientation={ orientation }
1171
+ />
1172
+ ) }
1173
+ </ResponsiveWrapper>
1174
+ </>
1175
+ ) }
1176
+ </TagName>
1177
+ </RecursionProvider>
1178
+ </EntityProvider>
1179
+ </>
1176
1180
  );
1177
1181
  }
1178
1182
 
@@ -67,7 +67,8 @@ function NavigationMenuSelector( {
67
67
  const [ currentTitle ] = useEntityProp(
68
68
  'postType',
69
69
  'wp_navigation',
70
- 'title'
70
+ 'title',
71
+ currentMenuId
71
72
  );
72
73
 
73
74
  const menuChoices = useMemo( () => {
@@ -425,7 +425,11 @@ class WP_Navigation_Block_Renderer {
425
425
  $full_template_part_id = $theme . '//' . $slug;
426
426
  $block_template = get_block_file_template( $full_template_part_id, 'wp_template_part' );
427
427
  if ( isset( $block_template->content ) ) {
428
- $parsed_blocks = parse_blocks( $block_template->content );
428
+ // Expand shortcodes before parsing blocks, matching the order in
429
+ // `render_block_core_template_part()`.
430
+ $content = shortcode_unautop( $block_template->content );
431
+ $content = do_shortcode( $content );
432
+ $parsed_blocks = parse_blocks( $content );
429
433
  $blocks = block_core_navigation_filter_out_empty_blocks( $parsed_blocks );
430
434
  // Disable overlay menu for any navigation blocks within the overlay to prevent nested overlays.
431
435
  $blocks = static::disable_overlay_menu_for_nested_navigation_blocks( $blocks );
@@ -449,6 +453,12 @@ class WP_Navigation_Block_Renderer {
449
453
  // Re-serialize, and run Block Hooks algorithm to inject hooked blocks.
450
454
  $markup = serialize_blocks( $blocks );
451
455
  $markup = apply_block_hooks_to_content_from_post_object( $markup, $template_part_post );
456
+
457
+ // Expand shortcodes before parsing blocks, matching the order in
458
+ // `render_block_core_template_part()`.
459
+ $markup = shortcode_unautop( $markup );
460
+ $markup = do_shortcode( $markup );
461
+
452
462
  $blocks = parse_blocks( $markup );
453
463
 
454
464
  // Disable overlay menu for any navigation blocks within the overlay to prevent nested overlays.
@@ -697,19 +707,21 @@ class WP_Navigation_Block_Renderer {
697
707
  if ( ! empty( $attributes['overlay'] ) ) {
698
708
  // Get blocks from the overlay template part.
699
709
  $overlay_blocks = static::get_overlay_blocks_from_template_part( $attributes['overlay'], $attributes );
700
- // Check if overlay contains a navigation-overlay-close block.
701
- $has_custom_overlay_close_block = block_core_navigation_block_tree_has_block_type(
702
- $overlay_blocks,
703
- 'core/navigation-overlay-close',
704
- array( 'core/navigation' ) // Skip navigation blocks, as they cannot contain an overlay close block
705
- );
706
710
  // Render template part blocks directly without navigation container wrapper.
707
711
  $overlay_blocks_html = static::get_template_part_blocks_html( $overlay_blocks );
712
+ // Check if overlay contains a navigation-overlay-close block (detect in rendered HTML so it works with patterns).
713
+ $has_custom_overlay_close_block = block_core_navigation_overlay_html_has_close_block( $overlay_blocks_html );
708
714
  // Add Interactivity API directives to the overlay close block if present.
709
715
  if ( $has_custom_overlay_close_block && $is_interactive ) {
710
716
  $tags = new WP_HTML_Tag_Processor( $overlay_blocks_html );
711
717
  $overlay_blocks_html = block_core_navigation_add_directives_to_overlay_close( $tags );
712
718
  }
719
+ // Images in the overlay are hidden until the menu is opened. Pre-set
720
+ // fetchpriority="low" so that when wp_filter_content_tags() processes the
721
+ // parent template part, it sees the attribute already present and calls
722
+ // wp_get_loading_optimization_attributes() with fetchpriority="low", which both prevents
723
+ // fetchpriority="high" from being added and stops the LCP counter from being incremented.
724
+ $overlay_blocks_html = block_core_navigation_set_overlay_image_fetch_priority( $overlay_blocks_html );
713
725
  }
714
726
 
715
727
  $has_custom_overlay = ! empty( $overlay_blocks_html );
@@ -1088,6 +1100,28 @@ if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
1088
1100
  }
1089
1101
  }
1090
1102
 
1103
+ /**
1104
+ * Checks if the overlay HTML contains a navigation-overlay-close block.
1105
+ *
1106
+ * Uses WP_HTML_Tag_Processor to detect the close button in rendered output,
1107
+ * so it works when the overlay uses patterns (pattern content is rendered at
1108
+ * output time, not in the block tree).
1109
+ *
1110
+ * @since 7.0.0
1111
+ *
1112
+ * @param string $html The rendered overlay HTML.
1113
+ * @return bool True if a close button element is found.
1114
+ */
1115
+ function block_core_navigation_overlay_html_has_close_block( $html ) {
1116
+ $tags = new WP_HTML_Tag_Processor( $html );
1117
+ return $tags->next_tag(
1118
+ array(
1119
+ 'tag_name' => 'BUTTON',
1120
+ 'class_name' => 'wp-block-navigation-overlay-close',
1121
+ )
1122
+ );
1123
+ }
1124
+
1091
1125
  /**
1092
1126
  * Add Interactivity API directives to the navigation-overlay-close block
1093
1127
  * markup using the Tag Processor.
@@ -1111,6 +1145,25 @@ function block_core_navigation_add_directives_to_overlay_close( $tags ) {
1111
1145
  return $tags->get_updated_html();
1112
1146
  }
1113
1147
 
1148
+ /**
1149
+ * Sets fetchpriority="low" on all IMG tags within the navigation overlay.
1150
+ *
1151
+ * Images in the overlay are hidden until the menu is opened, so they should
1152
+ * not compete with any actual LCP element image on the page.
1153
+ *
1154
+ * @since 7.0.0
1155
+ *
1156
+ * @param string $overlay_blocks_html The rendered HTML of the overlay blocks.
1157
+ * @return string Modified HTML with fetchpriority="low" on all IMG tags.
1158
+ */
1159
+ function block_core_navigation_set_overlay_image_fetch_priority( string $overlay_blocks_html ): string {
1160
+ $tags = new WP_HTML_Tag_Processor( $overlay_blocks_html );
1161
+ while ( $tags->next_tag( 'IMG' ) ) {
1162
+ $tags->set_attribute( 'fetchpriority', 'low' );
1163
+ }
1164
+ return $tags->get_updated_html();
1165
+ }
1166
+
1114
1167
  /**
1115
1168
  * Add Interactivity API directives to the navigation-submenu and page-list
1116
1169
  * blocks markup using the Tag Processor.
@@ -1146,8 +1199,8 @@ function block_core_navigation_add_directives_to_submenu( $tags, $block_attribut
1146
1199
  $open_on_hover = 'hover' === $computed_visibility;
1147
1200
 
1148
1201
  if ( $open_on_hover ) {
1149
- $tags->set_attribute( 'data-wp-on--mouseenter', 'actions.openMenuOnHover' );
1150
- $tags->set_attribute( 'data-wp-on--mouseleave', 'actions.closeMenuOnHover' );
1202
+ $tags->set_attribute( 'data-wp-on--pointerenter', 'actions.openMenuOnHover' );
1203
+ $tags->set_attribute( 'data-wp-on--pointerleave', 'actions.closeMenuOnHover' );
1151
1204
  }
1152
1205
 
1153
1206
  // Add directives to the toggle submenu button.
@@ -247,7 +247,13 @@ $navigation-icon-size: 24px;
247
247
  }
248
248
 
249
249
  // Show submenus on hover unless they open on click.
250
- &:not(.open-on-click):hover > .wp-block-navigation__submenu-container,
250
+ // Restricted to true-hover devices to prevent sticky touch-hover on mobile.
251
+ @media (hover: hover) {
252
+ &:not(.open-on-click):hover > .wp-block-navigation__submenu-container {
253
+ @include show-submenu;
254
+ min-width: 200px;
255
+ }
256
+ }
251
257
  // Keep submenus open when focus is within.
252
258
  &:not(.open-on-click):not(.open-on-hover-click):focus-within > .wp-block-navigation__submenu-container,
253
259
  // Show submenus on click.
@@ -694,8 +700,18 @@ button.wp-block-navigation-item__content {
694
700
  display: none;
695
701
  }
696
702
 
703
+ // Override justification dropdown menu positioning rules inside custom overlays.
704
+ // Mirrors the protection at lines 674-678 for default overlays, which does not
705
+ // apply here. Prevents .items-justified-right descendant rules from cascading
706
+ // right: 0 into the overlay and anchoring submenus off the left edge of the viewport.
707
+ // See: https://github.com/WordPress/gutenberg/issues/76276
697
708
  .wp-block-navigation__overlay-container {
698
709
  display: block;
710
+
711
+ .wp-block-navigation__submenu-container {
712
+ right: auto;
713
+ left: 0;
714
+ }
699
715
  }
700
716
  }
701
717
  }
@@ -82,7 +82,12 @@ const { state, actions } = store(
82
82
  },
83
83
  },
84
84
  actions: {
85
- openMenuOnHover() {
85
+ openMenuOnHover( event ) {
86
+ // Pointer events from touch should not open the submenu on hover;
87
+ // touch devices toggle via the click action instead.
88
+ if ( event?.pointerType === 'touch' ) {
89
+ return;
90
+ }
86
91
  const { type, overlayOpenedBy } = getContext();
87
92
  if (
88
93
  type === 'submenu' &&
@@ -93,7 +98,10 @@ const { state, actions } = store(
93
98
  actions.openMenu( 'hover' );
94
99
  }
95
100
  },
96
- closeMenuOnHover() {
101
+ closeMenuOnHover( event ) {
102
+ if ( event?.pointerType === 'touch' ) {
103
+ return;
104
+ }
97
105
  const { type, overlayOpenedBy } = getContext();
98
106
  if (
99
107
  type === 'submenu' &&
@@ -128,6 +136,10 @@ const { state, actions } = store(
128
136
  if ( menuOpenedBy.click || menuOpenedBy.focus ) {
129
137
  actions.closeMenu( 'click' );
130
138
  actions.closeMenu( 'focus' );
139
+ // Also clear hover in case it was set by a synthetic pointerenter
140
+ // on touch (e.g. the browser-fired mouseenter-equivalent before
141
+ // the click event), ensuring the submenu fully closes.
142
+ actions.closeMenu( 'hover' );
131
143
  } else {
132
144
  ctx.previousFocus = ref;
133
145
  actions.openMenu( 'click' );
@@ -177,6 +177,7 @@ export default function NavigationLinkEdit( {
177
177
  clientId,
178
178
  attributes,
179
179
  setAttributes,
180
+ allowTextUpdate: true,
180
181
  } );
181
182
 
182
183
  const [ isInvalid, isDraft ] = useIsInvalidLink(
@@ -150,3 +150,21 @@
150
150
  .navigation-link-control__error-text {
151
151
  color: $alert-red;
152
152
  }
153
+
154
+ .navigation-link-to__action-button {
155
+ grid-column: auto;
156
+ // When this is the last button AND in an odd position among its class
157
+ // siblings, it's unpaired — span the full grid row.
158
+ &:nth-last-child(1 of #{&}):nth-child(odd of #{&}) {
159
+ grid-column: 1 / -1;
160
+ }
161
+
162
+ // Artificially increase specificity to override `justify-content` styles.
163
+ // Not ideal, but it shouldn't be necessary once switching to the new `Button`
164
+ // component from `@wordpress/ui`.
165
+ &#{&}#{&} {
166
+ justify-content: center;
167
+ }
168
+
169
+ }
170
+
@@ -5,7 +5,6 @@ import {
5
5
  Button,
6
6
  __experimentalToolsPanel as ToolsPanel,
7
7
  __experimentalToolsPanelItem as ToolsPanelItem,
8
- __experimentalHStack as HStack,
9
8
  CheckboxControl,
10
9
  TextControl,
11
10
  TextareaControl,
@@ -150,7 +149,7 @@ export function Controls( {
150
149
 
151
150
  // Check if URL is viewable (not hash link or other relative path like ./ or ../)
152
151
  const isViewableUrl =
153
- url &&
152
+ !! url &&
154
153
  ( ! isHashLink( url ) ||
155
154
  ( isRelativePath( url ) && ! url.startsWith( '/' ) ) );
156
155
 
@@ -158,11 +157,6 @@ export function Controls( {
158
157
  const viewUrl =
159
158
  isViewableUrl && url.startsWith( '/' ) && homeUrl ? homeUrl + url : url;
160
159
 
161
- const entityTypeName = getEntityTypeName(
162
- attributes.type,
163
- attributes.kind
164
- );
165
-
166
160
  return (
167
161
  <ToolsPanel
168
162
  label={ __( 'Settings' ) }
@@ -220,61 +214,6 @@ export function Controls( {
220
214
  help={ helpText ? helpText : undefined }
221
215
  />
222
216
  </ToolsPanelItem>
223
-
224
- { url && (
225
- <HStack
226
- className="navigation-link-to__actions"
227
- alignment="left"
228
- justify="left"
229
- style={ { gridColumn: '1 / -1' } }
230
- >
231
- { hasUrlBinding &&
232
- isBoundEntityAvailable &&
233
- entityRecord?.id &&
234
- attributes.kind === 'post-type' &&
235
- onNavigateToEntityRecord && (
236
- <Button
237
- size="compact"
238
- variant="secondary"
239
- onClick={ () => {
240
- onNavigateToEntityRecord( {
241
- postId: entityRecord.id,
242
- postType: attributes.type,
243
- } );
244
- } }
245
- __next40pxDefaultSize
246
- >
247
- { sprintf(
248
- /* translators: %s: entity type (e.g., "page", "post", "category") */
249
- __( 'Edit %s' ),
250
- entityTypeName
251
- ) }
252
- </Button>
253
- ) }
254
- { isViewableUrl && (
255
- <Button
256
- size="compact"
257
- variant="secondary"
258
- href={ viewUrl }
259
- target="_blank"
260
- icon={ external }
261
- iconPosition="right"
262
- __next40pxDefaultSize
263
- >
264
- { sprintf(
265
- /* translators: %s: entity type (e.g., "page", "post", "category") or "link" for external links */
266
- __( 'View %s' ),
267
- attributes.kind &&
268
- attributes.type &&
269
- attributes.kind !== 'custom'
270
- ? entityTypeName
271
- : __( 'link' )
272
- ) }
273
- </Button>
274
- ) }
275
- </HStack>
276
- ) }
277
-
278
217
  <ToolsPanelItem
279
218
  hasValue={ () => !! opensInNewTab }
280
219
  label={ __( 'Open in new tab' ) }
@@ -291,6 +230,40 @@ export function Controls( {
291
230
  }
292
231
  />
293
232
  </ToolsPanelItem>
233
+
234
+ { !! url &&
235
+ hasUrlBinding &&
236
+ isBoundEntityAvailable &&
237
+ entityRecord?.id &&
238
+ attributes.kind === 'post-type' &&
239
+ onNavigateToEntityRecord && (
240
+ <Button
241
+ variant="secondary"
242
+ onClick={ () => {
243
+ onNavigateToEntityRecord( {
244
+ postId: entityRecord.id,
245
+ postType: attributes.type,
246
+ } );
247
+ } }
248
+ __next40pxDefaultSize
249
+ className="navigation-link-to__action-button"
250
+ >
251
+ { __( 'Edit' ) }
252
+ </Button>
253
+ ) }
254
+ { isViewableUrl && (
255
+ <Button
256
+ variant="secondary"
257
+ href={ viewUrl }
258
+ target="_blank"
259
+ icon={ external }
260
+ iconPosition="right"
261
+ __next40pxDefaultSize
262
+ className="navigation-link-to__action-button"
263
+ >
264
+ { __( 'View' ) }
265
+ </Button>
266
+ ) }
294
267
  </>
295
268
  ) }
296
269