@wordpress/block-editor 12.4.0 → 12.5.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 (316) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +5 -0
  3. package/build/components/block-heading-level-dropdown/heading-level-icon.js +10 -2
  4. package/build/components/block-heading-level-dropdown/heading-level-icon.js.map +1 -1
  5. package/build/components/block-heading-level-dropdown/index.native.js +4 -3
  6. package/build/components/block-heading-level-dropdown/index.native.js.map +1 -1
  7. package/build/components/block-lock/toolbar.js +25 -6
  8. package/build/components/block-lock/toolbar.js.map +1 -1
  9. package/build/components/block-mobile-toolbar/block-actions-menu.native.js +3 -6
  10. package/build/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  11. package/build/components/block-parent-selector/index.js +8 -5
  12. package/build/components/block-parent-selector/index.js.map +1 -1
  13. package/build/components/block-removal-warning-modal/index.js +18 -25
  14. package/build/components/block-removal-warning-modal/index.js.map +1 -1
  15. package/build/components/block-toolbar/index.js +8 -5
  16. package/build/components/block-toolbar/index.js.map +1 -1
  17. package/build/components/block-tools/block-contextual-toolbar.js +7 -11
  18. package/build/components/block-tools/block-contextual-toolbar.js.map +1 -1
  19. package/build/components/dimensions-tool/aspect-ratio-tool.js +99 -0
  20. package/build/components/dimensions-tool/aspect-ratio-tool.js.map +1 -0
  21. package/build/components/dimensions-tool/index.js +207 -0
  22. package/build/components/dimensions-tool/index.js.map +1 -0
  23. package/build/components/dimensions-tool/scale-tool.js +111 -0
  24. package/build/components/dimensions-tool/scale-tool.js.map +1 -0
  25. package/build/components/dimensions-tool/width-height-tool.js +125 -0
  26. package/build/components/dimensions-tool/width-height-tool.js.map +1 -0
  27. package/build/components/global-styles/color-panel.js +1 -1
  28. package/build/components/global-styles/color-panel.js.map +1 -1
  29. package/build/components/global-styles/filters-panel.js +1 -1
  30. package/build/components/global-styles/filters-panel.js.map +1 -1
  31. package/build/components/global-styles/hooks.js +2 -2
  32. package/build/components/global-styles/hooks.js.map +1 -1
  33. package/build/components/global-styles/typography-panel.js +34 -2
  34. package/build/components/global-styles/typography-panel.js.map +1 -1
  35. package/build/components/image-editor/aspect-ratio-dropdown.js +1 -1
  36. package/build/components/image-editor/aspect-ratio-dropdown.js.map +1 -1
  37. package/build/components/image-editor/use-save-image.js +1 -2
  38. package/build/components/image-editor/use-save-image.js.map +1 -1
  39. package/build/components/image-size-control/index.js +6 -0
  40. package/build/components/image-size-control/index.js.map +1 -1
  41. package/build/components/index.js +19 -1
  42. package/build/components/index.js.map +1 -1
  43. package/build/components/inserter/block-patterns-explorer/patterns-list.js +2 -2
  44. package/build/components/inserter/block-patterns-explorer/patterns-list.js.map +1 -1
  45. package/build/components/inserter/block-patterns-tab.js +7 -35
  46. package/build/components/inserter/block-patterns-tab.js.map +1 -1
  47. package/build/components/inserter/hooks/use-block-types-state.js +3 -4
  48. package/build/components/inserter/hooks/use-block-types-state.js.map +1 -1
  49. package/build/components/inserter/hooks/use-patterns-state.js +9 -3
  50. package/build/components/inserter/hooks/use-patterns-state.js.map +1 -1
  51. package/build/components/inserter/media-tab/hooks.js +2 -21
  52. package/build/components/inserter/media-tab/hooks.js.map +1 -1
  53. package/build/components/inserter/reusable-block-rename-hint.js +62 -0
  54. package/build/components/inserter/reusable-block-rename-hint.js.map +1 -0
  55. package/build/components/inserter/reusable-blocks-tab.js +6 -2
  56. package/build/components/inserter/reusable-blocks-tab.js.map +1 -1
  57. package/build/components/inserter/reusable-blocks-tab.native.js +2 -2
  58. package/build/components/inserter/reusable-blocks-tab.native.js.map +1 -1
  59. package/build/components/inserter/tabs.native.js +1 -1
  60. package/build/components/inserter/tabs.native.js.map +1 -1
  61. package/build/components/inserter-draggable-blocks/index.js +9 -1
  62. package/build/components/inserter-draggable-blocks/index.js.map +1 -1
  63. package/build/components/link-control/constants.js +1 -1
  64. package/build/components/link-control/constants.js.map +1 -1
  65. package/build/components/link-control/index.js +17 -15
  66. package/build/components/link-control/index.js.map +1 -1
  67. package/build/components/link-control/search-create-button.js +5 -21
  68. package/build/components/link-control/search-create-button.js.map +1 -1
  69. package/build/components/link-control/search-input.js +4 -4
  70. package/build/components/link-control/search-input.js.map +1 -1
  71. package/build/components/link-control/search-item.js +13 -30
  72. package/build/components/link-control/search-item.js.map +1 -1
  73. package/build/components/link-control/search-results.js +2 -2
  74. package/build/components/link-control/search-results.js.map +1 -1
  75. package/build/components/link-control/settings-drawer.js +2 -3
  76. package/build/components/link-control/settings-drawer.js.map +1 -1
  77. package/build/components/list-view/appender.js +2 -6
  78. package/build/components/list-view/appender.js.map +1 -1
  79. package/build/components/provider/index.js +5 -2
  80. package/build/components/provider/index.js.map +1 -1
  81. package/build/components/provider/use-block-sync.js +21 -0
  82. package/build/components/provider/use-block-sync.js.map +1 -1
  83. package/build/components/resolution-tool/index.js +55 -0
  84. package/build/components/resolution-tool/index.js.map +1 -0
  85. package/build/components/url-input/index.js +4 -2
  86. package/build/components/url-input/index.js.map +1 -1
  87. package/build/components/writing-flow/use-tab-nav.js +10 -27
  88. package/build/components/writing-flow/use-tab-nav.js.map +1 -1
  89. package/build/components/writing-mode-control/index.js +70 -0
  90. package/build/components/writing-mode-control/index.js.map +1 -0
  91. package/build/hooks/behaviors.js +25 -20
  92. package/build/hooks/behaviors.js.map +1 -1
  93. package/build/hooks/supports.js +7 -1
  94. package/build/hooks/supports.js.map +1 -1
  95. package/build/hooks/typography.js +2 -1
  96. package/build/hooks/typography.js.map +1 -1
  97. package/build/hooks/utils.js +4 -2
  98. package/build/hooks/utils.js.map +1 -1
  99. package/build/private-apis.js +10 -1
  100. package/build/private-apis.js.map +1 -1
  101. package/build/private-apis.native.js +3 -0
  102. package/build/private-apis.native.js.map +1 -1
  103. package/build/store/actions.js +195 -1
  104. package/build/store/actions.js.map +1 -1
  105. package/build/store/defaults.js +1 -0
  106. package/build/store/defaults.js.map +1 -1
  107. package/build/store/index.js +10 -1
  108. package/build/store/index.js.map +1 -1
  109. package/build/store/private-actions.js +46 -40
  110. package/build/store/private-actions.js.map +1 -1
  111. package/build/store/private-selectors.js +3 -3
  112. package/build/store/private-selectors.js.map +1 -1
  113. package/build/store/reducer.js +22 -8
  114. package/build/store/reducer.js.map +1 -1
  115. package/build/store/selectors.js +33 -15
  116. package/build/store/selectors.js.map +1 -1
  117. package/build-module/components/block-heading-level-dropdown/heading-level-icon.js +9 -2
  118. package/build-module/components/block-heading-level-dropdown/heading-level-icon.js.map +1 -1
  119. package/build-module/components/block-heading-level-dropdown/index.native.js +4 -3
  120. package/build-module/components/block-heading-level-dropdown/index.native.js.map +1 -1
  121. package/build-module/components/block-lock/toolbar.js +25 -7
  122. package/build-module/components/block-lock/toolbar.js.map +1 -1
  123. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js +4 -6
  124. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  125. package/build-module/components/block-parent-selector/index.js +7 -5
  126. package/build-module/components/block-parent-selector/index.js.map +1 -1
  127. package/build-module/components/block-removal-warning-modal/index.js +20 -24
  128. package/build-module/components/block-removal-warning-modal/index.js.map +1 -1
  129. package/build-module/components/block-toolbar/index.js +8 -5
  130. package/build-module/components/block-toolbar/index.js.map +1 -1
  131. package/build-module/components/block-tools/block-contextual-toolbar.js +8 -11
  132. package/build-module/components/block-tools/block-contextual-toolbar.js.map +1 -1
  133. package/build-module/components/dimensions-tool/aspect-ratio-tool.js +87 -0
  134. package/build-module/components/dimensions-tool/aspect-ratio-tool.js.map +1 -0
  135. package/build-module/components/dimensions-tool/index.js +195 -0
  136. package/build-module/components/dimensions-tool/index.js.map +1 -0
  137. package/build-module/components/dimensions-tool/scale-tool.js +103 -0
  138. package/build-module/components/dimensions-tool/scale-tool.js.map +1 -0
  139. package/build-module/components/dimensions-tool/width-height-tool.js +122 -0
  140. package/build-module/components/dimensions-tool/width-height-tool.js.map +1 -0
  141. package/build-module/components/global-styles/color-panel.js +1 -1
  142. package/build-module/components/global-styles/color-panel.js.map +1 -1
  143. package/build-module/components/global-styles/filters-panel.js +2 -2
  144. package/build-module/components/global-styles/filters-panel.js.map +1 -1
  145. package/build-module/components/global-styles/hooks.js +2 -2
  146. package/build-module/components/global-styles/hooks.js.map +1 -1
  147. package/build-module/components/global-styles/typography-panel.js +33 -2
  148. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  149. package/build-module/components/image-editor/aspect-ratio-dropdown.js +1 -1
  150. package/build-module/components/image-editor/aspect-ratio-dropdown.js.map +1 -1
  151. package/build-module/components/image-editor/use-save-image.js +1 -2
  152. package/build-module/components/image-editor/use-save-image.js.map +1 -1
  153. package/build-module/components/image-size-control/index.js +5 -0
  154. package/build-module/components/image-size-control/index.js.map +1 -1
  155. package/build-module/components/index.js +6 -0
  156. package/build-module/components/index.js.map +1 -1
  157. package/build-module/components/inserter/block-patterns-explorer/patterns-list.js +2 -2
  158. package/build-module/components/inserter/block-patterns-explorer/patterns-list.js.map +1 -1
  159. package/build-module/components/inserter/block-patterns-tab.js +7 -33
  160. package/build-module/components/inserter/block-patterns-tab.js.map +1 -1
  161. package/build-module/components/inserter/hooks/use-block-types-state.js +3 -4
  162. package/build-module/components/inserter/hooks/use-block-types-state.js.map +1 -1
  163. package/build-module/components/inserter/hooks/use-patterns-state.js +9 -3
  164. package/build-module/components/inserter/hooks/use-patterns-state.js.map +1 -1
  165. package/build-module/components/inserter/media-tab/hooks.js +2 -21
  166. package/build-module/components/inserter/media-tab/hooks.js.map +1 -1
  167. package/build-module/components/inserter/reusable-block-rename-hint.js +48 -0
  168. package/build-module/components/inserter/reusable-block-rename-hint.js.map +1 -0
  169. package/build-module/components/inserter/reusable-blocks-tab.js +5 -2
  170. package/build-module/components/inserter/reusable-blocks-tab.js.map +1 -1
  171. package/build-module/components/inserter/reusable-blocks-tab.native.js +2 -2
  172. package/build-module/components/inserter/reusable-blocks-tab.native.js.map +1 -1
  173. package/build-module/components/inserter/tabs.native.js +1 -1
  174. package/build-module/components/inserter/tabs.native.js.map +1 -1
  175. package/build-module/components/inserter-draggable-blocks/index.js +9 -2
  176. package/build-module/components/inserter-draggable-blocks/index.js.map +1 -1
  177. package/build-module/components/link-control/constants.js +1 -1
  178. package/build-module/components/link-control/constants.js.map +1 -1
  179. package/build-module/components/link-control/index.js +17 -15
  180. package/build-module/components/link-control/index.js.map +1 -1
  181. package/build-module/components/link-control/search-create-button.js +7 -20
  182. package/build-module/components/link-control/search-create-button.js.map +1 -1
  183. package/build-module/components/link-control/search-input.js +4 -4
  184. package/build-module/components/link-control/search-input.js.map +1 -1
  185. package/build-module/components/link-control/search-item.js +14 -28
  186. package/build-module/components/link-control/search-item.js.map +1 -1
  187. package/build-module/components/link-control/search-results.js +3 -3
  188. package/build-module/components/link-control/search-results.js.map +1 -1
  189. package/build-module/components/link-control/settings-drawer.js +4 -5
  190. package/build-module/components/link-control/settings-drawer.js.map +1 -1
  191. package/build-module/components/list-view/appender.js +2 -6
  192. package/build-module/components/list-view/appender.js.map +1 -1
  193. package/build-module/components/provider/index.js +5 -2
  194. package/build-module/components/provider/index.js.map +1 -1
  195. package/build-module/components/provider/use-block-sync.js +21 -0
  196. package/build-module/components/provider/use-block-sync.js.map +1 -1
  197. package/build-module/components/resolution-tool/index.js +45 -0
  198. package/build-module/components/resolution-tool/index.js.map +1 -0
  199. package/build-module/components/url-input/index.js +4 -2
  200. package/build-module/components/url-input/index.js.map +1 -1
  201. package/build-module/components/writing-flow/use-tab-nav.js +8 -26
  202. package/build-module/components/writing-flow/use-tab-nav.js.map +1 -1
  203. package/build-module/components/writing-mode-control/index.js +57 -0
  204. package/build-module/components/writing-mode-control/index.js.map +1 -0
  205. package/build-module/hooks/behaviors.js +26 -20
  206. package/build-module/hooks/behaviors.js.map +1 -1
  207. package/build-module/hooks/supports.js +7 -1
  208. package/build-module/hooks/supports.js.map +1 -1
  209. package/build-module/hooks/typography.js +2 -1
  210. package/build-module/hooks/typography.js.map +1 -1
  211. package/build-module/hooks/utils.js +4 -2
  212. package/build-module/hooks/utils.js.map +1 -1
  213. package/build-module/private-apis.js +7 -1
  214. package/build-module/private-apis.js.map +1 -1
  215. package/build-module/private-apis.native.js +2 -0
  216. package/build-module/private-apis.native.js.map +1 -1
  217. package/build-module/store/actions.js +191 -1
  218. package/build-module/store/actions.js.map +1 -1
  219. package/build-module/store/defaults.js +1 -0
  220. package/build-module/store/defaults.js.map +1 -1
  221. package/build-module/store/index.js +10 -1
  222. package/build-module/store/index.js.map +1 -1
  223. package/build-module/store/private-actions.js +45 -36
  224. package/build-module/store/private-actions.js.map +1 -1
  225. package/build-module/store/private-selectors.js +2 -2
  226. package/build-module/store/private-selectors.js.map +1 -1
  227. package/build-module/store/reducer.js +22 -8
  228. package/build-module/store/reducer.js.map +1 -1
  229. package/build-module/store/selectors.js +33 -15
  230. package/build-module/store/selectors.js.map +1 -1
  231. package/build-style/content-rtl.css +3 -0
  232. package/build-style/content.css +3 -0
  233. package/build-style/style-rtl.css +131 -129
  234. package/build-style/style.css +131 -129
  235. package/package.json +32 -31
  236. package/src/components/alignment-control/test/__snapshots__/index.js.snap +6 -6
  237. package/src/components/block-alignment-control/test/__snapshots__/index.js.snap +5 -5
  238. package/src/components/block-draggable/style.scss +1 -0
  239. package/src/components/block-heading-level-dropdown/heading-level-icon.js +6 -1
  240. package/src/components/block-heading-level-dropdown/index.native.js +8 -4
  241. package/src/components/block-inspector/style.scss +2 -1
  242. package/src/components/block-lock/toolbar.js +34 -6
  243. package/src/components/block-mobile-toolbar/block-actions-menu.native.js +4 -8
  244. package/src/components/block-parent-selector/index.js +13 -8
  245. package/src/components/block-removal-warning-modal/index.js +20 -33
  246. package/src/components/block-toolbar/index.js +9 -6
  247. package/src/components/block-tools/block-contextual-toolbar.js +5 -11
  248. package/src/components/block-tools/style.scss +73 -26
  249. package/src/components/default-block-appender/content.scss +11 -0
  250. package/src/components/dimensions-tool/aspect-ratio-tool.js +124 -0
  251. package/src/components/dimensions-tool/index.js +212 -0
  252. package/src/components/dimensions-tool/scale-tool.js +124 -0
  253. package/src/components/dimensions-tool/stories/aspect-ratio-tool.js +52 -0
  254. package/src/components/dimensions-tool/stories/index.js +54 -0
  255. package/src/components/dimensions-tool/stories/scale-tool.js +48 -0
  256. package/src/components/dimensions-tool/stories/width-height-tool.js +54 -0
  257. package/src/components/dimensions-tool/test/index.js +641 -0
  258. package/src/components/dimensions-tool/width-height-tool.js +113 -0
  259. package/src/components/font-family/README.md +71 -0
  260. package/src/components/global-styles/color-panel.js +1 -1
  261. package/src/components/global-styles/filters-panel.js +2 -2
  262. package/src/components/global-styles/hooks.js +2 -0
  263. package/src/components/global-styles/typography-panel.js +40 -0
  264. package/src/components/image-editor/aspect-ratio-dropdown.js +1 -1
  265. package/src/components/image-editor/use-save-image.js +0 -1
  266. package/src/components/image-size-control/index.js +6 -0
  267. package/src/components/index.js +6 -0
  268. package/src/components/inserter/block-patterns-explorer/patterns-list.js +8 -2
  269. package/src/components/inserter/block-patterns-tab.js +8 -56
  270. package/src/components/inserter/hooks/use-block-types-state.js +3 -4
  271. package/src/components/inserter/hooks/use-patterns-state.js +35 -19
  272. package/src/components/inserter/media-tab/hooks.js +2 -22
  273. package/src/components/inserter/reusable-block-rename-hint.js +52 -0
  274. package/src/components/inserter/reusable-blocks-tab.js +5 -1
  275. package/src/components/inserter/reusable-blocks-tab.native.js +2 -2
  276. package/src/components/inserter/style.scss +28 -0
  277. package/src/components/inserter/tabs.native.js +5 -1
  278. package/src/components/inserter-draggable-blocks/index.js +13 -2
  279. package/src/components/link-control/constants.js +1 -1
  280. package/src/components/link-control/index.js +32 -28
  281. package/src/components/link-control/search-create-button.js +8 -26
  282. package/src/components/link-control/search-input.js +4 -3
  283. package/src/components/link-control/search-item.js +21 -43
  284. package/src/components/link-control/search-results.js +48 -46
  285. package/src/components/link-control/settings-drawer.js +6 -5
  286. package/src/components/link-control/style.scss +51 -123
  287. package/src/components/link-control/test/index.js +135 -123
  288. package/src/components/list-view/appender.js +5 -6
  289. package/src/components/list-view/style.scss +1 -2
  290. package/src/components/media-replace-flow/test/index.js +1 -1
  291. package/src/components/panel-color-settings/README.md +98 -0
  292. package/src/components/provider/index.js +9 -2
  293. package/src/components/provider/test/use-block-sync.js +21 -6
  294. package/src/components/provider/use-block-sync.js +19 -0
  295. package/src/components/recursion-provider/README.md +101 -0
  296. package/src/components/resolution-tool/index.js +56 -0
  297. package/src/components/resolution-tool/stories/index.js +48 -0
  298. package/src/components/url-input/index.js +2 -0
  299. package/src/components/writing-flow/use-tab-nav.js +10 -33
  300. package/src/components/writing-mode-control/index.js +68 -0
  301. package/src/components/writing-mode-control/style.scss +18 -0
  302. package/src/hooks/behaviors.js +25 -16
  303. package/src/hooks/supports.js +7 -0
  304. package/src/hooks/typography.js +2 -0
  305. package/src/hooks/utils.js +3 -0
  306. package/src/private-apis.js +6 -0
  307. package/src/private-apis.native.js +2 -0
  308. package/src/store/actions.js +194 -1
  309. package/src/store/defaults.js +1 -0
  310. package/src/store/index.js +10 -0
  311. package/src/store/private-actions.js +39 -39
  312. package/src/store/private-selectors.js +2 -2
  313. package/src/store/reducer.js +22 -8
  314. package/src/store/selectors.js +54 -20
  315. package/src/store/test/actions.js +111 -0
  316. package/src/store/test/private-actions.js +56 -0
