@wordpress/block-editor 11.5.0 → 11.7.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 (345) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +4 -0
  3. package/build/components/block-list/block-html.js +1 -3
  4. package/build/components/block-list/block-html.js.map +1 -1
  5. package/build/components/block-list/block-invalid-warning.js +63 -80
  6. package/build/components/block-list/block-invalid-warning.js.map +1 -1
  7. package/build/components/block-preview/auto.js +6 -23
  8. package/build/components/block-preview/auto.js.map +1 -1
  9. package/build/components/block-settings-menu-controls/index.js +1 -1
  10. package/build/components/block-settings-menu-controls/index.js.map +1 -1
  11. package/build/components/block-switcher/block-transformations-menu.native.js +1 -0
  12. package/build/components/block-switcher/block-transformations-menu.native.js.map +1 -1
  13. package/build/components/convert-to-group-buttons/use-convert-to-group-button-props.js +6 -3
  14. package/build/components/convert-to-group-buttons/use-convert-to-group-button-props.js.map +1 -1
  15. package/build/components/editor-styles/index.js +20 -2
  16. package/build/components/editor-styles/index.js.map +1 -1
  17. package/build/components/global-styles/border-panel.js +306 -0
  18. package/build/components/global-styles/border-panel.js.map +1 -0
  19. package/build/components/global-styles/color-panel.js +583 -0
  20. package/build/components/global-styles/color-panel.js.map +1 -0
  21. package/build/components/global-styles/dimensions-panel.js +8 -30
  22. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  23. package/build/components/global-styles/get-block-css-selector.js +129 -0
  24. package/build/components/global-styles/get-block-css-selector.js.map +1 -0
  25. package/build/components/global-styles/hooks.js +109 -3
  26. package/build/components/global-styles/hooks.js.map +1 -1
  27. package/build/components/global-styles/index.js +36 -0
  28. package/build/components/global-styles/index.js.map +1 -1
  29. package/build/components/global-styles/typography-panel.js +66 -45
  30. package/build/components/global-styles/typography-panel.js.map +1 -1
  31. package/build/components/global-styles/use-global-styles-output.js +180 -99
  32. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  33. package/build/components/global-styles/utils.js +2 -1
  34. package/build/components/global-styles/utils.js.map +1 -1
  35. package/build/components/image-size-control/index.js +8 -5
  36. package/build/components/image-size-control/index.js.map +1 -1
  37. package/build/components/inserter/index.js +29 -17
  38. package/build/components/inserter/index.js.map +1 -1
  39. package/build/components/inserter/menu.js +1 -1
  40. package/build/components/inserter/menu.js.map +1 -1
  41. package/build/components/inserter/quick-inserter.js +4 -2
  42. package/build/components/inserter/quick-inserter.js.map +1 -1
  43. package/build/components/inserter/search-results.js +10 -3
  44. package/build/components/inserter/search-results.js.map +1 -1
  45. package/build/components/inserter/tabs.js +1 -1
  46. package/build/components/inserter/tabs.js.map +1 -1
  47. package/build/components/inspector-controls-tabs/position-controls-panel.js +43 -7
  48. package/build/components/inspector-controls-tabs/position-controls-panel.js.map +1 -1
  49. package/build/components/line-height-control/index.js +15 -1
  50. package/build/components/line-height-control/index.js.map +1 -1
  51. package/build/components/link-control/index.js +1 -1
  52. package/build/components/link-control/index.js.map +1 -1
  53. package/build/components/link-control/search-item.js +5 -2
  54. package/build/components/link-control/search-item.js.map +1 -1
  55. package/build/components/list-view/appender.js +105 -0
  56. package/build/components/list-view/appender.js.map +1 -0
  57. package/build/components/list-view/block.js +5 -5
  58. package/build/components/list-view/block.js.map +1 -1
  59. package/build/components/list-view/branch.js +25 -5
  60. package/build/components/list-view/branch.js.map +1 -1
  61. package/build/components/list-view/index.js +37 -13
  62. package/build/components/list-view/index.js.map +1 -1
  63. package/build/components/list-view/use-block-selection.js +1 -2
  64. package/build/components/list-view/use-block-selection.js.map +1 -1
  65. package/build/components/media-replace-flow/index.js +13 -4
  66. package/build/components/media-replace-flow/index.js.map +1 -1
  67. package/build/components/off-canvas-editor/appender.js +28 -3
  68. package/build/components/off-canvas-editor/appender.js.map +1 -1
  69. package/build/components/off-canvas-editor/branch.js +5 -3
  70. package/build/components/off-canvas-editor/branch.js.map +1 -1
  71. package/build/components/off-canvas-editor/index.js +9 -7
  72. package/build/components/off-canvas-editor/index.js.map +1 -1
  73. package/build/components/off-canvas-editor/link-ui.js +0 -1
  74. package/build/components/off-canvas-editor/link-ui.js.map +1 -1
  75. package/build/components/provider/use-block-sync.js +17 -3
  76. package/build/components/provider/use-block-sync.js.map +1 -1
  77. package/build/components/rich-text/format-edit.js +2 -30
  78. package/build/components/rich-text/format-edit.js.map +1 -1
  79. package/build/components/rich-text/format-toolbar-container.js +0 -3
  80. package/build/components/rich-text/format-toolbar-container.js.map +1 -1
  81. package/build/components/writing-flow/use-input.js +4 -8
  82. package/build/components/writing-flow/use-input.js.map +1 -1
  83. package/build/hooks/border.js +90 -240
  84. package/build/hooks/border.js.map +1 -1
  85. package/build/hooks/color.js +92 -229
  86. package/build/hooks/color.js.map +1 -1
  87. package/build/hooks/content-lock-ui.js +4 -2
  88. package/build/hooks/content-lock-ui.js.map +1 -1
  89. package/build/hooks/{color-panel.js → contrast-checker.js} +11 -49
  90. package/build/hooks/contrast-checker.js.map +1 -0
  91. package/build/hooks/custom-class-name.js +4 -4
  92. package/build/hooks/custom-class-name.js.map +1 -1
  93. package/build/hooks/custom-class-name.native.js +3 -4
  94. package/build/hooks/custom-class-name.native.js.map +1 -1
  95. package/build/hooks/dimensions.js +0 -1
  96. package/build/hooks/dimensions.js.map +1 -1
  97. package/build/hooks/duotone.js +3 -1
  98. package/build/hooks/duotone.js.map +1 -1
  99. package/build/hooks/layout.js +19 -22
  100. package/build/hooks/layout.js.map +1 -1
  101. package/build/hooks/position.js +2 -2
  102. package/build/hooks/position.js.map +1 -1
  103. package/build/hooks/style.js +23 -26
  104. package/build/hooks/style.js.map +1 -1
  105. package/build/hooks/supports.js +7 -1
  106. package/build/hooks/supports.js.map +1 -1
  107. package/build/hooks/typography.js +2 -2
  108. package/build/hooks/typography.js.map +1 -1
  109. package/build/hooks/utils.js +50 -75
  110. package/build/hooks/utils.js.map +1 -1
  111. package/build/layouts/constrained.js +6 -2
  112. package/build/layouts/constrained.js.map +1 -1
  113. package/build/layouts/grid.js +165 -0
  114. package/build/layouts/grid.js.map +1 -0
  115. package/build/layouts/index.js +3 -1
  116. package/build/layouts/index.js.map +1 -1
  117. package/build/private-apis.js +7 -1
  118. package/build/private-apis.js.map +1 -1
  119. package/build/store/actions.js +10 -8
  120. package/build/store/actions.js.map +1 -1
  121. package/build/store/selectors.js +19 -3
  122. package/build/store/selectors.js.map +1 -1
  123. package/build/utils/object.js +76 -0
  124. package/build/utils/object.js.map +1 -0
  125. package/build/utils/parse-css-unit-to-px.js +15 -9
  126. package/build/utils/parse-css-unit-to-px.js.map +1 -1
  127. package/build-module/components/block-list/block-html.js +1 -3
  128. package/build-module/components/block-list/block-html.js.map +1 -1
  129. package/build-module/components/block-list/block-invalid-warning.js +66 -78
  130. package/build-module/components/block-list/block-invalid-warning.js.map +1 -1
  131. package/build-module/components/block-preview/auto.js +6 -22
  132. package/build-module/components/block-preview/auto.js.map +1 -1
  133. package/build-module/components/block-settings-menu-controls/index.js +1 -1
  134. package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
  135. package/build-module/components/block-switcher/block-transformations-menu.native.js +1 -0
  136. package/build-module/components/block-switcher/block-transformations-menu.native.js.map +1 -1
  137. package/build-module/components/convert-to-group-buttons/use-convert-to-group-button-props.js +6 -3
  138. package/build-module/components/convert-to-group-buttons/use-convert-to-group-button-props.js.map +1 -1
  139. package/build-module/components/editor-styles/index.js +19 -2
  140. package/build-module/components/editor-styles/index.js.map +1 -1
  141. package/build-module/components/global-styles/border-panel.js +291 -0
  142. package/build-module/components/global-styles/border-panel.js.map +1 -0
  143. package/build-module/components/global-styles/color-panel.js +554 -0
  144. package/build-module/components/global-styles/color-panel.js.map +1 -0
  145. package/build-module/components/global-styles/dimensions-panel.js +7 -30
  146. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  147. package/build-module/components/global-styles/get-block-css-selector.js +120 -0
  148. package/build-module/components/global-styles/get-block-css-selector.js.map +1 -0
  149. package/build-module/components/global-styles/hooks.js +104 -3
  150. package/build-module/components/global-styles/hooks.js.map +1 -1
  151. package/build-module/components/global-styles/index.js +3 -0
  152. package/build-module/components/global-styles/index.js.map +1 -1
  153. package/build-module/components/global-styles/typography-panel.js +65 -46
  154. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  155. package/build-module/components/global-styles/use-global-styles-output.js +181 -100
  156. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  157. package/build-module/components/global-styles/utils.js +2 -1
  158. package/build-module/components/global-styles/utils.js.map +1 -1
  159. package/build-module/components/image-size-control/index.js +8 -5
  160. package/build-module/components/image-size-control/index.js.map +1 -1
  161. package/build-module/components/inserter/index.js +28 -16
  162. package/build-module/components/inserter/index.js.map +1 -1
  163. package/build-module/components/inserter/menu.js +1 -1
  164. package/build-module/components/inserter/menu.js.map +1 -1
  165. package/build-module/components/inserter/quick-inserter.js +4 -2
  166. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  167. package/build-module/components/inserter/search-results.js +10 -3
  168. package/build-module/components/inserter/search-results.js.map +1 -1
  169. package/build-module/components/inserter/tabs.js +1 -1
  170. package/build-module/components/inserter/tabs.js.map +1 -1
  171. package/build-module/components/inspector-controls-tabs/position-controls-panel.js +42 -7
  172. package/build-module/components/inspector-controls-tabs/position-controls-panel.js.map +1 -1
  173. package/build-module/components/line-height-control/index.js +15 -1
  174. package/build-module/components/line-height-control/index.js.map +1 -1
  175. package/build-module/components/link-control/index.js +1 -1
  176. package/build-module/components/link-control/index.js.map +1 -1
  177. package/build-module/components/link-control/search-item.js +4 -2
  178. package/build-module/components/link-control/search-item.js.map +1 -1
  179. package/build-module/components/list-view/appender.js +88 -0
  180. package/build-module/components/list-view/appender.js.map +1 -0
  181. package/build-module/components/list-view/block.js +5 -4
  182. package/build-module/components/list-view/block.js.map +1 -1
  183. package/build-module/components/list-view/branch.js +22 -5
  184. package/build-module/components/list-view/branch.js.map +1 -1
  185. package/build-module/components/list-view/index.js +32 -12
  186. package/build-module/components/list-view/index.js.map +1 -1
  187. package/build-module/components/list-view/use-block-selection.js +1 -2
  188. package/build-module/components/list-view/use-block-selection.js.map +1 -1
  189. package/build-module/components/media-replace-flow/index.js +12 -4
  190. package/build-module/components/media-replace-flow/index.js.map +1 -1
  191. package/build-module/components/off-canvas-editor/appender.js +28 -4
  192. package/build-module/components/off-canvas-editor/appender.js.map +1 -1
  193. package/build-module/components/off-canvas-editor/branch.js +5 -3
  194. package/build-module/components/off-canvas-editor/branch.js.map +1 -1
  195. package/build-module/components/off-canvas-editor/index.js +9 -7
  196. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  197. package/build-module/components/off-canvas-editor/link-ui.js +0 -1
  198. package/build-module/components/off-canvas-editor/link-ui.js.map +1 -1
  199. package/build-module/components/provider/use-block-sync.js +17 -3
  200. package/build-module/components/provider/use-block-sync.js.map +1 -1
  201. package/build-module/components/rich-text/format-edit.js +3 -31
  202. package/build-module/components/rich-text/format-edit.js.map +1 -1
  203. package/build-module/components/rich-text/format-toolbar-container.js +0 -3
  204. package/build-module/components/rich-text/format-toolbar-container.js.map +1 -1
  205. package/build-module/components/writing-flow/use-input.js +4 -8
  206. package/build-module/components/writing-flow/use-input.js.map +1 -1
  207. package/build-module/hooks/border.js +92 -240
  208. package/build-module/hooks/border.js.map +1 -1
  209. package/build-module/hooks/color.js +90 -232
  210. package/build-module/hooks/color.js.map +1 -1
  211. package/build-module/hooks/content-lock-ui.js +4 -2
  212. package/build-module/hooks/content-lock-ui.js.map +1 -1
  213. package/build-module/hooks/{color-panel.js → contrast-checker.js} +10 -44
  214. package/build-module/hooks/contrast-checker.js.map +1 -0
  215. package/build-module/hooks/custom-class-name.js +4 -4
  216. package/build-module/hooks/custom-class-name.js.map +1 -1
  217. package/build-module/hooks/custom-class-name.native.js +3 -4
  218. package/build-module/hooks/custom-class-name.native.js.map +1 -1
  219. package/build-module/hooks/dimensions.js +0 -1
  220. package/build-module/hooks/dimensions.js.map +1 -1
  221. package/build-module/hooks/duotone.js +4 -2
  222. package/build-module/hooks/duotone.js.map +1 -1
  223. package/build-module/hooks/layout.js +19 -22
  224. package/build-module/hooks/layout.js.map +1 -1
  225. package/build-module/hooks/position.js +3 -3
  226. package/build-module/hooks/position.js.map +1 -1
  227. package/build-module/hooks/style.js +23 -26
  228. package/build-module/hooks/style.js.map +1 -1
  229. package/build-module/hooks/supports.js +7 -1
  230. package/build-module/hooks/supports.js.map +1 -1
  231. package/build-module/hooks/typography.js +2 -2
  232. package/build-module/hooks/typography.js.map +1 -1
  233. package/build-module/hooks/utils.js +48 -72
  234. package/build-module/hooks/utils.js.map +1 -1
  235. package/build-module/layouts/constrained.js +6 -2
  236. package/build-module/layouts/constrained.js.map +1 -1
  237. package/build-module/layouts/grid.js +151 -0
  238. package/build-module/layouts/grid.js.map +1 -0
  239. package/build-module/layouts/index.js +2 -1
  240. package/build-module/layouts/index.js.map +1 -1
  241. package/build-module/private-apis.js +5 -1
  242. package/build-module/private-apis.js.map +1 -1
  243. package/build-module/store/actions.js +10 -8
  244. package/build-module/store/actions.js.map +1 -1
  245. package/build-module/store/selectors.js +17 -3
  246. package/build-module/store/selectors.js.map +1 -1
  247. package/build-module/utils/object.js +69 -0
  248. package/build-module/utils/object.js.map +1 -0
  249. package/build-module/utils/parse-css-unit-to-px.js +15 -9
  250. package/build-module/utils/parse-css-unit-to-px.js.map +1 -1
  251. package/build-style/style-rtl.css +32 -12
  252. package/build-style/style.css +32 -12
  253. package/package.json +31 -31
  254. package/src/components/block-draggable/content.scss +1 -1
  255. package/src/components/block-inspector/style.scss +3 -0
  256. package/src/components/block-list/block-html.js +1 -1
  257. package/src/components/block-list/block-invalid-warning.js +72 -64
  258. package/src/components/block-mover/test/__snapshots__/index.native.js.snap +20 -2
  259. package/src/components/block-preview/auto.js +2 -17
  260. package/src/components/block-preview/test/index.js +0 -2
  261. package/src/components/block-settings-menu-controls/index.js +2 -1
  262. package/src/components/block-styles/style.scss +2 -2
  263. package/src/components/block-switcher/block-transformations-menu.native.js +1 -0
  264. package/src/components/color-palette/test/__snapshots__/control.js.snap +16 -14
  265. package/src/components/colors-gradients/style.scss +8 -8
  266. package/src/components/convert-to-group-buttons/use-convert-to-group-button-props.js +48 -38
  267. package/src/components/editor-styles/index.js +29 -1
  268. package/src/components/global-styles/border-panel.js +285 -0
  269. package/src/components/global-styles/color-panel.js +706 -0
  270. package/src/components/global-styles/dimensions-panel.js +13 -42
  271. package/src/components/global-styles/get-block-css-selector.js +129 -0
  272. package/src/components/global-styles/hooks.js +154 -1
  273. package/src/components/global-styles/index.js +3 -0
  274. package/src/components/global-styles/test/use-global-styles-output.js +31 -2
  275. package/src/components/global-styles/typography-panel.js +67 -45
  276. package/src/components/global-styles/use-global-styles-output.js +176 -93
  277. package/src/components/global-styles/utils.js +3 -0
  278. package/src/components/image-size-control/index.js +4 -3
  279. package/src/components/image-size-control/test/index.js +2 -2
  280. package/src/components/inner-blocks/README.md +1 -1
  281. package/src/components/inserter/index.js +30 -11
  282. package/src/components/inserter/menu.js +0 -1
  283. package/src/components/inserter/quick-inserter.js +2 -0
  284. package/src/components/inserter/search-results.js +7 -1
  285. package/src/components/inserter/style.scss +3 -0
  286. package/src/components/inserter/tabs.js +1 -9
  287. package/src/components/inspector-controls-tabs/position-controls-panel.js +40 -9
  288. package/src/components/line-height-control/index.js +10 -1
  289. package/src/components/link-control/index.js +1 -1
  290. package/src/components/link-control/search-item.js +3 -1
  291. package/src/components/link-control/style.scss +0 -4
  292. package/src/components/link-control/test/index.js +0 -2
  293. package/src/components/list-view/appender.js +101 -0
  294. package/src/components/list-view/block.js +5 -4
  295. package/src/components/list-view/branch.js +30 -1
  296. package/src/components/list-view/index.js +43 -10
  297. package/src/components/list-view/style.scss +19 -0
  298. package/src/components/list-view/use-block-selection.js +0 -2
  299. package/src/components/media-replace-flow/index.js +36 -24
  300. package/src/components/media-replace-flow/style.scss +5 -2
  301. package/src/components/off-canvas-editor/appender.js +31 -5
  302. package/src/components/off-canvas-editor/branch.js +3 -1
  303. package/src/components/off-canvas-editor/index.js +7 -7
  304. package/src/components/off-canvas-editor/link-ui.js +0 -1
  305. package/src/components/provider/use-block-sync.js +21 -4
  306. package/src/components/rich-text/format-edit.js +2 -32
  307. package/src/components/rich-text/format-toolbar-container.js +1 -7
  308. package/src/components/url-popover/test/index.js +0 -2
  309. package/src/components/writing-flow/use-input.js +4 -5
  310. package/src/hooks/border.js +93 -225
  311. package/src/hooks/color.js +120 -296
  312. package/src/hooks/content-lock-ui.js +6 -2
  313. package/src/hooks/{color-panel.js → contrast-checker.js} +10 -46
  314. package/src/hooks/custom-class-name.js +4 -4
  315. package/src/hooks/custom-class-name.native.js +3 -4
  316. package/src/hooks/dimensions.js +0 -1
  317. package/src/hooks/duotone.js +8 -5
  318. package/src/hooks/layout.js +19 -16
  319. package/src/hooks/position.js +3 -3
  320. package/src/hooks/style.js +29 -28
  321. package/src/hooks/supports.js +6 -0
  322. package/src/hooks/test/style.js +2 -1
  323. package/src/hooks/test/use-typography-props.js +2 -0
  324. package/src/hooks/test/utils.js +0 -104
  325. package/src/hooks/typography.js +2 -1
  326. package/src/hooks/utils.js +63 -70
  327. package/src/layouts/constrained.js +23 -17
  328. package/src/layouts/grid.js +172 -0
  329. package/src/layouts/index.js +2 -1
  330. package/src/layouts/test/grid.js +21 -0
  331. package/src/private-apis.js +4 -0
  332. package/src/store/actions.js +10 -8
  333. package/src/store/selectors.js +20 -3
  334. package/src/utils/object.js +69 -0
  335. package/src/utils/parse-css-unit-to-px.js +14 -9
  336. package/src/utils/test/object.js +107 -0
  337. package/src/utils/test/parse-css-unit-to-px.js +1 -2
  338. package/tsconfig.tsbuildinfo +1 -1
  339. package/build/hooks/border-radius.js +0 -100
  340. package/build/hooks/border-radius.js.map +0 -1
  341. package/build/hooks/color-panel.js.map +0 -1
  342. package/build-module/hooks/border-radius.js +0 -84
  343. package/build-module/hooks/border-radius.js.map +0 -1
  344. package/build-module/hooks/color-panel.js.map +0 -1
  345. package/src/hooks/border-radius.js +0 -70
