@wordpress/block-editor 11.4.0 → 11.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 (288) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/components/block-inspector/index.js +11 -10
  3. package/build/components/block-inspector/index.js.map +1 -1
  4. package/build/components/block-inspector/useBlockInspectorAnimationSettings.js +46 -0
  5. package/build/components/block-inspector/useBlockInspectorAnimationSettings.js.map +1 -0
  6. package/build/components/block-lock/modal.js +1 -0
  7. package/build/components/block-lock/modal.js.map +1 -1
  8. package/build/components/block-settings-menu/block-settings-dropdown.js +2 -2
  9. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  10. package/build/components/block-styles/index.js +2 -1
  11. package/build/components/block-styles/index.js.map +1 -1
  12. package/build/components/child-layout-control/index.js +107 -0
  13. package/build/components/child-layout-control/index.js.map +1 -0
  14. package/build/components/date-format-picker/index.js +3 -3
  15. package/build/components/date-format-picker/index.js.map +1 -1
  16. package/build/components/global-styles/dimensions-panel.js +594 -0
  17. package/build/components/global-styles/dimensions-panel.js.map +1 -0
  18. package/build/components/global-styles/hooks.js +72 -36
  19. package/build/components/global-styles/hooks.js.map +1 -1
  20. package/build/components/global-styles/index.js +20 -6
  21. package/build/components/global-styles/index.js.map +1 -1
  22. package/build/components/global-styles/typography-panel.js +25 -12
  23. package/build/components/global-styles/typography-panel.js.map +1 -1
  24. package/build/components/global-styles/use-global-styles-output.js +1 -1
  25. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  26. package/build/components/global-styles/utils.js +2 -0
  27. package/build/components/global-styles/utils.js.map +1 -1
  28. package/build/components/index.native.js +23 -0
  29. package/build/components/index.native.js.map +1 -1
  30. package/build/components/inserter/media-tab/hooks.js +10 -11
  31. package/build/components/inserter/media-tab/hooks.js.map +1 -1
  32. package/build/components/inserter/media-tab/media-list.js +5 -108
  33. package/build/components/inserter/media-tab/media-list.js.map +1 -1
  34. package/build/components/inserter/media-tab/media-preview.js +242 -0
  35. package/build/components/inserter/media-tab/media-preview.js.map +1 -0
  36. package/build/components/inspector-controls/block-support-tools-panel.js +1 -1
  37. package/build/components/inspector-controls/block-support-tools-panel.js.map +1 -1
  38. package/build/components/inspector-controls/fill.js +38 -9
  39. package/build/components/inspector-controls/fill.js.map +1 -1
  40. package/build/components/link-control/settings-drawer.js +1 -1
  41. package/build/components/link-control/settings-drawer.js.map +1 -1
  42. package/build/components/link-control/settings.js +1 -0
  43. package/build/components/link-control/settings.js.map +1 -1
  44. package/build/components/list-view/block.js +17 -3
  45. package/build/components/list-view/block.js.map +1 -1
  46. package/build/components/list-view/branch.js +2 -2
  47. package/build/components/list-view/branch.js.map +1 -1
  48. package/build/components/list-view/expander.js +2 -1
  49. package/build/components/list-view/expander.js.map +1 -1
  50. package/build/components/list-view/leaf.js +10 -6
  51. package/build/components/list-view/leaf.js.map +1 -1
  52. package/build/components/list-view/use-list-view-scroll-into-view.js +51 -0
  53. package/build/components/list-view/use-list-view-scroll-into-view.js.map +1 -0
  54. package/build/components/off-canvas-editor/appender.js +5 -10
  55. package/build/components/off-canvas-editor/appender.js.map +1 -1
  56. package/build/components/off-canvas-editor/branch.js +1 -0
  57. package/build/components/off-canvas-editor/branch.js.map +1 -1
  58. package/build/components/off-canvas-editor/index.js +7 -3
  59. package/build/components/off-canvas-editor/index.js.map +1 -1
  60. package/build/components/off-canvas-editor/leaf-more-menu.js +34 -4
  61. package/build/components/off-canvas-editor/leaf-more-menu.js.map +1 -1
  62. package/build/components/off-canvas-editor/link-ui.js +1 -0
  63. package/build/components/off-canvas-editor/link-ui.js.map +1 -1
  64. package/build/components/responsive-block-control/index.js +1 -0
  65. package/build/components/responsive-block-control/index.js.map +1 -1
  66. package/build/components/rich-text/index.js +9 -43
  67. package/build/components/rich-text/index.js.map +1 -1
  68. package/build/components/rich-text/use-delete.js +73 -0
  69. package/build/components/rich-text/use-delete.js.map +1 -0
  70. package/build/components/rich-text/use-input-rules.js +14 -6
  71. package/build/components/rich-text/use-input-rules.js.map +1 -1
  72. package/build/components/writing-flow/use-selection-observer.js +4 -1
  73. package/build/components/writing-flow/use-selection-observer.js.map +1 -1
  74. package/build/hooks/align.js +3 -1
  75. package/build/hooks/align.js.map +1 -1
  76. package/build/hooks/dimensions.js +72 -190
  77. package/build/hooks/dimensions.js.map +1 -1
  78. package/build/hooks/duotone.js +94 -25
  79. package/build/hooks/duotone.js.map +1 -1
  80. package/build/hooks/gap.js +0 -202
  81. package/build/hooks/gap.js.map +1 -1
  82. package/build/hooks/layout.js +14 -5
  83. package/build/hooks/layout.js.map +1 -1
  84. package/build/hooks/margin.js +7 -163
  85. package/build/hooks/margin.js.map +1 -1
  86. package/build/hooks/padding.js +7 -163
  87. package/build/hooks/padding.js.map +1 -1
  88. package/build/hooks/typography.js +50 -65
  89. package/build/hooks/typography.js.map +1 -1
  90. package/build/hooks/utils.js +75 -0
  91. package/build/hooks/utils.js.map +1 -1
  92. package/build/layouts/flex.js +1 -0
  93. package/build/layouts/flex.js.map +1 -1
  94. package/build/store/actions.js +24 -12
  95. package/build/store/actions.js.map +1 -1
  96. package/build/store/defaults.js +28 -1
  97. package/build/store/defaults.js.map +1 -1
  98. package/build/store/reducer.js +53 -47
  99. package/build/store/reducer.js.map +1 -1
  100. package/build/store/selectors.js +5 -1
  101. package/build/store/selectors.js.map +1 -1
  102. package/build/utils/parse-css-unit-to-px.js +36 -3
  103. package/build/utils/parse-css-unit-to-px.js.map +1 -1
  104. package/build-module/components/block-inspector/index.js +9 -9
  105. package/build-module/components/block-inspector/index.js.map +1 -1
  106. package/build-module/components/block-inspector/useBlockInspectorAnimationSettings.js +37 -0
  107. package/build-module/components/block-inspector/useBlockInspectorAnimationSettings.js.map +1 -0
  108. package/build-module/components/block-lock/modal.js +1 -0
  109. package/build-module/components/block-lock/modal.js.map +1 -1
  110. package/build-module/components/block-settings-menu/block-settings-dropdown.js +2 -2
  111. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  112. package/build-module/components/block-styles/index.js +2 -1
  113. package/build-module/components/block-styles/index.js.map +1 -1
  114. package/build-module/components/child-layout-control/index.js +98 -0
  115. package/build-module/components/child-layout-control/index.js.map +1 -0
  116. package/build-module/components/date-format-picker/index.js +4 -4
  117. package/build-module/components/date-format-picker/index.js.map +1 -1
  118. package/build-module/components/global-styles/dimensions-panel.js +574 -0
  119. package/build-module/components/global-styles/dimensions-panel.js.map +1 -0
  120. package/build-module/components/global-styles/hooks.js +71 -33
  121. package/build-module/components/global-styles/hooks.js.map +1 -1
  122. package/build-module/components/global-styles/index.js +2 -1
  123. package/build-module/components/global-styles/index.js.map +1 -1
  124. package/build-module/components/global-styles/typography-panel.js +26 -11
  125. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  126. package/build-module/components/global-styles/use-global-styles-output.js +1 -1
  127. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  128. package/build-module/components/global-styles/utils.js +2 -0
  129. package/build-module/components/global-styles/utils.js.map +1 -1
  130. package/build-module/components/index.native.js +2 -1
  131. package/build-module/components/index.native.js.map +1 -1
  132. package/build-module/components/inserter/media-tab/hooks.js +10 -11
  133. package/build-module/components/inserter/media-tab/hooks.js.map +1 -1
  134. package/build-module/components/inserter/media-tab/media-list.js +6 -105
  135. package/build-module/components/inserter/media-tab/media-list.js.map +1 -1
  136. package/build-module/components/inserter/media-tab/media-preview.js +222 -0
  137. package/build-module/components/inserter/media-tab/media-preview.js.map +1 -0
  138. package/build-module/components/inspector-controls/block-support-tools-panel.js +1 -1
  139. package/build-module/components/inspector-controls/block-support-tools-panel.js.map +1 -1
  140. package/build-module/components/inspector-controls/fill.js +39 -9
  141. package/build-module/components/inspector-controls/fill.js.map +1 -1
  142. package/build-module/components/link-control/settings-drawer.js +1 -1
  143. package/build-module/components/link-control/settings-drawer.js.map +1 -1
  144. package/build-module/components/link-control/settings.js +1 -0
  145. package/build-module/components/link-control/settings.js.map +1 -1
  146. package/build-module/components/list-view/block.js +16 -3
  147. package/build-module/components/list-view/block.js.map +1 -1
  148. package/build-module/components/list-view/branch.js +2 -2
  149. package/build-module/components/list-view/branch.js.map +1 -1
  150. package/build-module/components/list-view/expander.js +2 -1
  151. package/build-module/components/list-view/expander.js.map +1 -1
  152. package/build-module/components/list-view/leaf.js +8 -4
  153. package/build-module/components/list-view/leaf.js.map +1 -1
  154. package/build-module/components/list-view/use-list-view-scroll-into-view.js +42 -0
  155. package/build-module/components/list-view/use-list-view-scroll-into-view.js.map +1 -0
  156. package/build-module/components/off-canvas-editor/appender.js +5 -10
  157. package/build-module/components/off-canvas-editor/appender.js.map +1 -1
  158. package/build-module/components/off-canvas-editor/branch.js +1 -0
  159. package/build-module/components/off-canvas-editor/branch.js.map +1 -1
  160. package/build-module/components/off-canvas-editor/index.js +7 -3
  161. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  162. package/build-module/components/off-canvas-editor/leaf-more-menu.js +36 -7
  163. package/build-module/components/off-canvas-editor/leaf-more-menu.js.map +1 -1
  164. package/build-module/components/off-canvas-editor/link-ui.js +1 -0
  165. package/build-module/components/off-canvas-editor/link-ui.js.map +1 -1
  166. package/build-module/components/responsive-block-control/index.js +1 -0
  167. package/build-module/components/responsive-block-control/index.js.map +1 -1
  168. package/build-module/components/rich-text/index.js +9 -43
  169. package/build-module/components/rich-text/index.js.map +1 -1
  170. package/build-module/components/rich-text/use-delete.js +62 -0
  171. package/build-module/components/rich-text/use-delete.js.map +1 -0
  172. package/build-module/components/rich-text/use-input-rules.js +14 -6
  173. package/build-module/components/rich-text/use-input-rules.js.map +1 -1
  174. package/build-module/components/writing-flow/use-selection-observer.js +4 -1
  175. package/build-module/components/writing-flow/use-selection-observer.js.map +1 -1
  176. package/build-module/hooks/align.js +3 -1
  177. package/build-module/hooks/align.js.map +1 -1
  178. package/build-module/hooks/dimensions.js +75 -187
  179. package/build-module/hooks/dimensions.js.map +1 -1
  180. package/build-module/hooks/duotone.js +86 -24
  181. package/build-module/hooks/duotone.js.map +1 -1
  182. package/build-module/hooks/gap.js +0 -183
  183. package/build-module/hooks/gap.js.map +1 -1
  184. package/build-module/hooks/layout.js +14 -5
  185. package/build-module/hooks/layout.js.map +1 -1
  186. package/build-module/hooks/margin.js +4 -143
  187. package/build-module/hooks/margin.js.map +1 -1
  188. package/build-module/hooks/padding.js +4 -143
  189. package/build-module/hooks/padding.js.map +1 -1
  190. package/build-module/hooks/typography.js +52 -65
  191. package/build-module/hooks/typography.js.map +1 -1
  192. package/build-module/hooks/utils.js +70 -0
  193. package/build-module/hooks/utils.js.map +1 -1
  194. package/build-module/layouts/flex.js +1 -0
  195. package/build-module/layouts/flex.js.map +1 -1
  196. package/build-module/store/actions.js +24 -12
  197. package/build-module/store/actions.js.map +1 -1
  198. package/build-module/store/defaults.js +28 -1
  199. package/build-module/store/defaults.js.map +1 -1
  200. package/build-module/store/reducer.js +53 -45
  201. package/build-module/store/reducer.js.map +1 -1
  202. package/build-module/store/selectors.js +5 -1
  203. package/build-module/store/selectors.js.map +1 -1
  204. package/build-module/utils/parse-css-unit-to-px.js +36 -3
  205. package/build-module/utils/parse-css-unit-to-px.js.map +1 -1
  206. package/build-style/style-rtl.css +33 -21
  207. package/build-style/style.css +33 -21
  208. package/package.json +31 -31
  209. package/src/components/block-draggable/test/__snapshots__/index.native.js.snap +24 -24
  210. package/src/components/block-inspector/index.js +11 -14
  211. package/src/components/block-inspector/useBlockInspectorAnimationSettings.js +53 -0
  212. package/src/components/block-lock/modal.js +1 -0
  213. package/src/components/block-lock/style.scss +0 -9
  214. package/src/components/block-mobile-toolbar/test/__snapshots__/block-actions-menu.native.js.snap +20 -20
  215. package/src/components/block-mover/test/__snapshots__/index.native.js.snap +15 -15
  216. package/src/components/block-settings-menu/block-settings-dropdown.js +4 -1
  217. package/src/components/block-styles/index.js +5 -1
  218. package/src/components/child-layout-control/index.js +106 -0
  219. package/src/components/color-palette/test/__snapshots__/control.js.snap +1 -1
  220. package/src/components/date-format-picker/index.js +6 -8
  221. package/src/components/date-format-picker/style.scss +0 -5
  222. package/src/components/global-styles/dimensions-panel.js +627 -0
  223. package/src/components/global-styles/hooks.js +88 -45
  224. package/src/components/global-styles/index.js +5 -1
  225. package/src/components/global-styles/typography-panel.js +33 -8
  226. package/src/components/global-styles/use-global-styles-output.js +4 -3
  227. package/src/components/global-styles/utils.js +2 -0
  228. package/src/components/index.native.js +5 -0
  229. package/src/components/inner-blocks/test/__snapshots__/index.js.snap +1 -1
  230. package/src/components/inserter/media-tab/hooks.js +9 -8
  231. package/src/components/inserter/media-tab/media-list.js +3 -122
  232. package/src/components/inserter/media-tab/media-preview.js +268 -0
  233. package/src/components/inserter/style.scss +22 -0
  234. package/src/components/inserter/test/__snapshots__/index.native.js.snap +15 -15
  235. package/src/components/inspector-controls/block-support-tools-panel.js +0 -1
  236. package/src/components/inspector-controls/fill.js +32 -8
  237. package/src/components/link-control/settings-drawer.js +2 -1
  238. package/src/components/link-control/settings.js +1 -0
  239. package/src/components/link-control/style.scss +18 -8
  240. package/src/components/link-control/test/index.js +3 -3
  241. package/src/components/list-view/block.js +19 -1
  242. package/src/components/list-view/branch.js +1 -2
  243. package/src/components/list-view/expander.js +1 -0
  244. package/src/components/list-view/leaf.js +43 -29
  245. package/src/components/list-view/use-list-view-scroll-into-view.js +48 -0
  246. package/src/components/media-replace-flow/style.scss +7 -9
  247. package/src/components/off-canvas-editor/appender.js +13 -16
  248. package/src/components/off-canvas-editor/branch.js +1 -0
  249. package/src/components/off-canvas-editor/index.js +8 -2
  250. package/src/components/off-canvas-editor/leaf-more-menu.js +57 -15
  251. package/src/components/off-canvas-editor/link-ui.js +1 -0
  252. package/src/components/responsive-block-control/index.js +1 -0
  253. package/src/components/rich-text/index.js +8 -44
  254. package/src/components/rich-text/use-delete.js +59 -0
  255. package/src/components/rich-text/use-input-rules.js +13 -5
  256. package/src/components/spacing-sizes-control/style.scss +1 -1
  257. package/src/components/url-popover/stories/index.js +1 -0
  258. package/src/components/writing-flow/use-selection-observer.js +5 -1
  259. package/src/hooks/align.js +1 -1
  260. package/src/hooks/dimensions.js +85 -269
  261. package/src/hooks/duotone.js +100 -30
  262. package/src/hooks/gap.js +0 -208
  263. package/src/hooks/layout.js +19 -6
  264. package/src/hooks/margin.js +1 -164
  265. package/src/hooks/padding.js +1 -163
  266. package/src/hooks/test/__snapshots__/align.native.js.snap +24 -24
  267. package/src/hooks/test/duotone.js +102 -0
  268. package/src/hooks/typography.js +66 -88
  269. package/src/hooks/utils.js +90 -0
  270. package/src/layouts/flex.js +1 -0
  271. package/src/store/actions.js +12 -4
  272. package/src/store/defaults.js +14 -1
  273. package/src/store/reducer.js +68 -43
  274. package/src/store/selectors.js +8 -1
  275. package/src/store/test/actions.js +4 -2
  276. package/src/utils/parse-css-unit-to-px.js +35 -5
  277. package/src/utils/test/parse-css-unit-to-px.js +12 -0
  278. package/tsconfig.tsbuildinfo +1 -1
  279. package/build/hooks/child-layout.js +0 -213
  280. package/build/hooks/child-layout.js.map +0 -1
  281. package/build/hooks/min-height.js +0 -139
  282. package/build/hooks/min-height.js.map +0 -1
  283. package/build-module/hooks/child-layout.js +0 -193
  284. package/build-module/hooks/child-layout.js.map +0 -1
  285. package/build-module/hooks/min-height.js +0 -116
  286. package/build-module/hooks/min-height.js.map +0 -1
  287. package/src/hooks/child-layout.js +0 -195
  288. package/src/hooks/min-height.js +0 -104
