@wordpress/block-editor 16.2.0 → 17.0.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 (328) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/build/components/block-inspector/index.cjs +9 -6
  3. package/build/components/block-inspector/index.cjs.map +2 -2
  4. package/build/components/block-keyboard-shortcuts/index.cjs +201 -0
  5. package/build/components/block-keyboard-shortcuts/index.cjs.map +7 -0
  6. package/build/components/block-list/block.cjs +10 -3
  7. package/build/components/block-list/block.cjs.map +2 -2
  8. package/build/components/block-list/index.cjs +6 -1
  9. package/build/components/block-list/index.cjs.map +2 -2
  10. package/build/components/block-list/use-block-props/use-focus-first-element.cjs +4 -0
  11. package/build/components/block-list/use-block-props/use-focus-first-element.cjs.map +2 -2
  12. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs +6 -7
  13. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs.map +2 -2
  14. package/build/components/block-parent-selector/index.cjs +98 -29
  15. package/build/components/block-parent-selector/index.cjs.map +3 -3
  16. package/build/components/block-popover/inbetween.cjs +2 -2
  17. package/build/components/block-popover/inbetween.cjs.map +2 -2
  18. package/build/components/block-preview/index.cjs +0 -4
  19. package/build/components/block-preview/index.cjs.map +2 -2
  20. package/build/components/block-styles/index.cjs +77 -33
  21. package/build/components/block-styles/index.cjs.map +3 -3
  22. package/build/components/block-visibility/constants.cjs.map +2 -2
  23. package/build/components/child-layout-control/index.cjs.map +2 -2
  24. package/build/components/colors/with-colors.cjs +55 -71
  25. package/build/components/colors/with-colors.cjs.map +2 -2
  26. package/build/components/dimensions-tool/aspect-ratio-tool.cjs +4 -2
  27. package/build/components/dimensions-tool/aspect-ratio-tool.cjs.map +2 -2
  28. package/build/components/dimensions-tool/index.cjs +18 -16
  29. package/build/components/dimensions-tool/index.cjs.map +2 -2
  30. package/build/components/dimensions-tool/utils.cjs +61 -0
  31. package/build/components/dimensions-tool/utils.cjs.map +7 -0
  32. package/build/components/duotone-control/index.cjs +2 -0
  33. package/build/components/duotone-control/index.cjs.map +2 -2
  34. package/build/components/global-styles/advanced-panel.cjs.map +3 -3
  35. package/build/components/global-styles/border-panel.cjs +2 -5
  36. package/build/components/global-styles/border-panel.cjs.map +2 -2
  37. package/build/components/global-styles/color-panel.cjs +14 -2
  38. package/build/components/global-styles/color-panel.cjs.map +2 -2
  39. package/build/components/global-styles/dimensions-panel.cjs +9 -5
  40. package/build/components/global-styles/dimensions-panel.cjs.map +2 -2
  41. package/build/components/global-styles/filters-panel.cjs +12 -8
  42. package/build/components/global-styles/filters-panel.cjs.map +2 -2
  43. package/build/components/global-styles/shadow-panel-components.cjs +16 -11
  44. package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
  45. package/build/components/global-styles/utils.cjs +9 -0
  46. package/build/components/global-styles/utils.cjs.map +2 -2
  47. package/build/components/inner-blocks/index.cjs +5 -3
  48. package/build/components/inner-blocks/index.cjs.map +2 -2
  49. package/build/components/inserter/block-patterns-explorer/index.cjs +39 -22
  50. package/build/components/inserter/block-patterns-explorer/index.cjs.map +2 -2
  51. package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.cjs +21 -55
  52. package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.cjs.map +2 -2
  53. package/build/components/inserter/block-patterns-explorer/pattern-list.cjs +19 -44
  54. package/build/components/inserter/block-patterns-explorer/pattern-list.cjs.map +3 -3
  55. package/build/components/inserter/hooks/use-insertion-point.cjs +4 -4
  56. package/build/components/inserter/hooks/use-insertion-point.cjs.map +2 -2
  57. package/build/components/inserter/menu.cjs +18 -7
  58. package/build/components/inserter/menu.cjs.map +2 -2
  59. package/build/components/inserter/quick-inserter.cjs +30 -27
  60. package/build/components/inserter/quick-inserter.cjs.map +2 -2
  61. package/build/components/inspector-controls-tabs/styles-tab.cjs +1 -1
  62. package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
  63. package/build/components/list-view/index.cjs +31 -5
  64. package/build/components/list-view/index.cjs.map +3 -3
  65. package/build/components/list-view/utils.cjs +13 -1
  66. package/build/components/list-view/utils.cjs.map +2 -2
  67. package/build/components/media-placeholder/index.cjs +1 -1
  68. package/build/components/media-placeholder/index.cjs.map +3 -3
  69. package/build/components/provider/index.cjs +5 -1
  70. package/build/components/provider/index.cjs.map +3 -3
  71. package/build/components/publish-date-time-picker/index.cjs +3 -2
  72. package/build/components/publish-date-time-picker/index.cjs.map +2 -2
  73. package/build/components/rich-text/event-listeners/enter.cjs +46 -39
  74. package/build/components/rich-text/event-listeners/enter.cjs.map +2 -2
  75. package/build/components/rich-text/index.cjs +7 -5
  76. package/build/components/rich-text/index.cjs.map +2 -2
  77. package/build/components/rich-text/multiline.cjs +105 -70
  78. package/build/components/rich-text/multiline.cjs.map +3 -3
  79. package/build/components/url-input/index.cjs.map +2 -2
  80. package/build/components/writing-flow/use-input.cjs +65 -13
  81. package/build/components/writing-flow/use-input.cjs.map +3 -3
  82. package/build/hooks/border.cjs +25 -3
  83. package/build/hooks/border.cjs.map +2 -2
  84. package/build/hooks/dimensions.cjs +9 -2
  85. package/build/hooks/dimensions.cjs.map +2 -2
  86. package/build/hooks/duotone.cjs +4 -3
  87. package/build/hooks/duotone.cjs.map +2 -2
  88. package/build/hooks/gap.cjs +8 -2
  89. package/build/hooks/gap.cjs.map +2 -2
  90. package/build/hooks/layout-child.cjs +35 -13
  91. package/build/hooks/layout-child.cjs.map +2 -2
  92. package/build/hooks/layout.cjs +23 -1
  93. package/build/hooks/layout.cjs.map +2 -2
  94. package/build/hooks/states.cjs +7 -4
  95. package/build/hooks/states.cjs.map +2 -2
  96. package/build/layouts/constrained.cjs +8 -1
  97. package/build/layouts/constrained.cjs.map +2 -2
  98. package/build/layouts/flex.cjs +9 -0
  99. package/build/layouts/flex.cjs.map +2 -2
  100. package/build/layouts/flow.cjs +4 -1
  101. package/build/layouts/flow.cjs.map +2 -2
  102. package/build/layouts/grid.cjs +5 -1
  103. package/build/layouts/grid.cjs.map +2 -2
  104. package/build/private-apis.cjs +3 -1
  105. package/build/private-apis.cjs.map +2 -2
  106. package/build/store/actions.cjs +1 -1
  107. package/build/store/actions.cjs.map +2 -2
  108. package/build-module/components/block-inspector/index.mjs +9 -6
  109. package/build-module/components/block-inspector/index.mjs.map +2 -2
  110. package/build-module/components/block-keyboard-shortcuts/index.mjs +173 -0
  111. package/build-module/components/block-keyboard-shortcuts/index.mjs.map +7 -0
  112. package/build-module/components/block-list/block.mjs +10 -3
  113. package/build-module/components/block-list/block.mjs.map +2 -2
  114. package/build-module/components/block-list/index.mjs +6 -1
  115. package/build-module/components/block-list/index.mjs.map +2 -2
  116. package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs +4 -0
  117. package/build-module/components/block-list/use-block-props/use-focus-first-element.mjs.map +2 -2
  118. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs +6 -7
  119. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs.map +2 -2
  120. package/build-module/components/block-parent-selector/index.mjs +101 -32
  121. package/build-module/components/block-parent-selector/index.mjs.map +2 -2
  122. package/build-module/components/block-popover/inbetween.mjs +2 -2
  123. package/build-module/components/block-popover/inbetween.mjs.map +2 -2
  124. package/build-module/components/block-preview/index.mjs +0 -4
  125. package/build-module/components/block-preview/index.mjs.map +2 -2
  126. package/build-module/components/block-styles/index.mjs +79 -35
  127. package/build-module/components/block-styles/index.mjs.map +2 -2
  128. package/build-module/components/block-visibility/constants.mjs.map +2 -2
  129. package/build-module/components/child-layout-control/index.mjs +5 -5
  130. package/build-module/components/child-layout-control/index.mjs.map +1 -1
  131. package/build-module/components/colors/with-colors.mjs +56 -72
  132. package/build-module/components/colors/with-colors.mjs.map +2 -2
  133. package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs +4 -2
  134. package/build-module/components/dimensions-tool/aspect-ratio-tool.mjs.map +2 -2
  135. package/build-module/components/dimensions-tool/index.mjs +19 -17
  136. package/build-module/components/dimensions-tool/index.mjs.map +2 -2
  137. package/build-module/components/dimensions-tool/utils.mjs +35 -0
  138. package/build-module/components/dimensions-tool/utils.mjs.map +7 -0
  139. package/build-module/components/duotone-control/index.mjs +2 -0
  140. package/build-module/components/duotone-control/index.mjs.map +2 -2
  141. package/build-module/components/global-styles/advanced-panel.mjs +5 -2
  142. package/build-module/components/global-styles/advanced-panel.mjs.map +2 -2
  143. package/build-module/components/global-styles/border-panel.mjs +2 -5
  144. package/build-module/components/global-styles/border-panel.mjs.map +2 -2
  145. package/build-module/components/global-styles/color-panel.mjs +14 -2
  146. package/build-module/components/global-styles/color-panel.mjs.map +2 -2
  147. package/build-module/components/global-styles/dimensions-panel.mjs +9 -5
  148. package/build-module/components/global-styles/dimensions-panel.mjs.map +2 -2
  149. package/build-module/components/global-styles/filters-panel.mjs +16 -9
  150. package/build-module/components/global-styles/filters-panel.mjs.map +2 -2
  151. package/build-module/components/global-styles/shadow-panel-components.mjs +16 -11
  152. package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
  153. package/build-module/components/global-styles/utils.mjs +8 -0
  154. package/build-module/components/global-styles/utils.mjs.map +2 -2
  155. package/build-module/components/inner-blocks/index.mjs +5 -3
  156. package/build-module/components/inner-blocks/index.mjs.map +2 -2
  157. package/build-module/components/inserter/block-patterns-explorer/index.mjs +39 -22
  158. package/build-module/components/inserter/block-patterns-explorer/index.mjs.map +2 -2
  159. package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.mjs +22 -56
  160. package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.mjs.map +2 -2
  161. package/build-module/components/inserter/block-patterns-explorer/pattern-list.mjs +20 -45
  162. package/build-module/components/inserter/block-patterns-explorer/pattern-list.mjs.map +2 -2
  163. package/build-module/components/inserter/hooks/use-insertion-point.mjs +4 -4
  164. package/build-module/components/inserter/hooks/use-insertion-point.mjs.map +2 -2
  165. package/build-module/components/inserter/menu.mjs +19 -8
  166. package/build-module/components/inserter/menu.mjs.map +2 -2
  167. package/build-module/components/inserter/quick-inserter.mjs +30 -27
  168. package/build-module/components/inserter/quick-inserter.mjs.map +2 -2
  169. package/build-module/components/inspector-controls-tabs/styles-tab.mjs +1 -1
  170. package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
  171. package/build-module/components/list-view/index.mjs +32 -5
  172. package/build-module/components/list-view/index.mjs.map +3 -3
  173. package/build-module/components/list-view/utils.mjs +13 -1
  174. package/build-module/components/list-view/utils.mjs.map +2 -2
  175. package/build-module/components/media-placeholder/index.mjs +3 -3
  176. package/build-module/components/media-placeholder/index.mjs.map +2 -2
  177. package/build-module/components/provider/index.mjs +6 -2
  178. package/build-module/components/provider/index.mjs.map +2 -2
  179. package/build-module/components/publish-date-time-picker/index.mjs +3 -2
  180. package/build-module/components/publish-date-time-picker/index.mjs.map +2 -2
  181. package/build-module/components/rich-text/event-listeners/enter.mjs +46 -39
  182. package/build-module/components/rich-text/event-listeners/enter.mjs.map +2 -2
  183. package/build-module/components/rich-text/index.mjs +7 -5
  184. package/build-module/components/rich-text/index.mjs.map +2 -2
  185. package/build-module/components/rich-text/multiline.mjs +112 -72
  186. package/build-module/components/rich-text/multiline.mjs.map +2 -2
  187. package/build-module/components/url-input/index.mjs +2 -2
  188. package/build-module/components/url-input/index.mjs.map +1 -1
  189. package/build-module/components/writing-flow/use-input.mjs +66 -14
  190. package/build-module/components/writing-flow/use-input.mjs.map +3 -3
  191. package/build-module/hooks/border.mjs +26 -8
  192. package/build-module/hooks/border.mjs.map +2 -2
  193. package/build-module/hooks/dimensions.mjs +9 -2
  194. package/build-module/hooks/dimensions.mjs.map +2 -2
  195. package/build-module/hooks/duotone.mjs +8 -4
  196. package/build-module/hooks/duotone.mjs.map +2 -2
  197. package/build-module/hooks/gap.mjs +6 -1
  198. package/build-module/hooks/gap.mjs.map +2 -2
  199. package/build-module/hooks/layout-child.mjs +36 -13
  200. package/build-module/hooks/layout-child.mjs.map +2 -2
  201. package/build-module/hooks/layout.mjs +22 -1
  202. package/build-module/hooks/layout.mjs.map +2 -2
  203. package/build-module/hooks/states.mjs +8 -5
  204. package/build-module/hooks/states.mjs.map +2 -2
  205. package/build-module/layouts/constrained.mjs +8 -1
  206. package/build-module/layouts/constrained.mjs.map +2 -2
  207. package/build-module/layouts/flex.mjs +9 -0
  208. package/build-module/layouts/flex.mjs.map +2 -2
  209. package/build-module/layouts/flow.mjs +4 -1
  210. package/build-module/layouts/flow.mjs.map +2 -2
  211. package/build-module/layouts/grid.mjs +5 -1
  212. package/build-module/layouts/grid.mjs.map +2 -2
  213. package/build-module/private-apis.mjs +3 -1
  214. package/build-module/private-apis.mjs.map +2 -2
  215. package/build-module/store/actions.mjs +1 -1
  216. package/build-module/store/actions.mjs.map +2 -2
  217. package/build-style/style-rtl.css +108 -71
  218. package/build-style/style.css +108 -71
  219. package/build-types/components/block-visibility/constants.d.ts +4 -3
  220. package/build-types/components/block-visibility/constants.d.ts.map +1 -1
  221. package/package.json +43 -43
  222. package/src/components/background-image-control/README.md +122 -0
  223. package/src/components/block-edit-visually-button/README.md +39 -0
  224. package/src/components/block-editing-mode/README.md +72 -0
  225. package/src/components/block-inspector/index.js +6 -6
  226. package/src/components/block-keyboard-shortcuts/index.js +256 -0
  227. package/src/components/block-list/block.js +7 -0
  228. package/src/components/block-list/index.js +7 -1
  229. package/src/components/block-list/use-block-props/use-focus-first-element.js +5 -0
  230. package/src/components/block-list/use-block-props/use-selected-block-event-handlers.js +6 -8
  231. package/src/components/block-parent-selector/index.js +111 -30
  232. package/src/components/block-popover/README.md +10 -3
  233. package/src/components/block-popover/inbetween.js +8 -2
  234. package/src/components/block-popover/stories/index.story.jsx +143 -0
  235. package/src/components/block-preview/index.js +0 -2
  236. package/src/components/block-styles/index.js +95 -43
  237. package/src/components/block-styles/style.scss +5 -34
  238. package/src/components/block-tools/style.scss +94 -0
  239. package/src/components/block-visibility/constants.ts +4 -3
  240. package/src/components/child-layout-control/index.js +5 -5
  241. package/src/components/color-palette/test/__snapshots__/control.js.snap +3 -29
  242. package/src/components/colors/test/with-colors.js +6 -7
  243. package/src/components/colors/with-colors.js +79 -105
  244. package/src/components/dimensions-tool/aspect-ratio-tool.js +16 -4
  245. package/src/components/dimensions-tool/index.js +34 -22
  246. package/src/components/dimensions-tool/test/index.js +166 -2
  247. package/src/components/dimensions-tool/test/utils.js +51 -0
  248. package/src/components/dimensions-tool/utils.js +67 -0
  249. package/src/components/duotone-control/index.js +2 -0
  250. package/src/components/duotone-control/test/index.js +100 -0
  251. package/src/components/global-styles/advanced-panel.js +5 -2
  252. package/src/components/global-styles/border-panel.js +11 -9
  253. package/src/components/global-styles/color-panel.js +13 -1
  254. package/src/components/global-styles/dimensions-panel.js +17 -5
  255. package/src/components/global-styles/filters-panel.js +24 -10
  256. package/src/components/global-styles/shadow-panel-components.js +38 -11
  257. package/src/components/global-styles/test/border-panel.js +230 -0
  258. package/src/components/global-styles/test/color-panel.js +24 -0
  259. package/src/components/global-styles/test/dimensions-panel.js +98 -7
  260. package/src/components/global-styles/test/filters-panel.js +84 -0
  261. package/src/components/global-styles/test/utils.js +30 -0
  262. package/src/components/global-styles/utils.js +23 -0
  263. package/src/components/inner-blocks/index.js +11 -2
  264. package/src/components/inner-blocks/stories/index.story.jsx +246 -0
  265. package/src/components/inserter/block-patterns-explorer/index.js +24 -11
  266. package/src/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js +18 -56
  267. package/src/components/inserter/block-patterns-explorer/pattern-list.js +22 -47
  268. package/src/components/inserter/hooks/use-insertion-point.js +9 -4
  269. package/src/components/inserter/menu.js +23 -10
  270. package/src/components/inserter/quick-inserter.js +15 -13
  271. package/src/components/inserter/style.scss +44 -62
  272. package/src/components/inspector-controls-tabs/README.md +92 -0
  273. package/src/components/inspector-controls-tabs/styles-tab.js +1 -1
  274. package/src/components/link-control/test/index.js +5 -0
  275. package/src/components/list-view/index.js +50 -7
  276. package/src/components/list-view/utils.js +16 -1
  277. package/src/components/media-placeholder/index.js +9 -4
  278. package/src/components/plain-text/stories/index.story.jsx +3 -0
  279. package/src/components/provider/index.js +7 -1
  280. package/src/components/publish-date-time-picker/README.md +10 -0
  281. package/src/components/publish-date-time-picker/index.js +17 -14
  282. package/src/components/rich-text/event-listeners/enter.js +58 -45
  283. package/src/components/rich-text/index.js +9 -4
  284. package/src/components/rich-text/multiline.js +126 -86
  285. package/src/components/url-input/index.js +2 -2
  286. package/src/components/url-input/test/fixtures/validated-input-control-deprecation.js +27 -0
  287. package/src/components/url-input/test/index.js +5 -0
  288. package/src/components/url-popover/README.md +7 -0
  289. package/src/components/url-popover/stories/index.story.jsx +133 -47
  290. package/src/components/writing-flow/use-input.js +105 -15
  291. package/src/hooks/border.js +27 -8
  292. package/src/hooks/dimensions.js +8 -1
  293. package/src/hooks/duotone.js +23 -7
  294. package/src/hooks/gap.js +16 -0
  295. package/src/hooks/layout-child.js +41 -9
  296. package/src/hooks/layout.js +117 -71
  297. package/src/hooks/states.js +8 -5
  298. package/src/hooks/test/gap.js +31 -1
  299. package/src/hooks/test/layout-child.js +60 -1
  300. package/src/hooks/test/layout.js +27 -0
  301. package/src/layouts/constrained.js +9 -1
  302. package/src/layouts/flex.js +15 -0
  303. package/src/layouts/flow.js +4 -1
  304. package/src/layouts/grid.js +9 -1
  305. package/src/layouts/test/constrained.js +26 -0
  306. package/src/layouts/test/flow.js +26 -0
  307. package/src/layouts/test/grid.js +46 -0
  308. package/src/private-apis.js +2 -0
  309. package/src/store/actions.js +14 -1
  310. package/build/components/floating-toolbar/nav-up-icon.cjs +0 -52
  311. package/build/components/floating-toolbar/nav-up-icon.cjs.map +0 -7
  312. package/build/components/gradients/with-gradient.cjs +0 -36
  313. package/build/components/gradients/with-gradient.cjs.map +0 -7
  314. package/build/components/inserter-button/sparkles.cjs +0 -36
  315. package/build/components/inserter-button/sparkles.cjs.map +0 -7
  316. package/build-module/components/floating-toolbar/nav-up-icon.mjs +0 -31
  317. package/build-module/components/floating-toolbar/nav-up-icon.mjs.map +0 -7
  318. package/build-module/components/gradients/with-gradient.mjs +0 -11
  319. package/build-module/components/gradients/with-gradient.mjs.map +0 -7
  320. package/build-module/components/inserter-button/sparkles.mjs +0 -15
  321. package/build-module/components/inserter-button/sparkles.mjs.map +0 -7
  322. package/build-style/default-editor-styles-rtl.css +0 -68
  323. package/build-style/default-editor-styles.css +0 -68
  324. package/src/components/floating-toolbar/nav-up-icon.js +0 -22
  325. package/src/components/gradients/with-gradient.js +0 -9
  326. package/src/components/inserter-button/README.md +0 -62
  327. package/src/components/inserter-button/sparkles.js +0 -12
  328. package/src/default-editor-styles.scss +0 -25