@@ -30,11 +30,17 @@ const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
30
30
  * decorations e.g. settings found in `block.json`.
31
31
  */
32
32
  const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration';
33
+ /**
34
+ * Key within block settings' supports array indicating support for writing mode
35
+ * e.g. settings found in `block.json`.
36
+ */
37
+ const WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode';
33
38
  /**
34
39
  * Key within block settings' supports array indicating support for text
35
40
  * transforms e.g. settings found in `block.json`.
36
41
  */
37
42
  const TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform';
43
+
38
44
  /**
39
45
  * Key within block settings' supports array indicating support for letter-spacing
40
46
  * e.g. settings found in `block.json`.
@@ -50,6 +56,7 @@ const TYPOGRAPHY_SUPPORT_KEYS = [
50
56
  TEXT_COLUMNS_SUPPORT_KEY,
51
57
  TEXT_DECORATION_SUPPORT_KEY,
52
58
  TEXT_TRANSFORM_SUPPORT_KEY,
59
+ WRITING_MODE_SUPPORT_KEY,
53
60
  LETTER_SPACING_SUPPORT_KEY,
54
61
  ];
55
62
  const SPACING_SUPPORT_KEY = 'spacing';
@@ -30,6 +30,7 @@ const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration';
30
30
  const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
31
31
  const FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle';
32
32
  const FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight';
33
+ const WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode';
33
34
  export const TYPOGRAPHY_SUPPORT_KEY = 'typography';
34
35
  export const TYPOGRAPHY_SUPPORT_KEYS = [
35
36
  LINE_HEIGHT_SUPPORT_KEY,
@@ -39,6 +40,7 @@ export const TYPOGRAPHY_SUPPORT_KEYS = [
39
40
  FONT_FAMILY_SUPPORT_KEY,
40
41
  TEXT_COLUMNS_SUPPORT_KEY,
41
42
  TEXT_DECORATION_SUPPORT_KEY,
43
+ WRITING_MODE_SUPPORT_KEY,
42
44
  TEXT_TRANSFORM_SUPPORT_KEY,
43
45
  LETTER_SPACING_SUPPORT_KEY,
44
46
  ];
@@ -136,6 +136,7 @@ export function useBlockSettings( name, parentLayout ) {
136
136
  const lineHeight = useSetting( 'typography.lineHeight' );
137
137
  const textColumns = useSetting( 'typography.textColumns' );
138
138
  const textDecoration = useSetting( 'typography.textDecoration' );
139
+ const writingMode = useSetting( 'typography.writingMode' );
139
140
  const textTransform = useSetting( 'typography.textTransform' );
140
141
  const letterSpacing = useSetting( 'typography.letterSpacing' );
141
142
  const padding = useSetting( 'spacing.padding' );
@@ -211,6 +212,7 @@ export function useBlockSettings( name, parentLayout ) {
211
212
  textDecoration,
212
213
  textTransform,
213
214
  letterSpacing,
215
+ writingMode,
214
216
  },
215
217
  spacing: {
216
218
  spacingSizes: {
@@ -244,6 +246,7 @@ export function useBlockSettings( name, parentLayout ) {
244
246
  textDecoration,
245
247
  textTransform,
246
248
  letterSpacing,
249
+ writingMode,
247
250
  padding,
248
251
  margin,
249
252
  blockGap,
@@ -5,6 +5,7 @@ import * as globalStyles from './components/global-styles';
5
5
  import { ExperimentalBlockEditorProvider } from './components/provider';
6
6
  import { lock } from './lock-unlock';
7
7
  import { getRichTextValues } from './components/rich-text/content';
8
+ import { kebabCase } from './utils/object';
8
9
  import ResizableBoxPopover from './components/resizable-box-popover';
9
10
  import { ComposedPrivateInserter as PrivateInserter } from './components/inserter';
10
11
  import { PrivateListView } from './components/list-view';
@@ -16,6 +17,8 @@ import BlockQuickNavigation from './components/block-quick-navigation';
16
17
  import { LayoutStyle } from './components/block-list/layout';
17
18
  import { BlockRemovalWarningModal } from './components/block-removal-warning-modal';
18
19
  import { useLayoutClasses, useLayoutStyles } from './hooks';
20
+ import DimensionsTool from './components/dimensions-tool';
21
+ import ResolutionTool from './components/resolution-tool';
19
22
 
20
23
  /**
21
24
  * Private @wordpress/block-editor APIs.
@@ -25,6 +28,7 @@ lock( privateApis, {
25
28
  ...globalStyles,
26
29
  ExperimentalBlockEditorProvider,
27
30
  getRichTextValues,
31
+ kebabCase,
28
32
  PrivateInserter,
29
33
  PrivateListView,
30
34
  ResizableBoxPopover,
@@ -37,4 +41,6 @@ lock( privateApis, {
37
41
  BlockRemovalWarningModal,
38
42
  useLayoutClasses,
39
43
  useLayoutStyles,
44
+ DimensionsTool,
45
+ ResolutionTool,
40
46
  } );
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import * as globalStyles from './components/global-styles';
5
5
  import { ExperimentalBlockEditorProvider } from './components/provider';
6
+ import { kebabCase } from './utils/object';
6
7
  import { lock } from './lock-unlock';
7
8
 
8
9
  /**
@@ -11,5 +12,6 @@ import { lock } from './lock-unlock';
11
12
  export const privateApis = {};
12
13
  lock( privateApis, {
13
14
  ...globalStyles,
15
+ kebabCase,
14
16
  ExperimentalBlockEditorProvider,
15
17
  } );
@@ -1,3 +1,4 @@
1
+ /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */
1
2
  /**
2
3
  * WordPress dependencies
3
4
  */
