@wordpress/block-editor 11.5.0 → 11.6.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 (198) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-list/block-invalid-warning.js +63 -80
  3. package/build/components/block-list/block-invalid-warning.js.map +1 -1
  4. package/build/components/block-settings-menu-controls/index.js +1 -1
  5. package/build/components/block-settings-menu-controls/index.js.map +1 -1
  6. package/build/components/block-switcher/block-transformations-menu.native.js +1 -0
  7. package/build/components/block-switcher/block-transformations-menu.native.js.map +1 -1
  8. package/build/components/convert-to-group-buttons/use-convert-to-group-button-props.js +6 -3
  9. package/build/components/convert-to-group-buttons/use-convert-to-group-button-props.js.map +1 -1
  10. package/build/components/global-styles/border-panel.js +306 -0
  11. package/build/components/global-styles/border-panel.js.map +1 -0
  12. package/build/components/global-styles/hooks.js +57 -3
  13. package/build/components/global-styles/hooks.js.map +1 -1
  14. package/build/components/global-styles/index.js +20 -0
  15. package/build/components/global-styles/index.js.map +1 -1
  16. package/build/components/global-styles/typography-panel.js +62 -15
  17. package/build/components/global-styles/typography-panel.js.map +1 -1
  18. package/build/components/global-styles/use-global-styles-output.js +20 -13
  19. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  20. package/build/components/inserter/index.js +29 -17
  21. package/build/components/inserter/index.js.map +1 -1
  22. package/build/components/inserter/menu.js +1 -1
  23. package/build/components/inserter/menu.js.map +1 -1
  24. package/build/components/inserter/quick-inserter.js +4 -2
  25. package/build/components/inserter/quick-inserter.js.map +1 -1
  26. package/build/components/inserter/search-results.js +10 -3
  27. package/build/components/inserter/search-results.js.map +1 -1
  28. package/build/components/inserter/tabs.js +1 -1
  29. package/build/components/inserter/tabs.js.map +1 -1
  30. package/build/components/link-control/index.js +1 -1
  31. package/build/components/link-control/index.js.map +1 -1
  32. package/build/components/link-control/search-item.js +5 -2
  33. package/build/components/link-control/search-item.js.map +1 -1
  34. package/build/components/list-view/use-block-selection.js +1 -2
  35. package/build/components/list-view/use-block-selection.js.map +1 -1
  36. package/build/components/off-canvas-editor/appender.js +28 -3
  37. package/build/components/off-canvas-editor/appender.js.map +1 -1
  38. package/build/components/off-canvas-editor/branch.js +5 -3
  39. package/build/components/off-canvas-editor/branch.js.map +1 -1
  40. package/build/components/off-canvas-editor/index.js +9 -7
  41. package/build/components/off-canvas-editor/index.js.map +1 -1
  42. package/build/components/off-canvas-editor/link-ui.js +0 -1
  43. package/build/components/off-canvas-editor/link-ui.js.map +1 -1
  44. package/build/components/provider/use-block-sync.js +17 -3
  45. package/build/components/provider/use-block-sync.js.map +1 -1
  46. package/build/components/rich-text/format-toolbar-container.js +0 -3
  47. package/build/components/rich-text/format-toolbar-container.js.map +1 -1
  48. package/build/hooks/border.js +91 -240
  49. package/build/hooks/border.js.map +1 -1
  50. package/build/hooks/custom-class-name.js +4 -4
  51. package/build/hooks/custom-class-name.js.map +1 -1
  52. package/build/hooks/custom-class-name.native.js +3 -4
  53. package/build/hooks/custom-class-name.native.js.map +1 -1
  54. package/build/hooks/layout.js +19 -22
  55. package/build/hooks/layout.js.map +1 -1
  56. package/build/hooks/supports.js +7 -1
  57. package/build/hooks/supports.js.map +1 -1
  58. package/build/hooks/typography.js +2 -1
  59. package/build/hooks/typography.js.map +1 -1
  60. package/build/hooks/utils.js +27 -1
  61. package/build/hooks/utils.js.map +1 -1
  62. package/build/layouts/constrained.js +6 -2
  63. package/build/layouts/constrained.js.map +1 -1
  64. package/build/private-apis.js +4 -1
  65. package/build/private-apis.js.map +1 -1
  66. package/build/store/actions.js +10 -8
  67. package/build/store/actions.js.map +1 -1
  68. package/build/store/selectors.js +19 -3
  69. package/build/store/selectors.js.map +1 -1
  70. package/build/utils/parse-css-unit-to-px.js +15 -9
  71. package/build/utils/parse-css-unit-to-px.js.map +1 -1
  72. package/build-module/components/block-list/block-invalid-warning.js +66 -78
  73. package/build-module/components/block-list/block-invalid-warning.js.map +1 -1
  74. package/build-module/components/block-settings-menu-controls/index.js +1 -1
  75. package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
  76. package/build-module/components/block-switcher/block-transformations-menu.native.js +1 -0
  77. package/build-module/components/block-switcher/block-transformations-menu.native.js.map +1 -1
  78. package/build-module/components/convert-to-group-buttons/use-convert-to-group-button-props.js +6 -3
  79. package/build-module/components/convert-to-group-buttons/use-convert-to-group-button-props.js.map +1 -1
  80. package/build-module/components/global-styles/border-panel.js +291 -0
  81. package/build-module/components/global-styles/border-panel.js.map +1 -0
  82. package/build-module/components/global-styles/hooks.js +54 -3
  83. package/build-module/components/global-styles/hooks.js.map +1 -1
  84. package/build-module/components/global-styles/index.js +2 -1
  85. package/build-module/components/global-styles/index.js.map +1 -1
  86. package/build-module/components/global-styles/typography-panel.js +62 -16
  87. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  88. package/build-module/components/global-styles/use-global-styles-output.js +20 -13
  89. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  90. package/build-module/components/inserter/index.js +28 -16
  91. package/build-module/components/inserter/index.js.map +1 -1
  92. package/build-module/components/inserter/menu.js +1 -1
  93. package/build-module/components/inserter/menu.js.map +1 -1
  94. package/build-module/components/inserter/quick-inserter.js +4 -2
  95. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  96. package/build-module/components/inserter/search-results.js +10 -3
  97. package/build-module/components/inserter/search-results.js.map +1 -1
  98. package/build-module/components/inserter/tabs.js +1 -1
  99. package/build-module/components/inserter/tabs.js.map +1 -1
  100. package/build-module/components/link-control/index.js +1 -1
  101. package/build-module/components/link-control/index.js.map +1 -1
  102. package/build-module/components/link-control/search-item.js +4 -2
  103. package/build-module/components/link-control/search-item.js.map +1 -1
  104. package/build-module/components/list-view/use-block-selection.js +1 -2
  105. package/build-module/components/list-view/use-block-selection.js.map +1 -1
  106. package/build-module/components/off-canvas-editor/appender.js +28 -4
  107. package/build-module/components/off-canvas-editor/appender.js.map +1 -1
  108. package/build-module/components/off-canvas-editor/branch.js +5 -3
  109. package/build-module/components/off-canvas-editor/branch.js.map +1 -1
  110. package/build-module/components/off-canvas-editor/index.js +9 -7
  111. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  112. package/build-module/components/off-canvas-editor/link-ui.js +0 -1
  113. package/build-module/components/off-canvas-editor/link-ui.js.map +1 -1
  114. package/build-module/components/provider/use-block-sync.js +17 -3
  115. package/build-module/components/provider/use-block-sync.js.map +1 -1
  116. package/build-module/components/rich-text/format-toolbar-container.js +0 -3
  117. package/build-module/components/rich-text/format-toolbar-container.js.map +1 -1
  118. package/build-module/hooks/border.js +93 -240
  119. package/build-module/hooks/border.js.map +1 -1
  120. package/build-module/hooks/custom-class-name.js +4 -4
  121. package/build-module/hooks/custom-class-name.js.map +1 -1
  122. package/build-module/hooks/custom-class-name.native.js +3 -4
  123. package/build-module/hooks/custom-class-name.native.js.map +1 -1
  124. package/build-module/hooks/layout.js +19 -22
  125. package/build-module/hooks/layout.js.map +1 -1
  126. package/build-module/hooks/supports.js +7 -1
  127. package/build-module/hooks/supports.js.map +1 -1
  128. package/build-module/hooks/typography.js +2 -1
  129. package/build-module/hooks/typography.js.map +1 -1
  130. package/build-module/hooks/utils.js +27 -1
  131. package/build-module/hooks/utils.js.map +1 -1
  132. package/build-module/layouts/constrained.js +6 -2
  133. package/build-module/layouts/constrained.js.map +1 -1
  134. package/build-module/private-apis.js +3 -1
  135. package/build-module/private-apis.js.map +1 -1
  136. package/build-module/store/actions.js +10 -8
  137. package/build-module/store/actions.js.map +1 -1
  138. package/build-module/store/selectors.js +17 -3
  139. package/build-module/store/selectors.js.map +1 -1
  140. package/build-module/utils/parse-css-unit-to-px.js +15 -9
  141. package/build-module/utils/parse-css-unit-to-px.js.map +1 -1
  142. package/build-style/style-rtl.css +6 -6
  143. package/build-style/style.css +6 -6
  144. package/package.json +31 -31
  145. package/src/components/block-inspector/style.scss +3 -0
  146. package/src/components/block-list/block-invalid-warning.js +72 -64
  147. package/src/components/block-mover/test/__snapshots__/index.native.js.snap +20 -2
  148. package/src/components/block-preview/test/index.js +0 -2
  149. package/src/components/block-settings-menu-controls/index.js +2 -1
  150. package/src/components/block-styles/style.scss +2 -2
  151. package/src/components/block-switcher/block-transformations-menu.native.js +1 -0
  152. package/src/components/color-palette/test/__snapshots__/control.js.snap +16 -14
  153. package/src/components/convert-to-group-buttons/use-convert-to-group-button-props.js +48 -38
  154. package/src/components/global-styles/border-panel.js +285 -0
  155. package/src/components/global-styles/hooks.js +74 -1
  156. package/src/components/global-styles/index.js +2 -0
  157. package/src/components/global-styles/test/use-global-styles-output.js +1 -1
  158. package/src/components/global-styles/typography-panel.js +48 -1
  159. package/src/components/global-styles/use-global-styles-output.js +13 -13
  160. package/src/components/inserter/index.js +30 -11
  161. package/src/components/inserter/menu.js +0 -1
  162. package/src/components/inserter/quick-inserter.js +2 -0
  163. package/src/components/inserter/search-results.js +7 -1
  164. package/src/components/inserter/style.scss +3 -0
  165. package/src/components/inserter/tabs.js +1 -9
  166. package/src/components/link-control/index.js +1 -1
  167. package/src/components/link-control/search-item.js +3 -1
  168. package/src/components/link-control/style.scss +0 -4
  169. package/src/components/link-control/test/index.js +0 -2
  170. package/src/components/list-view/use-block-selection.js +0 -2
  171. package/src/components/off-canvas-editor/appender.js +31 -5
  172. package/src/components/off-canvas-editor/branch.js +3 -1
  173. package/src/components/off-canvas-editor/index.js +7 -7
  174. package/src/components/off-canvas-editor/link-ui.js +0 -1
  175. package/src/components/provider/use-block-sync.js +21 -4
  176. package/src/components/rich-text/format-toolbar-container.js +1 -7
  177. package/src/components/url-popover/test/index.js +0 -2
  178. package/src/hooks/border.js +94 -225
  179. package/src/hooks/custom-class-name.js +4 -4
  180. package/src/hooks/custom-class-name.native.js +3 -4
  181. package/src/hooks/layout.js +19 -16
  182. package/src/hooks/supports.js +6 -0
  183. package/src/hooks/test/style.js +2 -1
  184. package/src/hooks/test/use-typography-props.js +2 -0
  185. package/src/hooks/typography.js +2 -0
  186. package/src/hooks/utils.js +36 -0
  187. package/src/layouts/constrained.js +23 -17
  188. package/src/private-apis.js +2 -0
  189. package/src/store/actions.js +10 -8
  190. package/src/store/selectors.js +20 -3
  191. package/src/utils/parse-css-unit-to-px.js +14 -9
  192. package/src/utils/test/parse-css-unit-to-px.js +1 -2
  193. package/tsconfig.tsbuildinfo +1 -1
  194. package/build/hooks/border-radius.js +0 -100
  195. package/build/hooks/border-radius.js.map +0 -1
  196. package/build-module/hooks/border-radius.js +0 -84
  197. package/build-module/hooks/border-radius.js.map +0 -1
  198. package/src/hooks/border-radius.js +0 -70
