@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
@@ -0,0 +1,212 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useState } from '@wordpress/element';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import AspectRatioTool from './aspect-ratio-tool';
10
+ import ScaleTool from './scale-tool';
11
+ import WidthHeightTool from './width-height-tool';
12
+
13
+ /**
14
+ * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps
15
+ */
16
+
17
+ /**
18
+ * @typedef {import('@wordpress/components/build-types/unit-control/types').WPUnitControlUnit} WPUnitControlUnit
19
+ */
20
+
21
+ /**
22
+ * @typedef {Object} Dimensions
23
+ * @property {string} [width] CSS width property.
24
+ * @property {string} [height] CSS height property.
25
+ * @property {string} [scale] CSS object-fit property.
26
+ * @property {string} [aspectRatio] CSS aspect-ratio property.
27
+ */
28
+
29
+ /**
30
+ * @callback DimensionsControlsOnChange
31
+ * @param {Dimensions} nextValue
32
+ * @return {void}
33
+ */
34
+
35
+ /**
36
+ * @typedef {Object} DimensionsControlsProps
37
+ * @property {string} [panelId] ID of the panel that contains the controls.
38
+ * @property {Dimensions} [value] Current dimensions values.
39
+ * @property {DimensionsControlsOnChange} [onChange] Callback to update the dimensions values.
40
+ * @property {SelectControlProps[]} [aspectRatioOptions] Aspect ratio options.
41
+ * @property {SelectControlProps[]} [scaleOptions] Scale options.
42
+ * @property {WPUnitControlUnit[]} [unitsOptions] Units options.
43
+ */
44
+
45
+ /**
46
+ * Component that renders controls to edit the dimensions of an image or container.
47
+ *
48
+ * @param {DimensionsControlsProps} props The component props.
49
+ *
50
+ * @return {WPElement} The dimensions controls.
51
+ */
52
+ function DimensionsTool( {
53
+ panelId,
54
+ value = {},
55
+ onChange = () => {},
56
+ aspectRatioOptions, // Default options handled by AspectRatioTool.
57
+ defaultAspectRatio = 'auto', // Match CSS default value for aspect-ratio.
58
+ scaleOptions, // Default options handled by ScaleTool.
59
+ defaultScale = 'fill', // Match CSS default value for object-fit.
60
+ unitsOptions, // Default options handled by UnitControl.
61
+ } ) {
62
+ // Coerce undefined and CSS default values to be null.
63
+ const width =
64
+ value.width === undefined || value.width === 'auto'
65
+ ? null
66
+ : value.width;
67
+ const height =
68
+ value.height === undefined || value.height === 'auto'
69
+ ? null
70
+ : value.height;
71
+ const aspectRatio =
72
+ value.aspectRatio === undefined || value.aspectRatio === 'auto'
73
+ ? null
74
+ : value.aspectRatio;
75
+ const scale =
76
+ value.scale === undefined || value.scale === 'fill'
77
+ ? null
78
+ : value.scale;
79
+
80
+ // Keep track of state internally, so when the value is cleared by means
81
+ // other than directly editing that field, it's easier to restore the
82
+ // previous value.
83
+ const [ lastScale, setLastScale ] = useState( scale );
84
+ const [ lastAspectRatio, setLastAspectRatio ] = useState( aspectRatio );
85
+
86
+ // 'custom' is not a valid value for CSS aspect-ratio, but it is used in the
87
+ // dropdown to indicate that setting both the width and height is the same
88
+ // as a custom aspect ratio.
89
+ const aspectRatioValue = width && height ? 'custom' : lastAspectRatio;
90
+
91
+ const showScaleControl = aspectRatio || ( width && height );
92
+
93
+ return (
94
+ <>
95
+ <AspectRatioTool
96
+ panelId={ panelId }
97
+ options={ aspectRatioOptions }
98
+ defaultValue={ defaultAspectRatio }
99
+ value={ aspectRatioValue }
100
+ onChange={ ( nextAspectRatio ) => {
101
+ const nextValue = { ...value };
102
+
103
+ // 'auto' is CSS default, so it gets treated as null.
104
+ nextAspectRatio =
105
+ nextAspectRatio === 'auto' ? null : nextAspectRatio;
106
+
107
+ setLastAspectRatio( nextAspectRatio );
108
+
109
+ // Update aspectRatio.
110
+ if ( ! nextAspectRatio ) {
111
+ delete nextValue.aspectRatio;
112
+ } else {
113
+ nextValue.aspectRatio = nextAspectRatio;
114
+ }
115
+
116
+ // Auto-update scale.
117
+ if ( ! nextAspectRatio ) {
118
+ delete nextValue.scale;
119
+ } else if ( lastScale ) {
120
+ nextValue.scale = lastScale;
121
+ } else {
122
+ nextValue.scale = defaultScale;
123
+ setLastScale( defaultScale );
124
+ }
125
+
126
+ // Auto-update width and height.
127
+ if ( nextAspectRatio && width && height ) {
128
+ delete nextValue.height;
129
+ }
130
+
131
+ onChange( nextValue );
132
+ } }
133
+ />
134
+ { showScaleControl && (
135
+ <ScaleTool
136
+ panelId={ panelId }
137
+ options={ scaleOptions }
138
+ defaultValue={ defaultScale }
139
+ value={ lastScale }
140
+ onChange={ ( nextScale ) => {
141
+ const nextValue = { ...value };
142
+
143
+ // 'fill' is CSS default, so it gets treated as null.
144
+ nextScale = nextScale === 'fill' ? null : nextScale;
145
+
146
+ setLastScale( nextScale );
147
+
148
+ // Update scale.
149
+ if ( ! nextScale ) {
150
+ delete nextValue.scale;
151
+ } else {
152
+ nextValue.scale = nextScale;
153
+ }
154
+
155
+ onChange( nextValue );
156
+ } }
157
+ />
158
+ ) }
159
+ <WidthHeightTool
160
+ panelId={ panelId }
161
+ units={ unitsOptions }
162
+ value={ { width, height } }
163
+ onChange={ ( { width: nextWidth, height: nextHeight } ) => {
164
+ const nextValue = { ...value };
165
+
166
+ // 'auto' is CSS default, so it gets treated as null.
167
+ nextWidth = nextWidth === 'auto' ? null : nextWidth;
168
+ nextHeight = nextHeight === 'auto' ? null : nextHeight;
169
+
170
+ // Update width.
171
+ if ( ! nextWidth ) {
172
+ delete nextValue.width;
173
+ } else {
174
+ nextValue.width = nextWidth;
175
+ }
176
+
177
+ // Update height.
178
+ if ( ! nextHeight ) {
179
+ delete nextValue.height;
180
+ } else {
181
+ nextValue.height = nextHeight;
182
+ }
183
+
184
+ // Auto-update aspectRatio.
185
+ if ( nextWidth && nextHeight ) {
186
+ delete nextValue.aspectRatio;
187
+ } else if ( lastAspectRatio ) {
188
+ nextValue.aspectRatio = lastAspectRatio;
189
+ } else {
190
+ // No setting defaultAspectRatio here, because
191
+ // aspectRatio is optional in this scenario,
192
+ // unlike scale.
193
+ }
194
+
195
+ // Auto-update scale.
196
+ if ( ! lastAspectRatio && !! nextWidth !== !! nextHeight ) {
197
+ delete nextValue.scale;
198
+ } else if ( lastScale ) {
199
+ nextValue.scale = lastScale;
200
+ } else {
201
+ nextValue.scale = defaultScale;
202
+ setLastScale( defaultScale );
203
+ }
204
+
205
+ onChange( nextValue );
206
+ } }
207
+ />
208
+ </>
209
+ );
210
+ }
211
+
212
+ export default DimensionsTool;
@@ -0,0 +1,124 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ __experimentalToolsPanelItem as ToolsPanelItem,
6
+ __experimentalToggleGroupControl as ToggleGroupControl,
7
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
8
+ } from '@wordpress/components';
9
+ import { useMemo } from '@wordpress/element';
10
+ import { __, _x } from '@wordpress/i18n';
11
+
12
+ /**
13
+ * @typedef {import('@wordpress/components/build-types/select-control/types').SelectControlProps} SelectControlProps
14
+ */
15
+
16
+ /**
17
+ * The descriptions are purposely made generic as object-fit could be used for
18
+ * any replaced element. Provide your own set of options if you need different
19
+ * help text or labels.
20
+ *
21
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element
22
+ *
23
+ * @type {SelectControlProps[]}
24
+ */
25
+ const DEFAULT_SCALE_OPTIONS = [
26
+ {
27
+ value: 'fill',
28
+ label: _x( 'Fill', 'Scale option for dimensions control' ),
29
+ help: __( 'Fill the space by stretching the content.' ),
30
+ },
31
+ {
32
+ value: 'contain',
33
+ label: _x( 'Contain', 'Scale option for dimensions control' ),
34
+ help: __( 'Fit the content to the space without clipping.' ),
35
+ },
36
+ {
37
+ value: 'cover',
38
+ label: _x( 'Cover', 'Scale option for dimensions control' ),
39
+ help: __( "Fill the space by clipping what doesn't fit." ),
40
+ },
41
+ {
42
+ value: 'none',
43
+ label: _x( 'None', 'Scale option for dimensions control' ),
44
+ help: __(
45
+ 'Do not adjust the sizing of the content. Content that is too large will be clipped, and content that is too small will have additional padding.'
46
+ ),
47
+ },
48
+ {
49
+ value: 'scale-down',
50
+ label: _x( 'Scale down', 'Scale option for dimensions control' ),
51
+ help: __(
52
+ 'Scale down the content to fit the space if it is too big. Content that is too small will have additional padding.'
53
+ ),
54
+ },
55
+ ];
56
+
57
+ /**
58
+ * @callback ScaleToolPropsOnChange
59
+ * @param {string} nextValue New scale value.
60
+ * @return {void}
61
+ */
62
+
63
+ /**
64
+ * @typedef {Object} ScaleToolProps
65
+ * @property {string} [panelId] ID of the panel that contains the controls.
66
+ * @property {string} [value] Current scale value.
67
+ * @property {ScaleToolPropsOnChange} [onChange] Callback to update the scale value.
68
+ * @property {SelectControlProps[]} [options] Scale options.
69
+ * @property {string} [defaultValue] Default scale value.
70
+ * @property {boolean} [showControl=true] Whether to show the control.
71
+ * @property {boolean} [isShownByDefault=true] Whether the tool panel is shown by default.
72
+ */
73
+
74
+ /**
75
+ * A tool to select the CSS object-fit property for the image.
76
+ *
77
+ * @param {ScaleToolProps} props
78
+ *
79
+ * @return {import('@wordpress/element').WPElement} The scale tool.
80
+ */
81
+ export default function ScaleTool( {
82
+ panelId,
83
+ value,
84
+ onChange,
85
+ options = DEFAULT_SCALE_OPTIONS,
86
+ defaultValue = DEFAULT_SCALE_OPTIONS[ 0 ].value,
87
+ isShownByDefault = true,
88
+ } ) {
89
+ // Match the CSS default so if the value is used directly in CSS it will look correct in the control.
90
+ const displayValue = value ?? 'fill';
91
+
92
+ const scaleHelp = useMemo( () => {
93
+ return options.reduce( ( acc, option ) => {
94
+ acc[ option.value ] = option.help;
95
+ return acc;
96
+ }, {} );
97
+ }, [ options ] );
98
+
99
+ return (
100
+ <ToolsPanelItem
101
+ label={ __( 'Scale' ) }
102
+ isShownByDefault={ isShownByDefault }
103
+ hasValue={ () => displayValue !== defaultValue }
104
+ onDeselect={ () => onChange( defaultValue ) }
105
+ panelId={ panelId }
106
+ >
107
+ <ToggleGroupControl
108
+ label={ __( 'Scale' ) }
109
+ isBlock
110
+ help={ scaleHelp[ displayValue ] }
111
+ value={ displayValue }
112
+ onChange={ onChange }
113
+ __nextHasNoMarginBottom
114
+ >
115
+ { options.map( ( option ) => (
116
+ <ToggleGroupControlOption
117
+ key={ option.value }
118
+ { ...option }
119
+ />
120
+ ) ) }
121
+ </ToggleGroupControl>
122
+ </ToolsPanelItem>
123
+ );
124
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useState } from '@wordpress/element';
5
+ import {
6
+ Panel,
7
+ __experimentalToolsPanel as ToolsPanel,
8
+ } from '@wordpress/components';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import AspectRatioTool from '../aspect-ratio-tool';
14
+
15
+ export default {
16
+ title: 'BlockEditor (Private APIs)/DimensionsTool/AspectRatioTool',
17
+ component: AspectRatioTool,
18
+ argTypes: {
19
+ panelId: { control: { type: null } },
20
+ onChange: { action: 'changed' },
21
+ },
22
+ };
23
+
24
+ export const Default = ( { panelId, onChange: onChangeProp, ...props } ) => {
25
+ const [ value, setValue ] = useState( undefined );
26
+ const resetAll = () => {
27
+ setValue( undefined );
28
+ onChangeProp( undefined );
29
+ };
30
+ return (
31
+ <Panel>
32
+ <ToolsPanel
33
+ label="Aspect Ratio"
34
+ panelId={ panelId }
35
+ resetAll={ resetAll }
36
+ >
37
+ <AspectRatioTool
38
+ panelId={ panelId }
39
+ onChange={ ( nextValue ) => {
40
+ setValue( nextValue );
41
+ onChangeProp( nextValue );
42
+ } }
43
+ value={ value }
44
+ { ...props }
45
+ />
46
+ </ToolsPanel>
47
+ </Panel>
48
+ );
49
+ };
50
+ Default.args = {
51
+ panelId: 'panel-id',
52
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useState } from '@wordpress/element';
5
+ import {
6
+ Panel,
7
+ __experimentalToolsPanel as ToolsPanel,
8
+ } from '@wordpress/components';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import DimensionsTool from '..';
14
+
15
+ export default {
16
+ title: 'BlockEditor (Private APIs)/DimensionsTool',
17
+ component: DimensionsTool,
18
+ argTypes: {
19
+ panelId: { control: { type: null } },
20
+ onChange: { action: 'changed' },
21
+ },
22
+ };
23
+
24
+ const EMPTY_OBJECT = {};
25
+
26
+ export const Default = ( { panelId, onChange, ...props } ) => {
27
+ const [ value, setValue ] = useState( EMPTY_OBJECT );
28
+ const resetAll = () => {
29
+ setValue( EMPTY_OBJECT );
30
+ onChange( EMPTY_OBJECT );
31
+ };
32
+ return (
33
+ <Panel>
34
+ <ToolsPanel
35
+ label="Dimensions"
36
+ panelId={ panelId }
37
+ resetAll={ resetAll }
38
+ >
39
+ <DimensionsTool
40
+ panelId={ panelId }
41
+ onChange={ ( nextValue ) => {
42
+ setValue( nextValue );
43
+ onChange( nextValue );
44
+ } }
45
+ value={ value }
46
+ { ...props }
47
+ />
48
+ </ToolsPanel>
49
+ </Panel>
50
+ );
51
+ };
52
+ Default.args = {
53
+ panelId: 'panel-id',
54
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useState } from '@wordpress/element';
5
+ import {
6
+ Panel,
7
+ __experimentalToolsPanel as ToolsPanel,
8
+ } from '@wordpress/components';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import ScaleTool from '../scale-tool';
14
+
15
+ export default {
16
+ title: 'BlockEditor (Private APIs)/DimensionsTool/ScaleTool',
17
+ component: ScaleTool,
18
+ argTypes: {
19
+ panelId: { control: { type: null } },
20
+ onChange: { action: 'changed' },
21
+ },
22
+ };
23
+
24
+ export const Default = ( { panelId, onChange: onChangeProp, ...props } ) => {
25
+ const [ value, setValue ] = useState( undefined );
26
+ const resetAll = () => {
27
+ setValue( undefined );
28
+ onChangeProp( undefined );
29
+ };
30
+ return (
31
+ <Panel>
32
+ <ToolsPanel label="Scale" panelId={ panelId } resetAll={ resetAll }>
33
+ <ScaleTool
34
+ panelId={ panelId }
35
+ onChange={ ( nextValue ) => {
36
+ setValue( nextValue );
37
+ onChangeProp( nextValue );
38
+ } }
39
+ value={ value }
40
+ { ...props }
41
+ />
42
+ </ToolsPanel>
43
+ </Panel>
44
+ );
45
+ };
46
+ Default.args = {
47
+ panelId: 'panel-id',
48
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useState } from '@wordpress/element';
5
+ import {
6
+ Panel,
7
+ __experimentalToolsPanel as ToolsPanel,
8
+ } from '@wordpress/components';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import WidthHeightTool from '../width-height-tool';
14
+
15
+ export default {
16
+ title: 'BlockEditor (Private APIs)/DimensionsTool/WidthHeightTool',
17
+ component: WidthHeightTool,
18
+ argTypes: {
19
+ panelId: { control: { type: null } },
20
+ onChange: { action: 'changed' },
21
+ },
22
+ };
23
+
24
+ const EMPTY_OBJECT = {};
25
+
26
+ export const Default = ( { panelId, onChange: onChangeProp, ...props } ) => {
27
+ const [ value, setValue ] = useState( EMPTY_OBJECT );
28
+ const resetAll = () => {
29
+ setValue( EMPTY_OBJECT );
30
+ onChangeProp( EMPTY_OBJECT );
31
+ };
32
+ return (
33
+ <Panel>
34
+ <ToolsPanel
35
+ label="Width & Height"
36
+ panelId={ panelId }
37
+ resetAll={ resetAll }
38
+ >
39
+ <WidthHeightTool
40
+ panelId={ panelId }
41
+ onChange={ ( nextValue ) => {
42
+ setValue( nextValue );
43
+ onChangeProp( nextValue );
44
+ } }
45
+ value={ value }
46
+ { ...props }
47
+ />
48
+ </ToolsPanel>
49
+ </Panel>
50
+ );
51
+ };
52
+ Default.args = {
53
+ panelId: 'panel-id',
54
+ };