@@ -0,0 +1,122 @@
1
+ # Background Image Control
2
+
3
+ The `BackgroundImageControl` component provides an interface for selecting, positioning, and configuring background images in the WordPress block editor.
4
+
5
+ _Note:_ This is an internal component. It is not exported from `@wordpress/block-editor` and is not part of the public API; it is rendered by the Global Styles [background panel](../global-styles/background-panel.js).
6
+
7
+ ## Features
8
+
9
+ - Upload or select a background image from the media library.
10
+ - Adjust background position using a focal point picker.
11
+ - Toggle background repeat and attachment properties.
12
+ - Set background size (cover, contain, auto, or custom units).
13
+ - Remove or replace the background image.
14
+ - Drag and drop image uploads.
15
+
16
+ ## Development guidelines
17
+
18
+ ### Usage
19
+
20
+ Renders the background image controls, to be used within a `ToolsPanelItem` in the block inspector.
21
+
22
+ ```jsx
23
+ import { useState } from 'react';
24
+ import {
25
+ __experimentalToolsPanel as ToolsPanel,
26
+ __experimentalToolsPanelItem as ToolsPanelItem,
27
+ } from '@wordpress/components';
28
+ import BackgroundImageControl from '../background-image-control';
29
+
30
+ const MyBackgroundImageControl = () => {
31
+ const [ style, setStyle ] = useState( {} );
32
+ return (
33
+ <ToolsPanel label={ 'Background' } panelId="my-panel">
34
+ <ToolsPanelItem
35
+ label={ 'Image' }
36
+ panelId="my-panel"
37
+ isShownByDefault
38
+ hasValue={ () => !! style?.background?.backgroundImage }
39
+ onDeselect={ () => setStyle( {} ) }
40
+ >
41
+ <BackgroundImageControl
42
+ value={ style }
43
+ onChange={ setStyle }
44
+ settings={ {
45
+ background: {
46
+ backgroundImage: true,
47
+ backgroundSize: true,
48
+ },
49
+ } }
50
+ />
51
+ </ToolsPanelItem>
52
+ </ToolsPanel>
53
+ );
54
+ };
55
+ ```
56
+
57
+ ### Props
58
+
59
+ #### `value`
60
+
61
+ - **Type:** `Object`
62
+
63
+ The style object the controls read from and write to. Background values live under the `background` key, for example `{ background: { backgroundImage: { url, id, title }, backgroundSize: 'cover' } }`.
64
+
65
+ #### `onChange`
66
+
67
+ - **Type:** `Function`
68
+
69
+ A callback that receives the updated style object whenever a background property changes.
70
+
71
+ #### `inheritedValue`
72
+
73
+ - **Type:** `Object`
74
+ - **Default:** the `value` prop
75
+
76
+ A style object with the values inherited from global styles, used as the fallback when `value` has none. `ref` pointers within it are resolved before use.
77
+
78
+ #### `settings`
79
+
80
+ - **Type:** `Object`
81
+
82
+ The theme settings object. The background size, position, and repeat controls are only rendered when at least one of `settings.background.backgroundSize`, `settings.background.backgroundPosition`, or `settings.background.backgroundRepeat` is enabled.
83
+
84
+ #### `defaultValues`
85
+
86
+ - **Type:** `Object`
87
+ - **Default:** `{}`
88
+
89
+ Default values for the background properties, used as placeholders when nothing is set.
90
+
91
+ #### `showInheritanceLabelIndicators`
92
+
93
+ - **Type:** `Boolean`
94
+ - **Default:** whether global styles inheritance is enabled
95
+
96
+ Whether to show the inherited-value label treatment, including the local-override affordance on the reset control.
97
+
98
+ ## Utility functions
99
+
100
+ ### `coordsToBackgroundPosition( value )`
101
+
102
+ Converts `FocalPointPicker` x/y values to a CSS `background-position` value.
103
+
104
+ ```js
105
+ coordsToBackgroundPosition( { x: 0.5, y: 0.5 } ); // '50% 50%'
106
+ coordsToBackgroundPosition( { x: 0.5 } ); // '50% 50%' — a missing coord falls back to 0.5
107
+ coordsToBackgroundPosition( undefined ); // undefined
108
+ ```
109
+
110
+ ### `backgroundPositionToCoords( value )`
111
+
112
+ Converts a CSS `background-position` value to `FocalPointPicker` coordinates.
113
+
114
+ ```js
115
+ backgroundPositionToCoords( '50% 50%' ); // { x: 0.5, y: 0.5 }
116
+ backgroundPositionToCoords( '50%' ); // { x: 0.5, y: 0.5 } — y falls back to x
117
+ backgroundPositionToCoords( undefined ); // { x: undefined, y: undefined }
118
+ ```
119
+
120
+ ## Related components
121
+
122
+ Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree.
@@ -0,0 +1,39 @@
1
+ # Block Edit Visually Button
2
+
3
+ `BlockEditVisuallyButton` renders the toolbar button that takes a block out of the HTML editor and back to the visual editor. It is the toolbar counterpart of the "Edit as HTML" / "Edit visually" item that [`BlockSettingsMenu`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-settings-menu/README.md) renders, and it exists so that a block being edited as HTML always offers a visible way back without opening the settings menu.
4
+
5
+ _Note:_ This component is internal to the block editor and is not exported from `@wordpress/block-editor`. It is rendered by [`BlockToolbar`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-toolbar/README.md); it is documented here for contributors working on the block toolbar rather than as public API.
6
+
7
+ ## Development guidelines
8
+
9
+ The button renders only when a single block is selected and that block's mode is `html`, so it is safe to render unconditionally alongside the rest of the toolbar: with a multi-block selection, or with a block in visual mode, it returns `null`. Clicking it dispatches `toggleBlockMode` for the selected block, which flips the mode back to `visual`.
10
+
11
+ Note that the two entry points are not gated the same way. The settings menu item is only rendered for a valid block that supports `html` editing while the `codeEditingEnabled` setting is on, whereas this button checks the block's mode alone. Whatever put the block into HTML mode, the toolbar button is there to bring it back.
12
+
13
+ ### Usage
14
+
15
+ ```jsx
16
+ import { ToolbarGroup } from '@wordpress/components';
17
+
18
+ function MyBlockToolbar( { clientIds } ) {
19
+ return (
20
+ <div className="my-block-toolbar">
21
+ <ToolbarGroup>{ /* Block controls. */ }</ToolbarGroup>
22
+ <BlockEditVisuallyButton clientIds={ clientIds } />
23
+ </div>
24
+ );
25
+ }
26
+ ```
27
+
28
+ ### Props
29
+
30
+ #### `clientIds`
31
+
32
+ - **Type:** `Array`
33
+ - **Required:** Yes
34
+
35
+ The client IDs of the currently selected blocks. The button renders only when the array contains exactly one client ID, since editing visually applies to a single block.
36
+
37
+ ## Related components
38
+
39
+ Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree.
@@ -0,0 +1,72 @@
1
+ # Block Editing Mode
2
+
3
+ `useBlockEditingMode` is a hook that reads, and optionally sets, the editing mode of a block. The mode restricts the user interface that is displayed for editing that block.
4
+
5
+ The mode can be set to one of the following values:
6
+
7
+ - `'disabled'`: Prevents editing the block entirely, i.e., it cannot be selected.
8
+ - `'contentOnly'`: Hides all non-content UI, such as auxiliary controls in the toolbar, block movers, and block settings.
9
+ - `'default'`: Allows editing the block as normal.
10
+
11
+ Modes don't cascade to inner blocks, with one exception: a block set to `'disabled'` also disables its inner blocks, unless an inner block has its own mode explicitly set.
12
+
13
+ If called outside of a block context, the mode is set on the editor root, which follows the same rule, so `'disabled'` applies to every block, while `'contentOnly'` does not.
14
+
15
+ A mode can also be derived rather than set by the block itself. Under a `templateLock: 'contentOnly'` ancestor, a block without an explicitly set mode is derived as `'contentOnly'` if it is a content block (it has an attribute with `role: 'content'`, or `supports.contentRole`), and as `'disabled'` otherwise. An explicitly set mode wins over these derived modes. See the [block locking guide](https://developer.wordpress.org/block-editor/how-to-guides/curating-the-editor-experience/block-locking/) for more on locking.
16
+
17
+ ## Development guidelines
18
+
19
+ ### Usage
20
+
21
+ Called without an argument, the hook returns the current mode for the block. This is the most common use, and lets a block hide controls when editing is restricted:
22
+
23
+ ```jsx
24
+ import {
25
+ BlockControls,
26
+ useBlockEditingMode,
27
+ useBlockProps,
28
+ } from '@wordpress/block-editor';
29
+
30
+ function MyBlock( { attributes, setAttributes } ) {
31
+ const blockEditingMode = useBlockEditingMode();
32
+ return (
33
+ <>
34
+ { blockEditingMode === 'default' && (
35
+ <BlockControls group="block">
36
+ <MyToolbarControl />
37
+ </BlockControls>
38
+ ) }
39
+ <div { ...useBlockProps() }></div>
40
+ </>
41
+ );
42
+ }
43
+ ```
44
+
45
+ Passing a mode sets it for the block:
46
+
47
+ ```jsx
48
+ import {
49
+ useBlockEditingMode,
50
+ useBlockProps,
51
+ } from '@wordpress/block-editor';
52
+
53
+ function MyBlock( { attributes, setAttributes } ) {
54
+ useBlockEditingMode( 'disabled' );
55
+ return <div { ...useBlockProps() }></div>;
56
+ }
57
+ ```
58
+
59
+ ### Parameters
60
+
61
+ #### `mode`
62
+
63
+ - **Type:** `String`
64
+ - **Default:** `undefined`
65
+
66
+ The editing mode to set for the block. One of `'disabled'`, `'contentOnly'`, or `'default'`. If `undefined`, the current editing mode remains unchanged.
67
+
68
+ ### Return
69
+
70
+ - **Type:** `String`
71
+
72
+ The current editing mode for the block.
@@ -42,12 +42,12 @@ import {
42
42
  } from '../../hooks/block-style-state';
43
43
 
44
44
  function StyleInspectorSlots( {
45
- blockName,
45
+ clientId,
46
46
  showAdvancedControls = true,
47
47
  showPositionControls = true,
48
48
  showBindingsControls = true,
49
49
  } ) {
50
- const borderPanelLabel = useBorderPanelLabel( { blockName } );
50
+ const borderPanelLabel = useBorderPanelLabel( { clientId } );
51
51
  return (
52
52
  <>
53
53
  <InspectorControls.Slot />
@@ -97,7 +97,7 @@ function StyleStateInspectorSlots( {
97
97
  isSectionBlock,
98
98
  selectedBlockStyleState,
99
99
  } ) {
100
- const borderPanelLabel = useBorderPanelLabel( { blockName } );
100
+ const borderPanelLabel = useBorderPanelLabel( { clientId } );
101
101
  const showLayoutControls =
102
102
  hasViewportBlockStyleState( selectedBlockStyleState ) &&
103
103
  ! hasPseudoBlockStyleState( selectedBlockStyleState );
@@ -298,7 +298,6 @@ function BlockInspector() {
298
298
  <InspectorControlsTabs tabs={ availableTabs } />
299
299
  ) : (
300
300
  <StyleInspectorSlots
301
- blockName={ renderedBlockName }
302
301
  showAdvancedControls={ false }
303
302
  showPositionControls={ false }
304
303
  showBindingsControls={ false }
@@ -501,7 +500,6 @@ const BlockInspectorSingleBlock = ( {
501
500
  <BlockInspectorPreTabsSlot />
502
501
  { isEditingStyleState && (
503
502
  <StyleStateInspectorSlots
504
- blockName={ blockName }
505
503
  clientId={ renderedBlockClientId }
506
504
  contentClientIds={ contentClientIds }
507
505
  isSectionBlock={ isSectionBlock }
@@ -530,7 +528,9 @@ const BlockInspectorSingleBlock = ( {
530
528
  <InspectorControls.Slot group="list" ref={ listViewRef } />
531
529
  <ListViewContentPopover listViewRef={ listViewRef } />
532
530
  { ! isSectionBlock && (
533
- <StyleInspectorSlots blockName={ blockName } />
531
+ <StyleInspectorSlots
532
+ clientId={ renderedBlockClientId }
533
+ />
534
534
  ) }
535
535
  </>
536
536
  ) }
@@ -0,0 +1,256 @@
1
+ import { useCallback, useEffect, useRef } from '@wordpress/element';
2
+ import { useSelect, useDispatch } from '@wordpress/data';
3
+ import {
4
+ useShortcut,
5
+ store as keyboardShortcutsStore,
6
+ } from '@wordpress/keyboard-shortcuts';
7
+ import { store as blocksStore, switchToBlockType } from '@wordpress/blocks';
8
+ import warning from '@wordpress/warning';
9
+ import { store as blockEditorStore } from '../../store';
10
+ import { unlock } from '../../lock-unlock';
11
+
12
+ /**
13
+ * Returns every keyboard shortcut declared by a registered block type, through
14
+ * either a block variation or a block transform.
15
+ *
16
+ * @return {Array} Declared shortcuts, each paired with the block change it makes.
17
+ */
18
+ function useDeclaredBlockShortcuts() {
19
+ return useSelect(
20
+ ( select ) =>
21
+ unlock( select( blocksStore ) ).getBlockKeyboardShortcuts(),
22
+ []
23
+ );
24
+ }
25
+
26
+ /**
27
+ * Returns a callback applying a block-declared shortcut to the selected block.
28
+ *
29
+ * The callback reports whether the shortcut was relevant to the current
30
+ * selection, which is not the same as whether the block changed: a shortcut
31
+ * that resolves to the block's current state is still handled, so that the key
32
+ * combination is swallowed rather than typed into the block.
33
+ *
34
+ * @return {Function} Callback receiving a declared shortcut.
35
+ */
36
+ function useApplyBlockShortcut() {
37
+ const {
38
+ getBlock,
39
+ getBlockName,
40
+ getBlockAttributes,
41
+ getBlockEditingMode,
42
+ getSelectedBlockClientId,
43
+ } = useSelect( blockEditorStore );
44
+ const { getBlockVariations, getActiveBlockVariation } =
45
+ useSelect( blocksStore );
46
+ const { replaceBlocks, updateBlockAttributes } =
47
+ useDispatch( blockEditorStore );
48
+
49
+ return useCallback(
50
+ ( { targetBlockName, blockNames, variationName } ) => {
51
+ const clientId = getSelectedBlockClientId();
52
+ if ( ! clientId ) {
53
+ return false;
54
+ }
55
+
56
+ // Transforming a block is a structural change, so it is only
57
+ // allowed where the block is fully editable.
58
+ if ( getBlockEditingMode( clientId ) !== 'default' ) {
59
+ return false;
60
+ }
61
+
62
+ const blockName = getBlockName( clientId );
63
+ if ( ! blockNames.includes( blockName ) ) {
64
+ return false;
65
+ }
66
+
67
+ const variation = variationName
68
+ ? getBlockVariations( targetBlockName )?.find(
69
+ ( { name } ) => name === variationName
70
+ )
71
+ : undefined;
72
+
73
+ // The block is already of the target type, so there is nothing to
74
+ // transform. Applying the variation's attributes is all that is
75
+ // left to do.
76
+ if ( blockName === targetBlockName ) {
77
+ if ( ! variation?.attributes ) {
78
+ return false;
79
+ }
80
+ const activeVariation = getActiveBlockVariation(
81
+ targetBlockName,
82
+ getBlockAttributes( clientId )
83
+ );
84
+ if ( activeVariation?.name !== variationName ) {
85
+ updateBlockAttributes( clientId, variation.attributes );
86
+ }
87
+ return true;
88
+ }
89
+
90
+ const block = getBlock( clientId );
91
+ if ( ! block ) {
92
+ return false;
93
+ }
94
+
95
+ // Prefer a transform declared for this specific variation, and
96
+ // fall back to transforming to the block type and applying the
97
+ // variation's attributes on top.
98
+ let blocks = variation
99
+ ? switchToBlockType( block, targetBlockName, variation.name )
100
+ : null;
101
+
102
+ if ( ! blocks ) {
103
+ blocks = switchToBlockType( block, targetBlockName );
104
+
105
+ if ( blocks && variation?.attributes ) {
106
+ blocks = blocks.map( ( newBlock ) =>
107
+ newBlock.name === targetBlockName
108
+ ? {
109
+ ...newBlock,
110
+ attributes: {
111
+ ...newBlock.attributes,
112
+ ...variation.attributes,
113
+ },
114
+ }
115
+ : newBlock
116
+ );
117
+ }
118
+ }
119
+
120
+ if ( ! blocks ) {
121
+ return false;
122
+ }
123
+
124
+ replaceBlocks( clientId, blocks );
125
+ return true;
126
+ },
127
+ [
128
+ getBlock,
129
+ getBlockName,
130
+ getBlockAttributes,
131
+ getBlockEditingMode,
132
+ getSelectedBlockClientId,
133
+ getBlockVariations,
134
+ getActiveBlockVariation,
135
+ replaceBlocks,
136
+ updateBlockAttributes,
137
+ ]
138
+ );
139
+ }
140
+
141
+ function BlockShortcut( { entry, apply } ) {
142
+ useShortcut( entry.name, ( event ) => {
143
+ // Another handler already acted on this event: either a shortcut
144
+ // claiming the same key combination, or this same shortcut mounted
145
+ // twice because block editor providers can be nested.
146
+ if ( event.defaultPrevented ) {
147
+ return;
148
+ }
149
+
150
+ if ( apply( entry ) ) {
151
+ event.preventDefault();
152
+ }
153
+ } );
154
+
155
+ return null;
156
+ }
157
+
158
+ function BlockShortcutsRegister( { shortcuts } ) {
159
+ const { registerShortcut, unregisterShortcut } = useDispatch(
160
+ keyboardShortcutsStore
161
+ );
162
+ // Shortcuts registered by a previous run, keyed by name, so that those
163
+ // belonging to a block type that has since been unregistered can be
164
+ // removed. Registration deliberately outlives this component: providers can
165
+ // be nested, and unmounting one of them must not take the shortcuts away
166
+ // from the others.
167
+ const registeredRef = useRef( new Map() );
168
+
169
+ useEffect( () => {
170
+ const registered = new Map();
171
+ const combinations = new Map();
172
+
173
+ for ( const shortcut of shortcuts ) {
174
+ const config = {
175
+ name: shortcut.name,
176
+ category: 'block',
177
+ description: shortcut.description,
178
+ keyCombination: shortcut.keyCombination,
179
+ aliases: shortcut.aliases,
180
+ };
181
+ const serialized = JSON.stringify( config );
182
+
183
+ // One shortcut is declared once per block change it can make, so
184
+ // the same name legitimately appears more than once: the heading
185
+ // level shortcuts are declared both on the variation, for a
186
+ // heading, and on the transform that produces one from a
187
+ // paragraph. Only declarations that disagree are a mistake, since
188
+ // the store keys shortcuts by name and the last one registered
189
+ // would decide what the others are matched against.
190
+ const previous = registered.get( shortcut.name );
191
+ if ( previous !== undefined ) {
192
+ if ( previous !== serialized ) {
193
+ warning(
194
+ `Block keyboard shortcut "${ shortcut.name }" is declared more than once with different settings.`
195
+ );
196
+ }
197
+ continue;
198
+ }
199
+
200
+ // Handlers are matched by key combination rather than by name, so
201
+ // two shortcuts claiming the same one both run on the same event,
202
+ // in registration order, and the first that applies takes it.
203
+ const { modifier, character } = shortcut.keyCombination;
204
+ const combination = `${ modifier ?? '' }+${ character }`;
205
+ if ( combinations.has( combination ) ) {
206
+ warning(
207
+ `Block keyboard shortcut "${
208
+ shortcut.name
209
+ }" uses the same key combination as "${ combinations.get(
210
+ combination
211
+ ) }".`
212
+ );
213
+ }
214
+ combinations.set( combination, shortcut.name );
215
+
216
+ registerShortcut( config );
217
+ registered.set( shortcut.name, serialized );
218
+ }
219
+
220
+ for ( const name of registeredRef.current.keys() ) {
221
+ if ( ! registered.has( name ) ) {
222
+ unregisterShortcut( name );
223
+ }
224
+ }
225
+
226
+ registeredRef.current = registered;
227
+ }, [ shortcuts, registerShortcut, unregisterShortcut ] );
228
+
229
+ return null;
230
+ }
231
+
232
+ /**
233
+ * Registers and handles the keyboard shortcuts that blocks declare on their
234
+ * variations and transforms, applying them to the selected block.
235
+ *
236
+ * @return {Element} Element.
237
+ */
238
+ export default function BlockKeyboardShortcuts() {
239
+ const shortcuts = useDeclaredBlockShortcuts();
240
+ const apply = useApplyBlockShortcut();
241
+
242
+ return (
243
+ <>
244
+ <BlockShortcutsRegister shortcuts={ shortcuts } />
245
+ { shortcuts.map( ( entry, index ) => (
246
+ <BlockShortcut
247
+ // Shortcut names are not guaranteed to be unique across
248
+ // blocks, so the index keeps the list stable.
249
+ key={ `${ entry.name }-${ index }` }
250
+ entry={ entry }
251
+ apply={ apply }
252
+ />
253
+ ) ) }
254
+ </>
255
+ );
256
+ }
@@ -771,6 +771,11 @@ function BlockListBlockProvider( props ) {
771
771
  blockVisibility,
772
772
  deviceType,
773
773
  viewportSettings,
774
+ supportsSplitting: hasBlockSupport(
775
+ blockName,
776
+ 'splitting',
777
+ false
778
+ ),
774
779
  };
775
780
  },
776
781
  [ clientId, rootClientId, ghostBlock, ghostBlockWithoutAttributes ]
@@ -854,6 +859,7 @@ function BlockListBlockProvider( props ) {
854
859
  blockVisibility,
855
860
  deviceType,
856
861
  viewportSettings,
862
+ supportsSplitting,
857
863
  } = selectedProps;
858
864
 
859
865
  const privateContext = {
@@ -896,6 +902,7 @@ function BlockListBlockProvider( props ) {
896
902
  blockVisibility,
897
903
  deviceType,
898
904
  viewportSettings,
905
+ supportsSplitting,
899
906
  };
900
907
 
901
908
  if (
@@ -55,7 +55,13 @@ function Root( { className, ...settings } ) {
55
55
  } = getSettings();
56
56
  return {
57
57
  isOutlineMode: outlineMode && ! isTyping(),
58
- isFocusMode: focusMode || hasBlockSpotlight(),
58
+ /*
59
+ * Spotlight fades everything but the block being worked on, which
60
+ * has nothing to offer a canvas that cannot be edited — a preview
61
+ * would just render most of its content faded out.
62
+ */
63
+ isFocusMode:
64
+ ! _isPreviewMode && ( focusMode || hasBlockSpotlight() ),
59
65
  isPreviewMode: _isPreviewMode,
60
66
  editedContentOnlySection: getEditedContentOnlySection(),
61
67
  };
@@ -50,6 +50,11 @@ export function useFocusFirstElement( { clientId, initialPosition } ) {
50
50
  return;
51
51
  }
52
52
 
53
+ if ( initialPosition === true ) {
54
+ ref.current.focus();
55
+ return;
56
+ }
57
+
53
58
  // Find all tabbables within node.
54
59
  const textInputs = focus.tabbable
55
60
  .find( ref.current )
@@ -28,7 +28,6 @@ export function useEventHandlers( { clientId, isSelected } ) {
28
28
  getBlock,
29
29
  } = unlock( useSelect( blockEditorStore ) );
30
30
  const {
31
- insertAfterBlock,
32
31
  removeBlock,
33
32
  resetZoomLevel,
34
33
  startDraggingBlocks,
@@ -66,13 +65,13 @@ export function useEventHandlers( { clientId, isSelected } ) {
66
65
  return;
67
66
  }
68
67
 
69
- event.preventDefault();
70
-
71
- if ( keyCode === ENTER && isZoomOut() ) {
72
- resetZoomLevel();
73
- } else if ( keyCode === ENTER ) {
74
- insertAfterBlock( clientId );
68
+ if ( keyCode === ENTER ) {
69
+ if ( isZoomOut() ) {
70
+ event.preventDefault();
71
+ resetZoomLevel();
72
+ }
75
73
  } else {
74
+ event.preventDefault();
76
75
  removeBlock( clientId );
77
76
  }
78
77
  }
@@ -327,7 +326,6 @@ export function useEventHandlers( { clientId, isSelected } ) {
327
326
  getBlock,
328
327
  isReusableBlock,
329
328
  isTemplatePart,
330
- insertAfterBlock,
331
329
  removeBlock,
332
330
  isZoomOut,
333
331
  resetZoomLevel,