@@ -1389,7 +1390,9 @@ export function updateBlockListSettings( clientId, settings ) {
1389
1390
  * @return {Object} Action object
1390
1391
  */
1391
1392
  export function updateSettings( settings ) {
1392
- return __experimentalUpdateSettings( settings, true );
1393
+ return __experimentalUpdateSettings( settings, {
1394
+ stripExperimentalSettings: true,
1395
+ } );
1393
1396
  }
1394
1397
 
1395
1398
  /**
@@ -1692,3 +1695,193 @@ export function __unstableSetTemporarilyEditingAsBlocks(
1692
1695
  temporarilyEditingAsBlocks,
1693
1696
  };
1694
1697
  }
1698
+
1699
+ /**
1700
+ * Interface for inserter media requests.
1701
+ *
1702
+ * @typedef {Object} InserterMediaRequest
1703
+ * @property {number} per_page How many items to fetch per page.
1704
+ * @property {string} search The search term to use for filtering the results.
1705
+ */
1706
+
1707
+ /**
1708
+ * Interface for inserter media responses. Any media resource should
1709
+ * map their response to this interface, in order to create the core
1710
+ * WordPress media blocks (image, video, audio).
1711
+ *
1712
+ * @typedef {Object} InserterMediaItem
1713
+ * @property {string} title The title of the media item.
1714
+ * @property {string} url The source url of the media item.
1715
+ * @property {string} [previewUrl] The preview source url of the media item to display in the media list.
1716
+ * @property {number} [id] The WordPress id of the media item.
1717
+ * @property {number|string} [sourceId] The id of the media item from external source.
1718
+ * @property {string} [alt] The alt text of the media item.
1719
+ * @property {string} [caption] The caption of the media item.
1720
+ */
1721
+
1722
+ /**
1723
+ * Registers a new inserter media category. Once registered, the media category is
1724
+ * available in the inserter's media tab.
1725
+ *
1726
+ * The following interfaces are used:
1727
+ *
1728
+ * _Type Definition_
1729
+ *
1730
+ * - _InserterMediaRequest_ `Object`: Interface for inserter media requests.
1731
+ *
1732
+ * _Properties_
1733
+ *
1734
+ * - _per_page_ `number`: How many items to fetch per page.
1735
+ * - _search_ `string`: The search term to use for filtering the results.
1736
+ *
1737
+ * _Type Definition_
1738
+ *
1739
+ * - _InserterMediaItem_ `Object`: Interface for inserter media responses. Any media resource should
1740
+ * map their response to this interface, in order to create the core
1741
+ * WordPress media blocks (image, video, audio).
1742
+ *
1743
+ * _Properties_
1744
+ *
1745
+ * - _title_ `string`: The title of the media item.
1746
+ * - _url_ `string: The source url of the media item.
1747
+ * - _previewUrl_ `[string]`: The preview source url of the media item to display in the media list.
1748
+ * - _id_ `[number]`: The WordPress id of the media item.
1749
+ * - _sourceId_ `[number|string]`: The id of the media item from external source.
1750
+ * - _alt_ `[string]`: The alt text of the media item.
1751
+ * - _caption_ `[string]`: The caption of the media item.
1752
+ *
1753
+ * @param {InserterMediaCategory} category The inserter media category to register.
1754
+ *
1755
+ * @example
1756
+ * ```js
1757
+ *
1758
+ * wp.data.dispatch('core/block-editor').registerInserterMediaCategory( {
1759
+ * name: 'openverse',
1760
+ * labels: {
1761
+ * name: 'Openverse',
1762
+ * search_items: 'Search Openverse',
1763
+ * },
1764
+ * mediaType: 'image',
1765
+ * async fetch( query = {} ) {
1766
+ * const defaultArgs = {
1767
+ * mature: false,
1768
+ * excluded_source: 'flickr,inaturalist,wikimedia',
1769
+ * license: 'pdm,cc0',
1770
+ * };
1771
+ * const finalQuery = { ...query, ...defaultArgs };
1772
+ * // Sometimes you might need to map the supported request params according to `InserterMediaRequest`.
1773
+ * // interface. In this example the `search` query param is named `q`.
1774
+ * const mapFromInserterMediaRequest = {
1775
+ * per_page: 'page_size',
1776
+ * search: 'q',
1777
+ * };
1778
+ * const url = new URL( 'https://api.openverse.engineering/v1/images/' );
1779
+ * Object.entries( finalQuery ).forEach( ( [ key, value ] ) => {
1780
+ * const queryKey = mapFromInserterMediaRequest[ key ] || key;
1781
+ * url.searchParams.set( queryKey, value );
1782
+ * } );
1783
+ * const response = await window.fetch( url, {
1784
+ * headers: {
1785
+ * 'User-Agent': 'WordPress/inserter-media-fetch',
1786
+ * },
1787
+ * } );
1788
+ * const jsonResponse = await response.json();
1789
+ * const results = jsonResponse.results;
1790
+ * return results.map( ( result ) => ( {
1791
+ * ...result,
1792
+ * // If your response result includes an `id` prop that you want to access later, it should
1793
+ * // be mapped to `InserterMediaItem`'s `sourceId` prop. This can be useful if you provide
1794
+ * // a report URL getter.
1795
+ * // Additionally you should always clear the `id` value of your response results because
1796
+ * // it is used to identify WordPress media items.
1797
+ * sourceId: result.id,
1798
+ * id: undefined,
1799
+ * caption: result.caption,
1800
+ * previewUrl: result.thumbnail,
1801
+ * } ) );
1802
+ * },
1803
+ * getReportUrl: ( { sourceId } ) =>
1804
+ * `https://wordpress.org/openverse/image/${ sourceId }/report/`,
1805
+ * isExternalResource: true,
1806
+ * } );
1807
+ * ```
1808
+ *
1809
+ * @typedef {Object} InserterMediaCategory Interface for inserter media category.
1810
+ * @property {string} name The name of the media category, that should be unique among all media categories.
1811
+ * @property {Object} labels Labels for the media category.
1812
+ * @property {string} labels.name General name of the media category. It's used in the inserter media items list.
1813
+ * @property {string} [labels.search_items='Search'] Label for searching items. Default is ‘Search Posts’ / ‘Search Pages’.
1814
+ * @property {('image'|'audio'|'video')} mediaType The media type of the media category.
1815
+ * @property {(InserterMediaRequest) => Promise<InserterMediaItem[]>} fetch The function to fetch media items for the category.
1816
+ * @property {(InserterMediaItem) => string} [getReportUrl] If the media category supports reporting media items, this function should return
1817
+ * the report url for the media item. It accepts the `InserterMediaItem` as an argument.
1818
+ * @property {boolean} [isExternalResource] If the media category is an external resource, this should be set to true.
1819
+ * This is used to avoid making a request to the external resource when the user
1820
+ *
1821
+ */
1822
+ export const registerInserterMediaCategory =
1823
+ ( category ) =>
1824
+ ( { select, dispatch } ) => {
1825
+ if ( ! category || typeof category !== 'object' ) {
1826
+ console.error(
1827
+ 'Category should be an `InserterMediaCategory` object.'
1828
+ );
1829
+ return;
1830
+ }
1831
+ if ( ! category.name ) {
1832
+ console.error(
1833
+ 'Category should have a `name` that should be unique among all media categories.'
1834
+ );
1835
+ return;
1836
+ }
1837
+ if ( ! category.labels?.name ) {
1838
+ console.error( 'Category should have a `labels.name`.' );
1839
+ return;
1840
+ }
1841
+ if ( ! [ 'image', 'audio', 'video' ].includes( category.mediaType ) ) {
1842
+ console.error(
1843
+ 'Category should have `mediaType` property that is one of `image|audio|video`.'
1844
+ );
1845
+ return;
1846
+ }
1847
+ if ( ! category.fetch || typeof category.fetch !== 'function' ) {
1848
+ console.error(
1849
+ 'Category should have a `fetch` function defined with the following signature `(InserterMediaRequest) => Promise<InserterMediaItem[]>`.'
1850
+ );
1851
+ return;
1852
+ }
1853
+ const { inserterMediaCategories = [] } = select.getSettings();
1854
+ if (
1855
+ inserterMediaCategories.some(
1856
+ ( { name } ) => name === category.name
1857
+ )
1858
+ ) {
1859
+ console.error(
1860
+ `A category is already registered with the same name: "${ category.name }".`
1861
+ );
1862
+ return;
1863
+ }
1864
+ if (
1865
+ inserterMediaCategories.some(
1866
+ ( { labels: { name } } ) => name === category.labels?.name
1867
+ )
1868
+ ) {
1869
+ console.error(
1870
+ `A category is already registered with the same labels.name: "${ category.labels.name }".`
1871
+ );
1872
+ return;
1873
+ }
1874
+ // `inserterMediaCategories` is a private block editor setting, which means it cannot
1875
+ // be updated through the public `updateSettings` action. We preserve this setting as
1876
+ // private, so extenders can only add new inserter media categories and don't have any
1877
+ // control over the core media categories.
1878
+ dispatch( {
1879
+ type: 'UPDATE_SETTINGS',
1880
+ settings: {
1881
+ inserterMediaCategories: [
1882
+ ...inserterMediaCategories,
1883
+ { ...category, isExternalResource: true },
1884
+ ],
1885
+ },
1886
+ } );
1887
+ };
@@ -18,6 +18,7 @@ export const PREFERENCES_DEFAULTS = {
18
18
  * @property {number} maxWidth Max width to constraint resizing
19
19
  * @property {boolean|Array} allowedBlockTypes Allowed block types
20
20
  * @property {boolean} hasFixedToolbar Whether or not the editor toolbar is fixed
21
+ * @property {boolean} distractionFree Whether or not the editor UI is distraction free
21
22
  * @property {boolean} focusMode Whether the focus mode is enabled or not
22
23
  * @property {Array} styles Editor Styles
23
24
  * @property {boolean} keepCaretInsideBlock Whether caret should move between blocks in edit mode
@@ -43,3 +43,13 @@ const registeredStore = registerStore( STORE_NAME, {
43
43
  } );
44
44
  unlock( registeredStore ).registerPrivateActions( privateActions );
45
45
  unlock( registeredStore ).registerPrivateSelectors( privateSelectors );
46
+
47
+ // TODO: Remove once we switch to the `register` function (see above).
48
+ //
49
+ // Until then, private functions also need to be attached to the original
50
+ // `store` descriptor in order to avoid unit tests failing, which could happen
51
+ // when tests create new registries in which they register stores.
52
+ //
53
+ // @see https://github.com/WordPress/gutenberg/pull/51145#discussion_r1239999590
54
+ unlock( store ).registerPrivateActions( privateActions );
55
+ unlock( store ).registerPrivateSelectors( privateSelectors );
@@ -3,11 +3,6 @@
3
3
  */
4
4
  import { Platform } from '@wordpress/element';
5
5
 
6
- /**
7
- * Internal dependencies
8
- */
9
- import { blockTypePromptMessages } from '../components/block-removal-warning-modal';
10
-
11
6
  const castArray = ( maybeArray ) =>
12
7
  Array.isArray( maybeArray ) ? maybeArray : [ maybeArray ];
13
8
 
@@ -28,13 +23,15 @@ const privateSettings = [
28
23
  * Action that updates the block editor settings and
29
24
  * conditionally preserves the experimental ones.
30
25
  *
31
- * @param {Object} settings Updated settings
32
- * @param {boolean} stripExperimentalSettings Whether to strip experimental settings.
26
+ * @param {Object} settings Updated settings
27
+ * @param {Object} options Options object.
28
+ * @param {boolean} options.stripExperimentalSettings Whether to strip experimental settings.
29
+ * @param {boolean} options.reset Whether to reset the settings.
33
30
  * @return {Object} Action object
34
31
  */
35
32
  export function __experimentalUpdateSettings(
36
33
  settings,
37
- stripExperimentalSettings = false
34
+ { stripExperimentalSettings = false, reset = false } = {}
38
35
  ) {
39
36
  let cleanSettings = settings;
40
37
  // There are no plugins in the mobile apps, so there is no
@@ -50,6 +47,7 @@ export function __experimentalUpdateSettings(
50
47
  return {
51
48
  type: 'UPDATE_SETTINGS',
52
49
  settings: cleanSettings,
50
+ reset,
53
51
  };
54
52
  }
55
53
 
@@ -155,35 +153,22 @@ export const privateRemoveBlocks =
155
153
  // confirmation that they intended to remove such block(s). However,
156
154
  // the editor instance is responsible for presenting those confirmation
157
155
  // prompts to the user. Any instance opting into removal prompts must
158
- // register using `toggleRemovalPromptSupport()`.
156
+ // register using `setBlockRemovalRules()`.
159
157
  //
160
158
  // @see https://github.com/WordPress/gutenberg/pull/51145
161
- if (
162
- ! forceRemove &&
163
- // FIXME: Without this existence check, the unit tests for
164
- // `__experimentalDeleteReusableBlock` in
165
- // `packages/reusable-blocks/src/store/test/actions.js` fail due to
166
- // the fact that the `registry` object passed to the thunk actions
167
- // doesn't include this private action. This needs to be
168
- // investigated to understand whether it's a real smell or if it's
169
- // because not all store code has been updated to accommodate
170
- // private selectors.
171
- select.isRemovalPromptSupported &&
172
- select.isRemovalPromptSupported()
173
- ) {
159
+ const rules = ! forceRemove && select.getBlockRemovalRules();
160
+ if ( rules ) {
174
161
  const blockNamesForPrompt = new Set();
175
162
 
176
163
  // Given a list of client IDs of blocks that the user intended to
177
164
  // remove, perform a tree search (BFS) to find all block names
178
165
  // corresponding to "important" blocks, i.e. blocks that require a
179
166
  // removal prompt.
180
- //
181
- // @see blockTypePromptMessages
182
167
  const queue = [ ...clientIds ];
183
168
  while ( queue.length ) {
184
169
  const clientId = queue.shift();
185
170
  const blockName = select.getBlockName( clientId );
186
- if ( blockTypePromptMessages[ blockName ] ) {
171
+ if ( rules[ blockName ] ) {
187
172
  blockNamesForPrompt.add( blockName );
188
173
  }
189
174
  const innerBlocks = select.getBlockOrder( clientId );
@@ -194,7 +179,7 @@ export const privateRemoveBlocks =
194
179
  // skip any other steps (thus postponing actual removal).
195
180
  if ( blockNamesForPrompt.size ) {
196
181
  dispatch(
197
- displayRemovalPrompt(
182
+ displayBlockRemovalPrompt(
198
183
  clientIds,
199
184
  selectPrevious,
200
185
  Array.from( blockNamesForPrompt )
@@ -246,7 +231,7 @@ export const ensureDefaultBlock =
246
231
  * Returns an action object used in signalling that a block removal prompt must
247
232
  * be displayed.
248
233
  *
249
- * Contrast with `toggleRemovalPromptSupport`.
234
+ * Contrast with `setBlockRemovalRules`.
250
235
  *
251
236
  * @param {string|string[]} clientIds Client IDs of blocks to remove.
252
237
  * @param {boolean} selectPrevious True if the previous block
@@ -254,16 +239,19 @@ export const ensureDefaultBlock =
254
239
  * (if no previous block exists)
255
240
  * should be selected
256
241
  * when a block is removed.
257
- * @param {string[]} blockNamesForPrompt Names of blocks requiring user
242
+ * @param {string[]} blockNamesForPrompt Names of the blocks that
243
+ * triggered the need for
244
+ * confirmation before removal.
245
+ *
258
246
  * @return {Object} Action object.
259
247
  */
260
- export function displayRemovalPrompt(
248
+ function displayBlockRemovalPrompt(
261
249
  clientIds,
262
250
  selectPrevious,
263
251
  blockNamesForPrompt
264
252
  ) {
265
253
  return {
266
- type: 'DISPLAY_REMOVAL_PROMPT',
254
+ type: 'DISPLAY_BLOCK_REMOVAL_PROMPT',
267
255
  clientIds,
268
256
  selectPrevious,
269
257
  blockNamesForPrompt,
@@ -277,24 +265,36 @@ export function displayRemovalPrompt(
277
265
  *
278
266
  * @return {Object} Action object.
279
267
  */
280
- export function clearRemovalPrompt() {
268
+ export function clearBlockRemovalPrompt() {
281
269
  return {
282
- type: 'CLEAR_REMOVAL_PROMPT',
270
+ type: 'CLEAR_BLOCK_REMOVAL_PROMPT',
283
271
  };
284
272
  }
285
273
 
286
274
  /**
287
- * Returns an action object used in signalling that a removal prompt display
288
- * mechanism is available or unavailable in the current editor.
275
+ * Returns an action object used to set up any rules that a block editor may
276
+ * provide in order to prevent a user from accidentally removing certain
277
+ * blocks. These rules are then used to display a confirmation prompt to the
278
+ * user. For instance, in the Site Editor, the Query Loop block is important
279
+ * enough to warrant such confirmation.
280
+ *
281
+ * IMPORTANT: Registering rules implicitly signals to the `privateRemoveBlocks`
282
+ * action that the editor will be responsible for displaying block removal
283
+ * prompts and confirming deletions. This action is meant to be used by
284
+ * component `BlockRemovalWarningModal` only.
285
+ *
286
+ * The data is a record whose keys are block types (e.g. 'core/query') and
287
+ * whose values are the explanation to be shown to users (e.g. 'Query Loop
288
+ * displays a list of posts or pages.').
289
289
  *
290
- * Contrast with `displayRemovalPrompt`.
290
+ * Contrast with `displayBlockRemovalPrompt`.
291
291
  *
292
- * @param {boolean} status Whether a prompt display mechanism exists.
292
+ * @param {Record<string,string>|false} rules Block removal rules.
293
293
  * @return {Object} Action object.
294
294
  */
295
- export function toggleRemovalPromptSupport( status = true ) {
295
+ export function setBlockRemovalRules( rules = false ) {
296
296
  return {
297
- type: 'TOGGLE_REMOVAL_PROMPT_SUPPORT',
298
- status,
297
+ type: 'SET_BLOCK_REMOVAL_RULES',
298
+ rules,
299
299
  };
300
300
  }
@@ -205,6 +205,6 @@ export function getRemovalPromptData( state ) {
205
205
  *
206
206
  * @return {boolean} Whether removal prompt exists.
207
207
  */
208
- export function isRemovalPromptSupported( state ) {
209
- return state.isRemovalPromptSupported;
208
+ export function getBlockRemovalRules( state ) {
209
+ return state.blockRemovalRules;
210
210
  }
@@ -1480,14 +1480,14 @@ export function isSelectionEnabled( state = true, action ) {
1480
1480
  */
1481
1481
  function removalPromptData( state = false, action ) {
1482
1482
  switch ( action.type ) {
1483
- case 'DISPLAY_REMOVAL_PROMPT':
1483
+ case 'DISPLAY_BLOCK_REMOVAL_PROMPT':
1484
1484
  const { clientIds, selectPrevious, blockNamesForPrompt } = action;
1485
1485
  return {
1486
1486
  clientIds,
1487
1487
  selectPrevious,
1488
1488
  blockNamesForPrompt,
1489
1489
  };
1490
- case 'CLEAR_REMOVAL_PROMPT':
1490
+ case 'CLEAR_BLOCK_REMOVAL_PROMPT':
1491
1491
  return false;
1492
1492
  }
1493
1493
 
@@ -1495,17 +1495,25 @@ function removalPromptData( state = false, action ) {
1495
1495
  }
1496
1496
 
1497
1497
  /**
1498
- * Reducer prompt availability state.
1498
+ * Reducer returning any rules that a block editor may provide in order to
1499
+ * prevent a user from accidentally removing certain blocks. These rules are
1500
+ * then used to display a confirmation prompt to the user. For instance, in the
1501
+ * Site Editor, the Query Loop block is important enough to warrant such
1502
+ * confirmation.
1503
+ *
1504
+ * The data is a record whose keys are block types (e.g. 'core/query') and
1505
+ * whose values are the explanation to be shown to users (e.g. 'Query Loop
1506
+ * displays a list of posts or pages.').
1499
1507
  *
1500
1508
  * @param {boolean} state Current state.
1501
1509
  * @param {Object} action Dispatched action.
1502
1510
  *
1503
- * @return {boolean} Updated state.
1511
+ * @return {Record<string,string>} Updated state.
1504
1512
  */
1505
- function isRemovalPromptSupported( state = false, action ) {
1513
+ function blockRemovalRules( state = false, action ) {
1506
1514
  switch ( action.type ) {
1507
- case 'TOGGLE_REMOVAL_PROMPT_SUPPORT':
1508
- return action.status;
1515
+ case 'SET_BLOCK_REMOVAL_RULES':
1516
+ return action.rules;
1509
1517
  }
1510
1518
 
1511
1519
  return state;
@@ -1623,6 +1631,12 @@ export function template( state = { isValid: true }, action ) {
1623
1631
  export function settings( state = SETTINGS_DEFAULTS, action ) {
1624
1632
  switch ( action.type ) {
1625
1633
  case 'UPDATE_SETTINGS':
1634
+ if ( action.reset ) {
1635
+ return {
1636
+ ...SETTINGS_DEFAULTS,
1637
+ ...action.settings,
1638
+ };
1639
+ }
1626
1640
  return {
1627
1641
  ...state,
1628
1642
  ...action.settings,
@@ -1924,7 +1938,7 @@ const combinedReducers = combineReducers( {
1924
1938
  blockVisibility,
1925
1939
  blockEditingModes,
1926
1940
  removalPromptData,
1927
- isRemovalPromptSupported,
1941
+ blockRemovalRules,
1928
1942
  } );
1929
1943
 
1930
1944
  function withAutomaticChangeReset( reducer ) {