@@ -0,0 +1,627 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { __ } from '@wordpress/i18n';
10
+ import {
11
+ __experimentalToolsPanel as ToolsPanel,
12
+ __experimentalToolsPanelItem as ToolsPanelItem,
13
+ __experimentalBoxControl as BoxControl,
14
+ __experimentalHStack as HStack,
15
+ __experimentalVStack as VStack,
16
+ __experimentalUnitControl as UnitControl,
17
+ __experimentalUseCustomUnits as useCustomUnits,
18
+ __experimentalView as View,
19
+ } from '@wordpress/components';
20
+ import { Icon, positionCenter, stretchWide } from '@wordpress/icons';
21
+ import { useCallback, Platform } from '@wordpress/element';
22
+
23
+ /**
24
+ * Internal dependencies
25
+ */
26
+ import { getValueFromVariable } from './utils';
27
+ import SpacingSizesControl from '../spacing-sizes-control';
28
+ import HeightControl from '../height-control';
29
+ import ChildLayoutControl from '../child-layout-control';
30
+ import { cleanEmptyObject } from '../../hooks/utils';
31
+
32
+ const AXIAL_SIDES = [ 'horizontal', 'vertical' ];
33
+
34
+ export function useHasDimensionsPanel( settings ) {
35
+ const hasContentSize = useHasContentSize( settings );
36
+ const hasWideSize = useHasWideSize( settings );
37
+ const hasPadding = useHasPadding( settings );
38
+ const hasMargin = useHasMargin( settings );
39
+ const hasGap = useHasGap( settings );
40
+ const hasMinHeight = useHasMinHeight( settings );
41
+ const hasChildLayout = useHasChildLayout( settings );
42
+
43
+ return (
44
+ Platform.OS === 'web' &&
45
+ ( hasContentSize ||
46
+ hasWideSize ||
47
+ hasPadding ||
48
+ hasMargin ||
49
+ hasGap ||
50
+ hasMinHeight ||
51
+ hasChildLayout )
52
+ );
53
+ }
54
+
55
+ function useHasContentSize( settings ) {
56
+ return settings?.layout?.contentSize;
57
+ }
58
+
59
+ function useHasWideSize( settings ) {
60
+ return settings?.layout?.wideSize;
61
+ }
62
+
63
+ function useHasPadding( settings ) {
64
+ return settings?.spacing?.padding;
65
+ }
66
+
67
+ function useHasMargin( settings ) {
68
+ return settings?.spacing?.margin;
69
+ }
70
+
71
+ function useHasGap( settings ) {
72
+ return settings?.spacing?.blockGap;
73
+ }
74
+
75
+ function useHasMinHeight( settings ) {
76
+ return settings?.dimensions?.minHeight;
77
+ }
78
+
79
+ function useHasChildLayout( settings ) {
80
+ const {
81
+ type: parentLayoutType = 'default',
82
+ default: { type: defaultParentLayoutType = 'default' } = {},
83
+ allowSizingOnChildren = false,
84
+ } = settings?.parentLayout ?? {};
85
+
86
+ const support =
87
+ ( defaultParentLayoutType === 'flex' || parentLayoutType === 'flex' ) &&
88
+ allowSizingOnChildren;
89
+
90
+ return !! settings?.layout && support;
91
+ }
92
+
93
+ function useHasSpacingPresets( settings ) {
94
+ const {
95
+ custom,
96
+ theme,
97
+ default: defaultPresets,
98
+ } = settings?.spacing?.spacingSizes || {};
99
+ const presets = custom ?? theme ?? defaultPresets ?? [];
100
+
101
+ return presets.length > 0;
102
+ }
103
+
104
+ function filterValuesBySides( values, sides ) {
105
+ if ( ! sides ) {
106
+ // If no custom side configuration all sides are opted into by default.
107
+ return values;
108
+ }
109
+
110
+ // Only include sides opted into within filtered values.
111
+ const filteredValues = {};
112
+ sides.forEach( ( side ) => {
113
+ if ( side === 'vertical' ) {
114
+ filteredValues.top = values.top;
115
+ filteredValues.bottom = values.bottom;
116
+ }
117
+ if ( side === 'horizontal' ) {
118
+ filteredValues.left = values.left;
119
+ filteredValues.right = values.right;
120
+ }
121
+ filteredValues[ side ] = values?.[ side ];
122
+ } );
123
+
124
+ return filteredValues;
125
+ }
126
+
127
+ function splitStyleValue( value ) {
128
+ // Check for shorthand value (a string value).
129
+ if ( value && typeof value === 'string' ) {
130
+ // Convert to value for individual sides for BoxControl.
131
+ return {
132
+ top: value,
133
+ right: value,
134
+ bottom: value,
135
+ left: value,
136
+ };
137
+ }
138
+
139
+ return value;
140
+ }
141
+
142
+ function splitGapValue( value ) {
143
+ // Check for shorthand value (a string value).
144
+ if ( value && typeof value === 'string' ) {
145
+ // If the value is a string, treat it as a single side (top) for the spacing controls.
146
+ return {
147
+ top: value,
148
+ };
149
+ }
150
+
151
+ if ( value ) {
152
+ return {
153
+ ...value,
154
+ right: value?.left,
155
+ bottom: value?.top,
156
+ };
157
+ }
158
+
159
+ return value;
160
+ }
161
+
162
+ function DimensionsToolsPanel( {
163
+ resetAllFilter,
164
+ onChange,
165
+ value,
166
+ panelId,
167
+ children,
168
+ } ) {
169
+ const resetAll = () => {
170
+ const updatedValue = resetAllFilter( value );
171
+ onChange( updatedValue );
172
+ };
173
+
174
+ return (
175
+ <ToolsPanel
176
+ label={ __( 'Dimensions' ) }
177
+ resetAll={ resetAll }
178
+ panelId={ panelId }
179
+ >
180
+ { children }
181
+ </ToolsPanel>
182
+ );
183
+ }
184
+
185
+ const DEFAULT_CONTROLS = {
186
+ contentSize: true,
187
+ wideSize: true,
188
+ padding: true,
189
+ margin: true,
190
+ blockGap: true,
191
+ minHeight: true,
192
+ };
193
+
194
+ export default function DimensionsPanel( {
195
+ as: Wrapper = DimensionsToolsPanel,
196
+ value,
197
+ onChange,
198
+ inheritedValue = value,
199
+ settings,
200
+ panelId,
201
+ defaultControls = DEFAULT_CONTROLS,
202
+ onVisualize = () => {},
203
+ // Special case because the layout controls are not part of the dimensions panel
204
+ // in global styles but not in block inspector.
205
+ includeLayoutControls = false,
206
+ } ) {
207
+ const decodeValue = ( rawValue ) =>
208
+ getValueFromVariable( { settings }, '', rawValue );
209
+
210
+ const showSpacingPresetsControl = useHasSpacingPresets( settings );
211
+ const units = useCustomUnits( {
212
+ availableUnits: settings?.spacing?.units || [
213
+ '%',
214
+ 'px',
215
+ 'em',
216
+ 'rem',
217
+ 'vw',
218
+ ],
219
+ } );
220
+
221
+ // Content Size
222
+ const showContentSizeControl =
223
+ useHasContentSize( settings ) && includeLayoutControls;
224
+ const contentSizeValue = decodeValue( inheritedValue?.layout?.contentSize );
225
+ const setContentSizeValue = ( newValue ) => {
226
+ onChange( {
227
+ ...value,
228
+ layout: {
229
+ ...value?.layout,
230
+ contentSize: newValue,
231
+ },
232
+ } );
233
+ };
234
+ const hasUserSetContentSizeValue = () => !! value?.layout?.contentSize;
235
+ const resetContentSizeValue = () => setContentSizeValue( undefined );
236
+
237
+ // Wide Size
238
+ const showWideSizeControl =
239
+ useHasWideSize( settings ) && includeLayoutControls;
240
+ const wideSizeValue = decodeValue( inheritedValue?.layout?.wideSize );
241
+ const setWideSizeValue = ( newValue ) => {
242
+ onChange( {
243
+ ...value,
244
+ layout: {
245
+ ...value?.layout,
246
+ wideSize: newValue,
247
+ },
248
+ } );
249
+ };
250
+ const hasUserSetWideSizeValue = () => !! value?.layout?.wideSize;
251
+ const resetWideSizeValue = () => setWideSizeValue( undefined );
252
+
253
+ // Padding
254
+ const showPaddingControl = useHasPadding( settings );
255
+ const rawPadding = decodeValue( inheritedValue?.spacing?.padding );
256
+ const paddingValues = splitStyleValue( rawPadding );
257
+ const paddingSides = Array.isArray( settings?.spacing?.padding )
258
+ ? settings?.spacing?.padding
259
+ : settings?.spacing?.padding?.sides;
260
+ const isAxialPadding =
261
+ paddingSides &&
262
+ paddingSides.some( ( side ) => AXIAL_SIDES.includes( side ) );
263
+ const setPaddingValues = ( newPaddingValues ) => {
264
+ const padding = filterValuesBySides( newPaddingValues, paddingSides );
265
+ onChange( {
266
+ ...value,
267
+ spacing: {
268
+ ...value?.spacing,
269
+ padding,
270
+ },
271
+ } );
272
+ };
273
+ const hasPaddingValue = () =>
274
+ !! value?.spacing?.padding &&
275
+ Object.keys( value?.spacing?.padding ).length;
276
+ const resetPaddingValue = () => setPaddingValues( undefined );
277
+ const onMouseOverPadding = () => onVisualize( 'padding' );
278
+
279
+ // Margin
280
+ const showMarginControl = useHasMargin( settings );
281
+ const rawMargin = decodeValue( inheritedValue?.spacing?.margin );
282
+ const marginValues = splitStyleValue( rawMargin );
283
+ const marginSides = Array.isArray( settings?.spacing?.margin )
284
+ ? settings?.spacing?.margin
285
+ : settings?.spacing?.margin?.sides;
286
+ const isAxialMargin =
287
+ marginSides &&
288
+ marginSides.some( ( side ) => AXIAL_SIDES.includes( side ) );
289
+ const setMarginValues = ( newMarginValues ) => {
290
+ const margin = filterValuesBySides( newMarginValues, marginSides );
291
+ onChange( {
292
+ ...value,
293
+ spacing: {
294
+ ...value?.spacing,
295
+ margin,
296
+ },
297
+ } );
298
+ };
299
+ const hasMarginValue = () =>
300
+ !! value?.spacing?.margin &&
301
+ Object.keys( value?.spacing?.margin ).length;
302
+ const resetMarginValue = () => setMarginValues( undefined );
303
+ const onMouseOverMargin = () => onVisualize( 'margin' );
304
+
305
+ // Block Gap
306
+ const showGapControl = useHasGap( settings );
307
+ const gapValue = decodeValue( inheritedValue?.spacing?.blockGap );
308
+ const gapValues = splitGapValue( gapValue );
309
+ const gapSides = Array.isArray( settings?.spacing?.blockGap )
310
+ ? settings?.spacing?.blockGap
311
+ : settings?.spacing?.blockGap?.sides;
312
+ const isAxialGap =
313
+ gapSides && gapSides.some( ( side ) => AXIAL_SIDES.includes( side ) );
314
+ const setGapValue = ( newGapValue ) => {
315
+ onChange( {
316
+ ...value,
317
+ spacing: {
318
+ ...value?.spacing,
319
+ blockGap: newGapValue,
320
+ },
321
+ } );
322
+ };
323
+ const setGapValues = ( nextBoxGapValue ) => {
324
+ if ( ! nextBoxGapValue ) {
325
+ setGapValue( null );
326
+ }
327
+ // If axial gap is not enabled, treat the 'top' value as the shorthand gap value.
328
+ if ( ! isAxialGap && nextBoxGapValue?.hasOwnProperty( 'top' ) ) {
329
+ setGapValue( nextBoxGapValue.top );
330
+ } else {
331
+ setGapValue( {
332
+ top: nextBoxGapValue?.top,
333
+ left: nextBoxGapValue?.left,
334
+ } );
335
+ }
336
+ };
337
+ const resetGapValue = () => setGapValue( undefined );
338
+ const hasGapValue = () => !! value?.spacing?.blockGap;
339
+
340
+ // Min Height
341
+ const showMinHeightControl = useHasMinHeight( settings );
342
+ const minHeightValue = decodeValue( inheritedValue?.dimensions?.minHeight );
343
+ const setMinHeightValue = ( newValue ) => {
344
+ onChange( {
345
+ ...value,
346
+ dimensions: {
347
+ ...value?.dimensions,
348
+ minHeight: newValue,
349
+ },
350
+ } );
351
+ };
352
+ const resetMinHeightValue = () => {
353
+ setMinHeightValue( undefined );
354
+ };
355
+ const hasMinHeightValue = () => !! value?.dimensions?.minHeight;
356
+
357
+ // Child Layout
358
+ const showChildLayoutControl = useHasChildLayout( settings );
359
+ const childLayout = inheritedValue?.layout;
360
+ const { orientation = 'horizontal' } = settings?.parentLayout ?? {};
361
+ const childLayoutOrientationLabel =
362
+ orientation === 'horizontal' ? __( 'Width' ) : __( 'Height' );
363
+ const setChildLayout = ( newChildLayout ) => {
364
+ onChange( {
365
+ ...value,
366
+ layout: {
367
+ ...value?.layout,
368
+ ...newChildLayout,
369
+ },
370
+ } );
371
+ };
372
+ const resetChildLayoutValue = () => {
373
+ setChildLayout( {
374
+ selfStretch: undefined,
375
+ flexSize: undefined,
376
+ } );
377
+ };
378
+ const hasChildLayoutValue = () => !! value?.layout;
379
+
380
+ const resetAllFilter = useCallback( ( previousValue ) => {
381
+ return {
382
+ ...previousValue,
383
+ layout: cleanEmptyObject( {
384
+ ...previousValue?.layout,
385
+ contentSize: undefined,
386
+ wideSize: undefined,
387
+ selfStretch: undefined,
388
+ flexSize: undefined,
389
+ } ),
390
+ spacing: {
391
+ ...previousValue?.spacing,
392
+ padding: undefined,
393
+ margin: undefined,
394
+ blockGap: undefined,
395
+ },
396
+ dimensions: {
397
+ ...previousValue?.dimensions,
398
+ minHeight: undefined,
399
+ },
400
+ };
401
+ }, [] );
402
+
403
+ const onMouseLeaveControls = () => onVisualize( false );
404
+
405
+ return (
406
+ <Wrapper
407
+ resetAllFilter={ resetAllFilter }
408
+ value={ value }
409
+ onChange={ onChange }
410
+ panelId={ panelId }
411
+ >
412
+ { ( showContentSizeControl || showWideSizeControl ) && (
413
+ <span className="span-columns">
414
+ { __( 'Set the width of the main content area.' ) }
415
+ </span>
416
+ ) }
417
+ { showContentSizeControl && (
418
+ <ToolsPanelItem
419
+ className="single-column"
420
+ label={ __( 'Content size' ) }
421
+ hasValue={ hasUserSetContentSizeValue }
422
+ onDeselect={ resetContentSizeValue }
423
+ isShownByDefault={ defaultControls.contentSize }
424
+ panelId={ panelId }
425
+ >
426
+ <HStack alignment="flex-end" justify="flex-start">
427
+ <UnitControl
428
+ label={ __( 'Content' ) }
429
+ labelPosition="top"
430
+ __unstableInputWidth="80px"
431
+ value={ contentSizeValue || '' }
432
+ onChange={ ( nextContentSize ) => {
433
+ setContentSizeValue( nextContentSize );
434
+ } }
435
+ units={ units }
436
+ />
437
+ <View>
438
+ <Icon icon={ positionCenter } />
439
+ </View>
440
+ </HStack>
441
+ </ToolsPanelItem>
442
+ ) }
443
+ { showWideSizeControl && (
444
+ <ToolsPanelItem
445
+ className="single-column"
446
+ label={ __( 'Wide size' ) }
447
+ hasValue={ hasUserSetWideSizeValue }
448
+ onDeselect={ resetWideSizeValue }
449
+ isShownByDefault={ defaultControls.wideSize }
450
+ panelId={ panelId }
451
+ >
452
+ <HStack alignment="flex-end" justify="flex-start">
453
+ <UnitControl
454
+ label={ __( 'Wide' ) }
455
+ labelPosition="top"
456
+ __unstableInputWidth="80px"
457
+ value={ wideSizeValue || '' }
458
+ onChange={ ( nextWideSize ) => {
459
+ setWideSizeValue( nextWideSize );
460
+ } }
461
+ units={ units }
462
+ />
463
+ <View>
464
+ <Icon icon={ stretchWide } />
465
+ </View>
466
+ </HStack>
467
+ </ToolsPanelItem>
468
+ ) }
469
+ { showPaddingControl && (
470
+ <ToolsPanelItem
471
+ hasValue={ hasPaddingValue }
472
+ label={ __( 'Padding' ) }
473
+ onDeselect={ resetPaddingValue }
474
+ isShownByDefault={ defaultControls.padding }
475
+ className={ classnames( {
476
+ 'tools-panel-item-spacing': showSpacingPresetsControl,
477
+ } ) }
478
+ panelId={ panelId }
479
+ >
480
+ { ! showSpacingPresetsControl && (
481
+ <BoxControl
482
+ values={ paddingValues }
483
+ onChange={ setPaddingValues }
484
+ label={ __( 'Padding' ) }
485
+ sides={ paddingSides }
486
+ units={ units }
487
+ allowReset={ false }
488
+ splitOnAxis={ isAxialPadding }
489
+ onMouseOver={ onMouseOverPadding }
490
+ onMouseOut={ onMouseLeaveControls }
491
+ />
492
+ ) }
493
+ { showSpacingPresetsControl && (
494
+ <SpacingSizesControl
495
+ values={ paddingValues }
496
+ onChange={ setPaddingValues }
497
+ label={ __( 'Padding' ) }
498
+ sides={ paddingSides }
499
+ units={ units }
500
+ allowReset={ false }
501
+ splitOnAxis={ isAxialPadding }
502
+ onMouseOver={ onMouseOverPadding }
503
+ onMouseOut={ onMouseLeaveControls }
504
+ />
505
+ ) }
506
+ </ToolsPanelItem>
507
+ ) }
508
+ { showMarginControl && (
509
+ <ToolsPanelItem
510
+ hasValue={ hasMarginValue }
511
+ label={ __( 'Margin' ) }
512
+ onDeselect={ resetMarginValue }
513
+ isShownByDefault={ defaultControls.margin }
514
+ className={ classnames( {
515
+ 'tools-panel-item-spacing': showSpacingPresetsControl,
516
+ } ) }
517
+ panelId={ panelId }
518
+ >
519
+ { ! showSpacingPresetsControl && (
520
+ <BoxControl
521
+ values={ marginValues }
522
+ onChange={ setMarginValues }
523
+ label={ __( 'Margin' ) }
524
+ sides={ marginSides }
525
+ units={ units }
526
+ allowReset={ false }
527
+ splitOnAxis={ isAxialMargin }
528
+ onMouseOver={ onMouseOverMargin }
529
+ onMouseOut={ onMouseLeaveControls }
530
+ />
531
+ ) }
532
+ { showSpacingPresetsControl && (
533
+ <SpacingSizesControl
534
+ values={ marginValues }
535
+ onChange={ setMarginValues }
536
+ label={ __( 'Margin' ) }
537
+ sides={ marginSides }
538
+ units={ units }
539
+ allowReset={ false }
540
+ splitOnAxis={ isAxialMargin }
541
+ onMouseOver={ onMouseOverMargin }
542
+ onMouseOut={ onMouseLeaveControls }
543
+ />
544
+ ) }
545
+ </ToolsPanelItem>
546
+ ) }
547
+ { showGapControl && (
548
+ <ToolsPanelItem
549
+ hasValue={ hasGapValue }
550
+ label={ __( 'Block spacing' ) }
551
+ onDeselect={ resetGapValue }
552
+ isShownByDefault={ defaultControls.blockGap }
553
+ className={ classnames( {
554
+ 'tools-panel-item-spacing': showSpacingPresetsControl,
555
+ } ) }
556
+ panelId={ panelId }
557
+ >
558
+ { ! showSpacingPresetsControl &&
559
+ ( isAxialGap ? (
560
+ <BoxControl
561
+ label={ __( 'Block spacing' ) }
562
+ min={ 0 }
563
+ onChange={ setGapValues }
564
+ units={ units }
565
+ sides={ gapSides }
566
+ values={ gapValues }
567
+ allowReset={ false }
568
+ splitOnAxis={ isAxialGap }
569
+ />
570
+ ) : (
571
+ <UnitControl
572
+ label={ __( 'Block spacing' ) }
573
+ __unstableInputWidth="80px"
574
+ min={ 0 }
575
+ onChange={ setGapValue }
576
+ units={ units }
577
+ value={ gapValue }
578
+ />
579
+ ) ) }
580
+ { showSpacingPresetsControl && (
581
+ <SpacingSizesControl
582
+ label={ __( 'Block spacing' ) }
583
+ min={ 0 }
584
+ onChange={ setGapValues }
585
+ sides={ isAxialGap ? gapSides : [ 'top' ] } // Use 'top' as the shorthand property in non-axial configurations.
586
+ values={ gapValues }
587
+ allowReset={ false }
588
+ splitOnAxis={ isAxialGap }
589
+ />
590
+ ) }
591
+ </ToolsPanelItem>
592
+ ) }
593
+ { showMinHeightControl && (
594
+ <ToolsPanelItem
595
+ hasValue={ hasMinHeightValue }
596
+ label={ __( 'Min. height' ) }
597
+ onDeselect={ resetMinHeightValue }
598
+ isShownByDefault={ defaultControls.minHeight }
599
+ panelId={ panelId }
600
+ >
601
+ <HeightControl
602
+ label={ __( 'Min. height' ) }
603
+ value={ minHeightValue }
604
+ onChange={ setMinHeightValue }
605
+ />
606
+ </ToolsPanelItem>
607
+ ) }
608
+ { showChildLayoutControl && (
609
+ <VStack
610
+ as={ ToolsPanelItem }
611
+ spacing={ 2 }
612
+ hasValue={ hasChildLayoutValue }
613
+ label={ childLayoutOrientationLabel }
614
+ onDeselect={ resetChildLayoutValue }
615
+ isShownByDefault={ defaultControls.childLayout }
616
+ panelId={ panelId }
617
+ >
618
+ <ChildLayoutControl
619
+ value={ childLayout }
620
+ onChange={ setChildLayout }
621
+ parentLayout={ settings?.parentLayout }
622
+ />
623
+ </VStack>
624
+ ) }
625
+ </Wrapper>
626
+ );
627
+ }