@@ -95,11 +95,11 @@ function getPresetsDeclarations( blockPresets = {}, mergedSettings ) {
95
95
  /**
96
96
  * Transform given preset tree into a set of preset class declarations.
97
97
  *
98
- * @param {string} blockSelector
99
- * @param {Object} blockPresets
98
+ * @param {?string} blockSelector
99
+ * @param {Object} blockPresets
100
100
  * @return {string} CSS declarations for the preset classes.
101
101
  */
102
- function getPresetsClasses( blockSelector, blockPresets = {} ) {
102
+ function getPresetsClasses( blockSelector = '*', blockPresets = {} ) {
103
103
  return PRESET_METADATA.reduce(
104
104
  ( declarations, { path, cssVarInfix, classes } ) => {
105
105
  if ( ! classes ) {
@@ -399,7 +399,7 @@ export function getLayoutStyles( {
399
399
  ? `${ selector } .${ className }${
400
400
  spacingStyle?.selector || ''
401
401
  }`
402
- : `${ selector }.${ className }${
402
+ : `${ selector }-${ className }${ selector }-${ className }${
403
403
  spacingStyle?.selector || ''
404
404
  }`;
405
405
  }
@@ -496,9 +496,9 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
496
496
  }
497
497
 
498
498
  Object.entries( ELEMENTS ).forEach( ( [ name, selector ] ) => {
499
- if ( !! tree.styles?.elements[ name ] ) {
499
+ if ( !! tree.styles?.elements?.[ name ] ) {
500
500
  nodes.push( {
501
- styles: tree.styles?.elements[ name ],
501
+ styles: tree.styles?.elements?.[ name ],
502
502
  selector,
503
503
  } );
504
504
  }
@@ -529,7 +529,7 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
529
529
  blockSelectors[ blockName ].fallbackGapValue,
530
530
  hasLayoutSupport:
531
531
  blockSelectors[ blockName ].hasLayoutSupport,
532
- selector: blockSelectors[ blockName ].selector,
532
+ selector: blockSelectors[ blockName ]?.selector,
533
533
  styles: blockStyles,
534
534
  featureSelectors:
535
535
  blockSelectors[ blockName ].featureSelectors,
@@ -547,7 +547,7 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => {
547
547
  ) {
548
548
  nodes.push( {
549
549
  styles: value,
550
- selector: blockSelectors[ blockName ].selector
550
+ selector: blockSelectors[ blockName ]?.selector
551
551
  .split( ',' )
552
552
  .map( ( sel ) => {
553
553
  const elementSelectors =
@@ -606,7 +606,7 @@ export const getNodesWithSettings = ( tree, blockSelectors ) => {
606
606
  nodes.push( {
607
607
  presets: blockPresets,
608
608
  custom: blockCustom,
609
- selector: blockSelectors[ blockName ].selector,
609
+ selector: blockSelectors[ blockName ]?.selector,
610
610
  } );
611
611
  }
612
612
  }
@@ -973,10 +973,10 @@ export const getBlockSelectors = ( blockTypes, getBlockStyles ) => {
973
973
  */
974
974
  function updateConfigWithSeparator( config ) {
975
975
  const needsSeparatorStyleUpdate =
976
- config.styles?.blocks[ 'core/separator' ] &&
977
- config.styles?.blocks[ 'core/separator' ].color?.background &&
978
- ! config.styles?.blocks[ 'core/separator' ].color?.text &&
979
- ! config.styles?.blocks[ 'core/separator' ].border?.color;
976
+ config.styles?.blocks?.[ 'core/separator' ] &&
977
+ config.styles?.blocks?.[ 'core/separator' ].color?.background &&
978
+ ! config.styles?.blocks?.[ 'core/separator' ].color?.text &&
979
+ ! config.styles?.blocks?.[ 'core/separator' ].border?.color;
980
980
  if ( needsSeparatorStyleUpdate ) {
981
981
  return {
982
982
  ...config,
@@ -9,7 +9,7 @@ import classnames from 'classnames';
9
9
  import { speak } from '@wordpress/a11y';
10
10
  import { __, _x, sprintf } from '@wordpress/i18n';
11
11
  import { Dropdown, Button } from '@wordpress/components';
12
- import { Component } from '@wordpress/element';
12
+ import { forwardRef, Component } from '@wordpress/element';
13
13
  import { withDispatch, withSelect } from '@wordpress/data';
14
14
  import { compose, ifCondition } from '@wordpress/compose';
15
15
  import { createBlock, store as blocksStore } from '@wordpress/blocks';
@@ -31,21 +31,26 @@ const defaultRenderToggle = ( {
31
31
  toggleProps = {},
32
32
  prioritizePatterns,
33
33
  } ) => {
34
- let label;
35
- if ( hasSingleBlockType ) {
34
+ const {
35
+ as: Wrapper = Button,
36
+ label: labelProp,
37
+ onClick,
38
+ ...rest
39
+ } = toggleProps;
40
+
41
+ let label = labelProp;
42
+ if ( ! label && hasSingleBlockType ) {
36
43
  label = sprintf(
37
44
  // translators: %s: the name of the block when there is only one
38
45
  _x( 'Add %s', 'directly add the only allowed block' ),
39
46
  blockTitle
40
47
  );
41
- } else if ( prioritizePatterns ) {
48
+ } else if ( ! label && prioritizePatterns ) {
42
49
  label = __( 'Add pattern' );
43
- } else {
50
+ } else if ( ! label ) {
44
51
  label = _x( 'Add block', 'Generic label for block inserter button' );
45
52
  }
46
53
 
47
- const { onClick, ...rest } = toggleProps;
48
-
49
54
  // Handle both onClick functions from the toggle and the parent component.
50
55
  function handleClick( event ) {
51
56
  if ( onToggle ) {
@@ -57,7 +62,7 @@ const defaultRenderToggle = ( {
57
62
  }
58
63
 
59
64
  return (
60
- <Button
65
+ <Wrapper
61
66
  icon={ plus }
62
67
  label={ label }
63
68
  tooltipPosition="bottom"
@@ -71,7 +76,7 @@ const defaultRenderToggle = ( {
71
76
  );
72
77
  };
73
78
 
74
- class Inserter extends Component {
79
+ class PrivateInserter extends Component {
75
80
  constructor() {
76
81
  super( ...arguments );
77
82
 
@@ -145,6 +150,7 @@ class Inserter extends Component {
145
150
  prioritizePatterns,
146
151
  onSelectOrClose,
147
152
  selectBlockOnInsert,
153
+ orderInitialBlockItems,
148
154
  } = this.props;
149
155
 
150
156
  if ( isQuick ) {
@@ -168,6 +174,7 @@ class Inserter extends Component {
168
174
  isAppender={ isAppender }
169
175
  prioritizePatterns={ prioritizePatterns }
170
176
  selectBlockOnInsert={ selectBlockOnInsert }
177
+ orderInitialBlockItems={ orderInitialBlockItems }
171
178
  />
172
179
  );
173
180
  }
@@ -219,7 +226,7 @@ class Inserter extends Component {
219
226
  }
220
227
  }
221
228
 
222
- export default compose( [
229
+ export const ComposedPrivateInserter = compose( [
223
230
  withSelect(
224
231
  ( select, { clientId, rootClientId, shouldDirectInsert = true } ) => {
225
232
  const {
@@ -416,4 +423,16 @@ export default compose( [
416
423
  ( { hasItems, isAppender, rootClientId, clientId } ) =>
417
424
  hasItems || ( ! isAppender && ! rootClientId && ! clientId )
418
425
  ),
419
- ] )( Inserter );
426
+ ] )( PrivateInserter );
427
+
428
+ const Inserter = forwardRef( ( props, ref ) => {
429
+ return (
430
+ <ComposedPrivateInserter
431
+ ref={ ref }
432
+ { ...props }
433
+ orderInitialBlockItems={ undefined }
434
+ />
435
+ );
436
+ } );
437
+
438
+ export default Inserter;
@@ -152,7 +152,6 @@ function InserterMenu(
152
152
  destinationRootClientId,
153
153
  onInsert,
154
154
  onHover,
155
- delayedFilterValue,
156
155
  showMostUsedBlocks,
157
156
  showInserterHelpPanel,
158
157
  ]
@@ -32,6 +32,7 @@ export default function QuickInserter( {
32
32
  isAppender,
33
33
  prioritizePatterns,
34
34
  selectBlockOnInsert,
35
+ orderInitialBlockItems,
35
36
  } ) {
36
37
  const [ filterValue, setFilterValue ] = useState( '' );
37
38
  const [ destinationRootClientId, onInsertBlocks ] = useInsertionPoint( {
@@ -124,6 +125,7 @@ export default function QuickInserter( {
124
125
  isDraggable={ false }
125
126
  prioritizePatterns={ prioritizePatterns }
126
127
  selectBlockOnInsert={ selectBlockOnInsert }
128
+ orderInitialBlockItems={ orderInitialBlockItems }
127
129
  />
128
130
  </div>
129
131
 
@@ -46,6 +46,7 @@ function InserterSearchResults( {
46
46
  shouldFocusBlock = true,
47
47
  prioritizePatterns,
48
48
  selectBlockOnInsert,
49
+ orderInitialBlockItems,
49
50
  } ) {
50
51
  const debouncedSpeak = useDebounce( speak, 500 );
51
52
 
@@ -88,8 +89,12 @@ function InserterSearchResults( {
88
89
  if ( maxBlockTypesToShow === 0 ) {
89
90
  return [];
90
91
  }
92
+ let orderedItems = orderBy( blockTypes, 'frecency', 'desc' );
93
+ if ( ! filterValue && orderInitialBlockItems ) {
94
+ orderedItems = orderInitialBlockItems( orderedItems );
95
+ }
91
96
  const results = searchBlockItems(
92
- orderBy( blockTypes, 'frecency', 'desc' ),
97
+ orderedItems,
93
98
  blockTypeCategories,
94
99
  blockTypeCollections,
95
100
  filterValue
@@ -104,6 +109,7 @@ function InserterSearchResults( {
104
109
  blockTypeCategories,
105
110
  blockTypeCollections,
106
111
  maxBlockTypes,
112
+ orderInitialBlockItems,
107
113
  ] );
108
114
 
109
115
  // Announce search results on change.
@@ -35,6 +35,7 @@ $block-inserter-tabs-height: 44px;
35
35
  .components-popover__content {
36
36
  border: none;
37
37
  outline: none;
38
+ box-shadow: $shadow-popover;
38
39
 
39
40
  .block-editor-inserter__quick-inserter > * {
40
41
  border-left: $border-width solid $gray-400;
@@ -42,10 +43,12 @@ $block-inserter-tabs-height: 44px;
42
43
 
43
44
  &:first-child {
44
45
  border-top: $border-width solid $gray-400;
46
+ border-radius: $radius-block-ui $radius-block-ui 0 0;
45
47
  }
46
48
 
47
49
  &:last-child {
48
50
  border-bottom: $border-width solid $gray-400;
51
+ border-radius: 0 0 $radius-block-ui $radius-block-ui;
49
52
  }
50
53
 
51
54
  &.components-button {
@@ -52,15 +52,7 @@ function InserterTabs( {
52
52
  tempTabs.push( reusableBlocksTab );
53
53
  }
54
54
  return tempTabs;
55
- }, [
56
- prioritizePatterns,
57
- blocksTab,
58
- showPatterns,
59
- patternsTab,
60
- showReusableBlocks,
61
- showMedia,
62
- reusableBlocksTab,
63
- ] );
55
+ }, [ prioritizePatterns, showPatterns, showReusableBlocks, showMedia ] );
64
56
 
65
57
  return (
66
58
  <TabPanel
@@ -366,7 +366,7 @@ function LinkControl( {
366
366
  <Button
367
367
  variant="primary"
368
368
  onClick={ handleSubmit }
369
- className="xblock-editor-link-control__search-submit"
369
+ className="block-editor-link-control__search-submit"
370
370
  disabled={ currentInputIsEmpty } // Disallow submitting empty values.
371
371
  >
372
372
  { __( 'Apply' ) }
@@ -18,6 +18,7 @@ import {
18
18
  category,
19
19
  file,
20
20
  } from '@wordpress/icons';
21
+ import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
21
22
 
22
23
  const ICONS_MAP = {
23
24
  post: postList,
@@ -72,7 +73,8 @@ export const LinkControlSearchItem = ( {
72
73
  <span className="block-editor-link-control__search-item-header">
73
74
  <span className="block-editor-link-control__search-item-title">
74
75
  <TextHighlight
75
- text={ suggestion.title }
76
+ // The component expects a plain text string.
77
+ text={ stripHTML( suggestion.title ) }
76
78
  highlight={ searchTerm }
77
79
  />
78
80
  </span>
@@ -97,10 +97,6 @@ $preview-image-height: 140px;
97
97
  order: 20;
98
98
  }
99
99
 
100
- .components-button .block-editor-link-control__search-submit .has-icon {
101
- margin: -1px;
102
- }
103
-
104
100
  .block-editor-link-control__search-results-wrapper {
105
101
  position: relative;
106
102
  margin-top: -$grid-unit-20 + 1px;
@@ -51,8 +51,6 @@ jest.mock( '@wordpress/data/src/components/use-dispatch', () => ( {
51
51
  useDispatch: () => ( { saveEntityRecords: jest.fn() } ),
52
52
  } ) );
53
53
 
54
- jest.useRealTimers();
55
-
56
54
  jest.mock( '@wordpress/compose', () => ( {
57
55
  ...jest.requireActual( '@wordpress/compose' ),
58
56
  useReducedMotion: jest.fn( () => true ),
@@ -21,7 +21,6 @@ export default function useBlockSelection() {
21
21
  getBlockName,
22
22
  getBlockParents,
23
23
  getBlockSelectionStart,
24
- getBlockSelectionEnd,
25
24
  getSelectedBlockClientIds,
26
25
  hasMultiSelection,
27
26
  hasSelectedBlock,
@@ -154,7 +153,6 @@ export default function useBlockSelection() {
154
153
  getBlockType,
155
154
  getBlockParents,
156
155
  getBlockSelectionStart,
157
- getBlockSelectionEnd,
158
156
  getSelectedBlockClientIds,
159
157
  hasMultiSelection,
160
158
  hasSelectedBlock,
@@ -4,7 +4,12 @@
4
4
  import { useInstanceId } from '@wordpress/compose';
5
5
  import { speak } from '@wordpress/a11y';
6
6
  import { useSelect } from '@wordpress/data';
7
- import { forwardRef, useState, useEffect } from '@wordpress/element';
7
+ import {
8
+ forwardRef,
9
+ useState,
10
+ useEffect,
11
+ useCallback,
12
+ } from '@wordpress/element';
8
13
  import { __, sprintf } from '@wordpress/i18n';
9
14
 
10
15
  /**
@@ -12,7 +17,14 @@ import { __, sprintf } from '@wordpress/i18n';
12
17
  */
13
18
  import { store as blockEditorStore } from '../../store';
14
19
  import useBlockDisplayTitle from '../block-title/use-block-display-title';
15
- import Inserter from '../inserter';
20
+
21
+ import { unlock } from '../../lock-unlock';
22
+ import { privateApis as blockEditorPrivateApis } from '../../private-apis';
23
+
24
+ const prioritizedInserterBlocks = [
25
+ 'core/navigation-link/page',
26
+ 'core/navigation-link',
27
+ ];
16
28
 
17
29
  export const Appender = forwardRef(
18
30
  ( { nestingLevel, blockCount, clientId, ...props }, ref ) => {
@@ -58,10 +70,23 @@ export const Appender = forwardRef(
58
70
  );
59
71
  }, [ insertedBlockTitle ] );
60
72
 
73
+ const orderInitialBlockItems = useCallback( ( items ) => {
74
+ items.sort( ( { id: aName }, { id: bName } ) => {
75
+ // Sort block items according to `prioritizedInserterBlocks`.
76
+ let aIndex = prioritizedInserterBlocks.indexOf( aName );
77
+ let bIndex = prioritizedInserterBlocks.indexOf( bName );
78
+ // All other block items should come after that.
79
+ if ( aIndex < 0 ) aIndex = prioritizedInserterBlocks.length;
80
+ if ( bIndex < 0 ) bIndex = prioritizedInserterBlocks.length;
81
+ return aIndex - bIndex;
82
+ } );
83
+ return items;
84
+ }, [] );
85
+
61
86
  if ( hideInserter ) {
62
87
  return null;
63
88
  }
64
-
89
+ const { PrivateInserter } = unlock( blockEditorPrivateApis );
65
90
  const descriptionId = `off-canvas-editor-appender__${ instanceId }`;
66
91
  const description = sprintf(
67
92
  /* translators: 1: The name of the block. 2: The numerical position of the block. 3: The level of nesting for the block. */
@@ -73,11 +98,11 @@ export const Appender = forwardRef(
73
98
 
74
99
  return (
75
100
  <div className="offcanvas-editor-appender">
76
- <Inserter
101
+ <PrivateInserter
77
102
  ref={ ref }
78
103
  rootClientId={ clientId }
79
104
  position="bottom right"
80
- isAppender={ true }
105
+ isAppender
81
106
  selectBlockOnInsert={ false }
82
107
  shouldDirectInsert={ false }
83
108
  __experimentalIsQuick
@@ -88,6 +113,7 @@ export const Appender = forwardRef(
88
113
  setInsertedBlock( maybeInsertedBlock );
89
114
  }
90
115
  } }
116
+ orderInitialBlockItems={ orderInitialBlockItems }
91
117
  />
92
118
  <div
93
119
  className="offcanvas-editor-appender__description"
@@ -97,6 +97,7 @@ function ListViewBranch( props ) {
97
97
  isExpanded,
98
98
  parentId,
99
99
  shouldShowInnerBlocks = true,
100
+ showAppender: showAppenderProp = true,
100
101
  } = props;
101
102
 
102
103
  const isContentLocked = useSelect(
@@ -117,7 +118,7 @@ function ListViewBranch( props ) {
117
118
  }
118
119
 
119
120
  // Only show the appender at the first level.
120
- const showAppender = level === 1;
121
+ const showAppender = showAppenderProp && level === 1;
121
122
 
122
123
  const filteredBlocks = blocks.filter( Boolean );
123
124
  const blockCount = filteredBlocks.length;
@@ -205,6 +206,7 @@ function ListViewBranch( props ) {
205
206
  isBranchSelected={ isSelectedBranch }
206
207
  selectedClientIds={ selectedClientIds }
207
208
  isExpanded={ isExpanded }
209
+ showAppender={ showAppenderProp }
208
210
  />
209
211
  ) }
210
212
  </AsyncModeProvider>
@@ -56,20 +56,24 @@ export const BLOCK_LIST_ITEM_HEIGHT = 36;
56
56
  *
57
57
  * @param {Object} props Components props.
58
58
  * @param {string} props.id An HTML element id for the root element of ListView.
59
+ * @param {string} props.parentClientId The client id of the parent block.
59
60
  * @param {Array} props.blocks Custom subset of block client IDs to be used instead of the default hierarchy.
60
61
  * @param {boolean} props.showBlockMovers Flag to enable block movers
61
62
  * @param {boolean} props.isExpanded Flag to determine whether nested levels are expanded by default.
62
63
  * @param {Object} props.LeafMoreMenu Optional more menu substitution.
63
64
  * @param {string} props.description Optional accessible description for the tree grid component.
64
65
  * @param {string} props.onSelect Optional callback to be invoked when a block is selected.
66
+ * @param {string} props.showAppender Flag to show or hide the block appender.
65
67
  * @param {Object} ref Forwarded ref
66
68
  */
67
69
  function OffCanvasEditor(
68
70
  {
69
71
  id,
72
+ parentClientId,
70
73
  blocks,
71
74
  showBlockMovers = false,
72
75
  isExpanded = false,
76
+ showAppender = true,
73
77
  LeafMoreMenu,
74
78
  description = __( 'Block navigation structure' ),
75
79
  onSelect,
@@ -80,10 +84,9 @@ function OffCanvasEditor(
80
84
  const { clientIdsTree, draggedClientIds, selectedClientIds } =
81
85
  useListViewClientIds( blocks );
82
86
 
83
- const { visibleBlockCount, shouldShowInnerBlocks, parentId } = useSelect(
87
+ const { visibleBlockCount, shouldShowInnerBlocks } = useSelect(
84
88
  ( select ) => {
85
89
  const {
86
- getBlockRootClientId,
87
90
  getGlobalBlockCount,
88
91
  getClientIdsOfDescendants,
89
92
  __unstableGetEditorMode,
@@ -95,10 +98,6 @@ function OffCanvasEditor(
95
98
  return {
96
99
  visibleBlockCount: getGlobalBlockCount() - draggedBlockCount,
97
100
  shouldShowInnerBlocks: __unstableGetEditorMode() !== 'zoom-out',
98
- parentId:
99
- blocks.length > 0
100
- ? getBlockRootClientId( blocks[ 0 ].clientId )
101
- : undefined,
102
101
  };
103
102
  },
104
103
  [ draggedClientIds, blocks ]
@@ -232,7 +231,7 @@ function OffCanvasEditor(
232
231
  >
233
232
  <ListViewContext.Provider value={ contextValue }>
234
233
  <ListViewBranch
235
- parentId={ parentId }
234
+ parentId={ parentClientId }
236
235
  blocks={ clientIdsTree }
237
236
  selectBlock={ selectEditorBlock }
238
237
  showBlockMovers={ showBlockMovers }
@@ -240,6 +239,7 @@ function OffCanvasEditor(
240
239
  selectedClientIds={ selectedClientIds }
241
240
  isExpanded={ isExpanded }
242
241
  shouldShowInnerBlocks={ shouldShowInnerBlocks }
242
+ showAppender={ showAppender }
243
243
  />
244
244
  <TreeGridRow
245
245
  level={ 1 }
@@ -137,7 +137,6 @@ export function LinkUI( props ) {
137
137
  placement="bottom"
138
138
  onClose={ props.onClose }
139
139
  anchor={ props.anchor }
140
- __unstableSlotName={ '__unstable-block-tools-after' }
141
140
  shift
142
141
  >
143
142
  <LinkControl
@@ -76,10 +76,18 @@ export default function useBlockSync( {
76
76
  resetBlocks,
77
77
  resetSelection,
78
78
  replaceInnerBlocks,
79
+ selectBlock,
79
80
  setHasControlledInnerBlocks,
80
81
  __unstableMarkNextChangeAsNotPersistent,
81
82
  } = registry.dispatch( blockEditorStore );
82
- const { getBlockName, getBlocks } = registry.select( blockEditorStore );
83
+ const {
84
+ hasSelectedBlock,
85
+ getBlockName,
86
+ getBlocks,
87
+ getSelectionStart,
88
+ getSelectionEnd,
89
+ getBlock,
90
+ } = registry.select( blockEditorStore );
83
91
  const isControlled = useSelect(
84
92
  ( select ) => {
85
93
  return (
@@ -159,6 +167,9 @@ export default function useBlockSync( {
159
167
  // bound sync, unset the outbound value to avoid considering it in
160
168
  // subsequent renders.
161
169
  pendingChanges.current.outgoing = [];
170
+ const hadSelecton = hasSelectedBlock();
171
+ const selectionAnchor = getSelectionStart();
172
+ const selectionFocus = getSelectionEnd();
162
173
  setControlledBlocks();
163
174
 
164
175
  if ( controlledSelection ) {
@@ -167,6 +178,15 @@ export default function useBlockSync( {
167
178
  controlledSelection.selectionEnd,
168
179
  controlledSelection.initialPosition
169
180
  );
181
+ } else {
182
+ const selectionStillExists = getBlock(
183
+ selectionAnchor.clientId
184
+ );
185
+ if ( hadSelecton && ! selectionStillExists ) {
186
+ selectBlock( clientId );
187
+ } else {
188
+ resetSelection( selectionAnchor, selectionFocus );
189
+ }
170
190
  }
171
191
  }
172
192
  }, [ controlledBlocks, clientId ] );
@@ -182,8 +202,6 @@ export default function useBlockSync( {
182
202
 
183
203
  useEffect( () => {
184
204
  const {
185
- getSelectionStart,
186
- getSelectionEnd,
187
205
  getSelectedBlocksInitialCaretPosition,
188
206
  isLastBlockChangePersistent,
189
207
  __unstableIsLastBlockChangeIgnored,
@@ -220,7 +238,6 @@ export default function useBlockSync( {
220
238
  const newBlocks = getBlocks( clientId );
221
239
  const areBlocksDifferent = newBlocks !== blocks;
222
240
  blocks = newBlocks;
223
-
224
241
  if (
225
242
  areBlocksDifferent &&
226
243
  ( pendingChanges.current.incoming ||
@@ -19,11 +19,7 @@ import FormatToolbar from './format-toolbar';
19
19
  import NavigableToolbar from '../navigable-toolbar';
20
20
  import { store as blockEditorStore } from '../../store';
21
21
 
22
- function InlineSelectionToolbar( {
23
- value,
24
- editableContentElement,
25
- activeFormats,
26
- } ) {
22
+ function InlineSelectionToolbar( { editableContentElement, activeFormats } ) {
27
23
  const lastFormat = activeFormats[ activeFormats.length - 1 ];
28
24
  const lastFormatType = lastFormat?.type;
29
25
  const settings = useSelect(
@@ -32,7 +28,6 @@ function InlineSelectionToolbar( {
32
28
  );
33
29
  const popoverAnchor = useAnchor( {
34
30
  editableContentElement,
35
- value,
36
31
  settings,
37
32
  } );
38
33
 
@@ -85,7 +80,6 @@ const FormatToolbarContainer = ( {
85
80
  return (
86
81
  <InlineSelectionToolbar
87
82
  editableContentElement={ editableContentElement }
88
- value={ value }
89
83
  activeFormats={ activeFormats }
90
84
  />
91
85
  );
@@ -9,8 +9,6 @@ import userEvent from '@testing-library/user-event';
9
9
  */
10
10
  import URLPopover from '../';
11
11
 
12
- jest.useRealTimers();
13
-
14
12
  /**
15
13
  * Returns the first found popover element up the DOM tree.
16
14
  *