@@ -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
@@ -5,6 +5,8 @@ import {
5
5
  PanelBody,
6
6
  __experimentalUseSlotFills as useSlotFills,
7
7
  } from '@wordpress/components';
8
+ import { useSelect } from '@wordpress/data';
9
+ import { useLayoutEffect, useState } from '@wordpress/element';
8
10
  import { __ } from '@wordpress/i18n';
9
11
 
10
12
  /**
@@ -12,26 +14,55 @@ import { __ } from '@wordpress/i18n';
12
14
  */
13
15
  import InspectorControlsGroups from '../inspector-controls/groups';
14
16
  import { default as InspectorControls } from '../inspector-controls';
17
+ import { store as blockEditorStore } from '../../store';
15
18
 
16
- const PositionControls = () => {
17
- const fills = useSlotFills(
18
- InspectorControlsGroups.position.Slot.__unstableName
19
- );
20
- const hasFills = Boolean( fills && fills.length );
19
+ const PositionControlsPanel = () => {
20
+ const [ initialOpen, setInitialOpen ] = useState();
21
21
 
22
- if ( ! hasFills ) {
23
- return null;
24
- }
22
+ // Determine whether the panel should be expanded.
23
+ const { multiSelectedBlocks } = useSelect( ( select ) => {
24
+ const { getBlocksByClientId, getSelectedBlockClientIds } =
25
+ select( blockEditorStore );
26
+ const clientIds = getSelectedBlockClientIds();
27
+ return {
28
+ multiSelectedBlocks: getBlocksByClientId( clientIds ),
29
+ };
30
+ }, [] );
31
+
32
+ useLayoutEffect( () => {
33
+ // If any selected block has a position set, open the panel by default.
34
+ // The first block's value will still be used within the control though.
35
+ if ( initialOpen === undefined ) {
36
+ setInitialOpen(
37
+ multiSelectedBlocks.some(
38
+ ( { attributes } ) => !! attributes?.style?.position?.type
39
+ )
40
+ );
41
+ }
42
+ }, [ initialOpen, multiSelectedBlocks, setInitialOpen ] );
25
43
 
26
44
  return (
27
45
  <PanelBody
28
46
  className="block-editor-block-inspector__position"
29
47
  title={ __( 'Position' ) }
30
- initialOpen={ false }
48
+ initialOpen={ initialOpen ?? false }
31
49
  >
32
50
  <InspectorControls.Slot group="position" />
33
51
  </PanelBody>
34
52
  );
35
53
  };
36
54
 
55
+ const PositionControls = () => {
56
+ const fills = useSlotFills(
57
+ InspectorControlsGroups.position.Slot.__unstableName
58
+ );
59
+ const hasFills = Boolean( fills && fills.length );
60
+
61
+ if ( ! hasFills ) {
62
+ return null;
63
+ }
64
+
65
+ return <PositionControlsPanel />;
66
+ };
67
+
37
68
  export default PositionControls;
@@ -84,6 +84,15 @@ const LineHeightControl = ( {
84
84
  ? undefined
85
85
  : { marginBottom: 24 };
86
86
 
87
+ const handleOnChange = ( nextValue, { event } ) => {
88
+ if ( event.type === 'click' ) {
89
+ onChange( adjustNextValue( nextValue, false ) );
90
+ return;
91
+ }
92
+
93
+ onChange( nextValue );
94
+ };
95
+
87
96
  return (
88
97
  <div
89
98
  className="block-editor-line-height-control"
@@ -93,7 +102,7 @@ const LineHeightControl = ( {
93
102
  { ...otherProps }
94
103
  __unstableInputWidth={ __unstableInputWidth }
95
104
  __unstableStateReducer={ stateReducer }
96
- onChange={ onChange }
105
+ onChange={ handleOnChange }
97
106
  label={ __( 'Line height' ) }
98
107
  placeholder={ BASE_DEFAULT_VALUE }
99
108
  step={ STEP }
@@ -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 ),
@@ -0,0 +1,101 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useInstanceId } from '@wordpress/compose';
5
+ import { speak } from '@wordpress/a11y';
6
+ import { useSelect } from '@wordpress/data';
7
+ import { forwardRef, useState, useEffect } from '@wordpress/element';
8
+ import { __, sprintf } from '@wordpress/i18n';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { store as blockEditorStore } from '../../store';
14
+ import useBlockDisplayTitle from '../block-title/use-block-display-title';
15
+ import Inserter from '../inserter';
16
+
17
+ export const Appender = forwardRef(
18
+ ( { nestingLevel, blockCount, clientId, ...props }, ref ) => {
19
+ const [ insertedBlock, setInsertedBlock ] = useState( null );
20
+
21
+ const instanceId = useInstanceId( Appender );
22
+ const { hideInserter } = useSelect(
23
+ ( select ) => {
24
+ const { getTemplateLock, __unstableGetEditorMode } =
25
+ select( blockEditorStore );
26
+
27
+ return {
28
+ hideInserter:
29
+ !! getTemplateLock( clientId ) ||
30
+ __unstableGetEditorMode() === 'zoom-out',
31
+ };
32
+ },
33
+ [ clientId ]
34
+ );
35
+
36
+ const blockTitle = useBlockDisplayTitle( {
37
+ clientId,
38
+ context: 'list-view',
39
+ } );
40
+
41
+ const insertedBlockTitle = useBlockDisplayTitle( {
42
+ clientId: insertedBlock?.clientId,
43
+ context: 'list-view',
44
+ } );
45
+
46
+ useEffect( () => {
47
+ if ( ! insertedBlockTitle?.length ) {
48
+ return;
49
+ }
50
+
51
+ speak(
52
+ sprintf(
53
+ // translators: %s: name of block being inserted (i.e. Paragraph, Image, Group etc)
54
+ __( '%s block inserted' ),
55
+ insertedBlockTitle
56
+ ),
57
+ 'assertive'
58
+ );
59
+ }, [ insertedBlockTitle ] );
60
+
61
+ if ( hideInserter ) {
62
+ return null;
63
+ }
64
+
65
+ const descriptionId = `list-view-appender__${ instanceId }`;
66
+ const description = sprintf(
67
+ /* translators: 1: The name of the block. 2: The numerical position of the block. 3: The level of nesting for the block. */
68
+ __( 'Append to %1$s block at position %2$d, Level %3$d' ),
69
+ blockTitle,
70
+ blockCount + 1,
71
+ nestingLevel
72
+ );
73
+
74
+ return (
75
+ <div className="list-view-appender">
76
+ <Inserter
77
+ ref={ ref }
78
+ rootClientId={ clientId }
79
+ position="bottom right"
80
+ isAppender
81
+ selectBlockOnInsert={ false }
82
+ shouldDirectInsert={ false }
83
+ __experimentalIsQuick
84
+ { ...props }
85
+ toggleProps={ { 'aria-describedby': descriptionId } }
86
+ onSelectOrClose={ ( maybeInsertedBlock ) => {
87
+ if ( maybeInsertedBlock?.clientId ) {
88
+ setInsertedBlock( maybeInsertedBlock );
89
+ }
90
+ } }
91
+ />
92
+ <div
93
+ className="list-view-appender__description"
94
+ id={ descriptionId }
95
+ >
96
+ { description }
97
+ </div>
98
+ </div>
99
+ );
100
+ }
101
+ );
@@ -33,7 +33,6 @@ import {
33
33
  BlockMoverDownButton,
34
34
  } from '../block-mover/button';
35
35
  import ListViewBlockContents from './block-contents';
36
- import BlockSettingsDropdown from '../block-settings-menu/block-settings-dropdown';
37
36
  import { useListViewContext } from './context';
38
37
  import { getBlockPositionDescription } from './utils';
39
38
  import { store as blockEditorStore } from '../../store';
@@ -135,7 +134,8 @@ function ListViewBlock( {
135
134
  )
136
135
  : __( 'Options' );
137
136
 
138
- const { isTreeGridMounted, expand, collapse } = useListViewContext();
137
+ const { isTreeGridMounted, expand, collapse, BlockSettingsMenu } =
138
+ useListViewContext();
139
139
 
140
140
  const hasSiblings = siblingBlockCount > 0;
141
141
  const hasRenderedMovers = showBlockMovers && hasSiblings;
@@ -321,14 +321,15 @@ function ListViewBlock( {
321
321
  </>
322
322
  ) }
323
323
 
324
- { showBlockActions && (
324
+ { showBlockActions && BlockSettingsMenu && (
325
325
  <TreeGridCell
326
326
  className={ listViewBlockSettingsClassName }
327
327
  aria-selected={ !! isSelected || forceSelectionContentLock }
328
328
  >
329
329
  { ( { ref, tabIndex, onFocus } ) => (
330
- <BlockSettingsDropdown
330
+ <BlockSettingsMenu
331
331
  clientIds={ dropdownClientIds }
332
+ block={ block }
332
333
  icon={ moreVertical }
333
334
  label={ settingsAriaLabel }
334
335
  toggleProps={ {
@@ -1,12 +1,17 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
+ import {
5
+ __experimentalTreeGridRow as TreeGridRow,
6
+ __experimentalTreeGridCell as TreeGridCell,
7
+ } from '@wordpress/components';
4
8
  import { memo } from '@wordpress/element';
5
9
  import { AsyncModeProvider, useSelect } from '@wordpress/data';
6
10
 
7
11
  /**
8
12
  * Internal dependencies
9
13
  */
14
+ import { Appender } from './appender';
10
15
  import ListViewBlock from './block';
11
16
  import { useListViewContext } from './context';
12
17
  import { isClientIdSelected } from './utils';
@@ -93,6 +98,7 @@ function ListViewBranch( props ) {
93
98
  parentId,
94
99
  shouldShowInnerBlocks = true,
95
100
  isSyncedBranch = false,
101
+ showAppender: showAppenderProp = true,
96
102
  } = props;
97
103
 
98
104
  const parentBlockInformation = useBlockDisplayInformation( parentId );
@@ -120,8 +126,12 @@ function ListViewBranch( props ) {
120
126
  return null;
121
127
  }
122
128
 
129
+ // Only show the appender at the first level.
130
+ const showAppender = showAppenderProp && level === 1;
123
131
  const filteredBlocks = blocks.filter( Boolean );
124
132
  const blockCount = filteredBlocks.length;
133
+ // The appender means an extra row in List View, so add 1 to the row count.
134
+ const rowCount = showAppender ? blockCount + 1 : blockCount;
125
135
  let nextPosition = listPosition;
126
136
 
127
137
  return (
@@ -175,7 +185,7 @@ function ListViewBranch( props ) {
175
185
  isDragged={ isDragged }
176
186
  level={ level }
177
187
  position={ position }
178
- rowCount={ blockCount }
188
+ rowCount={ rowCount }
179
189
  siblingBlockCount={ blockCount }
180
190
  showBlockMovers={ showBlockMovers }
181
191
  path={ updatedPath }
@@ -209,6 +219,25 @@ function ListViewBranch( props ) {
209
219
  </AsyncModeProvider>
210
220
  );
211
221
  } ) }
222
+ { showAppender && (
223
+ <TreeGridRow
224
+ level={ level }
225
+ setSize={ rowCount }
226
+ positionInSet={ rowCount }
227
+ isExpanded={ true }
228
+ >
229
+ <TreeGridCell>
230
+ { ( treeGridCellProps ) => (
231
+ <Appender
232
+ clientId={ parentId }
233
+ nestingLevel={ level }
234
+ blockCount={ blockCount }
235
+ { ...treeGridCellProps }
236
+ />
237
+ ) }
238
+ </TreeGridCell>
239
+ </TreeGridRow>
240
+ ) }
212
241
  </>
213
242
  );
214
243
  }
@@ -28,6 +28,7 @@ import useListViewClientIds from './use-list-view-client-ids';
28
28
  import useListViewDropZone from './use-list-view-drop-zone';
29
29
  import useListViewExpandSelectedItem from './use-list-view-expand-selected-item';
30
30
  import { store as blockEditorStore } from '../../store';
31
+ import { BlockSettingsDropdown } from '../block-settings-menu/block-settings-dropdown';
31
32
 
32
33
  const expanded = ( state, action ) => {
33
34
  if ( Array.isArray( action.clientIds ) ) {
@@ -47,18 +48,30 @@ const expanded = ( state, action ) => {
47
48
 
48
49
  export const BLOCK_LIST_ITEM_HEIGHT = 36;
49
50
 
51
+ /** @typedef {import('react').ComponentType} ComponentType */
52
+ /** @typedef {import('react').Ref<HTMLElement>} Ref */
53
+
50
54
  /**
51
55
  * Show a hierarchical list of blocks.
52
56
  *
53
- * @param {Object} props Components props.
54
- * @param {string} props.id An HTML element id for the root element of ListView.
55
- * @param {Array} props.blocks Custom subset of block client IDs to be used instead of the default hierarchy.
56
- * @param {boolean} props.showBlockMovers Flag to enable block movers
57
- * @param {boolean} props.isExpanded Flag to determine whether nested levels are expanded by default.
58
- * @param {Object} ref Forwarded ref
57
+ * @param {Object} props Components props.
58
+ * @param {string} props.id An HTML element id for the root element of ListView.
59
+ * @param {Array} props.blocks Custom subset of block client IDs to be used instead of the default hierarchy.
60
+ * @param {?boolean} props.showBlockMovers Flag to enable block movers. Defaults to `false`.
61
+ * @param {?boolean} props.isExpanded Flag to determine whether nested levels are expanded by default. Defaults to `false`.
62
+ * @param {?boolean} props.showAppender Flag to show or hide the block appender. Defaults to `false`.
63
+ * @param {?ComponentType} props.blockSettingsMenu Optional more menu substitution. Defaults to the standard `BlockSettingsDropdown` component.
64
+ * @param {Ref} ref Forwarded ref
59
65
  */
60
- function ListView(
61
- { id, blocks, showBlockMovers = false, isExpanded = false },
66
+ function ListViewComponent(
67
+ {
68
+ id,
69
+ blocks,
70
+ showBlockMovers = false,
71
+ isExpanded = false,
72
+ showAppender = false,
73
+ blockSettingsMenu: BlockSettingsMenu = BlockSettingsDropdown,
74
+ },
62
75
  ref
63
76
  ) {
64
77
  const { clientIdsTree, draggedClientIds, selectedClientIds } =
@@ -170,8 +183,16 @@ function ListView(
170
183
  expandedState,
171
184
  expand,
172
185
  collapse,
186
+ BlockSettingsMenu,
173
187
  } ),
174
- [ isMounted.current, draggedClientIds, expandedState, expand, collapse ]
188
+ [
189
+ isMounted.current,
190
+ draggedClientIds,
191
+ expandedState,
192
+ expand,
193
+ collapse,
194
+ BlockSettingsMenu,
195
+ ]
175
196
  );
176
197
 
177
198
  // If there are no blocks to show, do not render the list view.
@@ -204,10 +225,22 @@ function ListView(
204
225
  selectedClientIds={ selectedClientIds }
205
226
  isExpanded={ isExpanded }
206
227
  shouldShowInnerBlocks={ shouldShowInnerBlocks }
228
+ showAppender={ showAppender }
207
229
  />
208
230
  </ListViewContext.Provider>
209
231
  </TreeGrid>
210
232
  </AsyncModeProvider>
211
233
  );
212
234
  }
213
- export default forwardRef( ListView );
235
+ export const PrivateListView = forwardRef( ListViewComponent );
236
+
237
+ export default forwardRef( ( props, ref ) => {
238
+ return (
239
+ <PrivateListView
240
+ ref={ ref }
241
+ { ...props }
242
+ showAppender={ false }
243
+ blockSettingsMenu={ BlockSettingsDropdown }
244
+ />
245
+ );
246
+ } );
@@ -410,3 +410,22 @@ $block-navigation-max-indent: 8;
410
410
  height: 36px;
411
411
  }
412
412
 
413
+ .list-view-appender .block-editor-inserter__toggle {
414
+ background-color: #1e1e1e;
415
+ color: #fff;
416
+ margin: $grid-unit-10 0 0 24px;
417
+ border-radius: 2px;
418
+ height: 24px;
419
+ min-width: 24px;
420
+ padding: 0;
421
+
422
+ &:hover,
423
+ &:focus {
424
+ background: var(--wp-admin-theme-color);
425
+ color: #fff;
426
+ }
427
+ }
428
+
429
+ .list-view-appender__description {
430
+ display: none;
431
+ }
@@ -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,