@wordpress/block-editor 9.7.0 → 9.7.1-next.d6164808d3.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 (279) hide show
  1. package/build/components/block-alignment-control/use-available-alignments.js +1 -1
  2. package/build/components/block-alignment-control/use-available-alignments.js.map +1 -1
  3. package/build/components/block-edit-visually-button/index.js +46 -0
  4. package/build/components/block-edit-visually-button/index.js.map +1 -0
  5. package/build/components/block-popover/inbetween.js +4 -2
  6. package/build/components/block-popover/inbetween.js.map +1 -1
  7. package/build/components/block-settings-menu/index.js +2 -6
  8. package/build/components/block-settings-menu/index.js.map +1 -1
  9. package/build/components/block-switcher/index.js +10 -16
  10. package/build/components/block-switcher/index.js.map +1 -1
  11. package/build/components/block-toolbar/index.js +5 -1
  12. package/build/components/block-toolbar/index.js.map +1 -1
  13. package/build/components/border-radius-control/all-input-control.js +31 -3
  14. package/build/components/border-radius-control/all-input-control.js.map +1 -1
  15. package/build/components/border-radius-control/index.js +20 -6
  16. package/build/components/border-radius-control/index.js.map +1 -1
  17. package/build/components/border-radius-control/input-controls.js +21 -6
  18. package/build/components/border-radius-control/input-controls.js.map +1 -1
  19. package/build/components/border-radius-control/utils.js +13 -16
  20. package/build/components/border-radius-control/utils.js.map +1 -1
  21. package/build/components/colors/with-colors.js +17 -4
  22. package/build/components/colors/with-colors.js.map +1 -1
  23. package/build/components/copy-handler/index.js +6 -0
  24. package/build/components/copy-handler/index.js.map +1 -1
  25. package/build/components/date-format-picker/index.js +2 -7
  26. package/build/components/date-format-picker/index.js.map +1 -1
  27. package/build/components/duotone/components.js +5 -5
  28. package/build/components/duotone/components.js.map +1 -1
  29. package/build/components/font-family/index.js +1 -1
  30. package/build/components/font-family/index.js.map +1 -1
  31. package/build/components/font-sizes/with-font-sizes.js +17 -4
  32. package/build/components/font-sizes/with-font-sizes.js.map +1 -1
  33. package/build/components/index.js +9 -0
  34. package/build/components/index.js.map +1 -1
  35. package/build/components/inserter/search-items.js +22 -4
  36. package/build/components/inserter/search-items.js.map +1 -1
  37. package/build/components/link-control/link-preview.js +0 -1
  38. package/build/components/link-control/link-preview.js.map +1 -1
  39. package/build/components/list-view/block-select-button.js +5 -2
  40. package/build/components/list-view/block-select-button.js.map +1 -1
  41. package/build/components/list-view/use-block-selection.js +1 -7
  42. package/build/components/list-view/use-block-selection.js.map +1 -1
  43. package/build/components/rich-text/use-enter.js +0 -4
  44. package/build/components/rich-text/use-enter.js.map +1 -1
  45. package/build/components/rich-text/use-format-types.js +8 -11
  46. package/build/components/rich-text/use-format-types.js.map +1 -1
  47. package/build/components/spacing-sizes-control/all-input-control.js +53 -0
  48. package/build/components/spacing-sizes-control/all-input-control.js.map +1 -0
  49. package/build/components/spacing-sizes-control/axial-input-controls.js +69 -0
  50. package/build/components/spacing-sizes-control/axial-input-controls.js.map +1 -0
  51. package/build/components/spacing-sizes-control/index.js +100 -0
  52. package/build/components/spacing-sizes-control/index.js.map +1 -0
  53. package/build/components/spacing-sizes-control/input-controls.js +52 -0
  54. package/build/components/spacing-sizes-control/input-controls.js.map +1 -0
  55. package/build/components/spacing-sizes-control/linked-button.js +38 -0
  56. package/build/components/spacing-sizes-control/linked-button.js.map +1 -0
  57. package/build/components/spacing-sizes-control/spacing-input-control.js +208 -0
  58. package/build/components/spacing-sizes-control/spacing-input-control.js.map +1 -0
  59. package/build/components/spacing-sizes-control/utils.js +202 -0
  60. package/build/components/spacing-sizes-control/utils.js.map +1 -0
  61. package/build/components/url-input/index.js +1 -1
  62. package/build/components/url-input/index.js.map +1 -1
  63. package/build/components/writing-flow/use-multi-selection.js +4 -2
  64. package/build/components/writing-flow/use-multi-selection.js.map +1 -1
  65. package/build/components/writing-flow/use-selection-observer.js +10 -2
  66. package/build/components/writing-flow/use-selection-observer.js.map +1 -1
  67. package/build/hooks/border-radius.js +2 -7
  68. package/build/hooks/border-radius.js.map +1 -1
  69. package/build/hooks/border.js +2 -2
  70. package/build/hooks/border.js.map +1 -1
  71. package/build/hooks/color.js +4 -1
  72. package/build/hooks/color.js.map +1 -1
  73. package/build/hooks/dimensions.js +15 -0
  74. package/build/hooks/dimensions.js.map +1 -1
  75. package/build/hooks/duotone.js +4 -4
  76. package/build/hooks/duotone.js.map +1 -1
  77. package/build/hooks/gap.js +6 -4
  78. package/build/hooks/gap.js.map +1 -1
  79. package/build/hooks/generated-class-name.js +1 -7
  80. package/build/hooks/generated-class-name.js.map +1 -1
  81. package/build/hooks/layout.js +20 -12
  82. package/build/hooks/layout.js.map +1 -1
  83. package/build/hooks/margin.js +28 -12
  84. package/build/hooks/margin.js.map +1 -1
  85. package/build/hooks/padding.js +19 -8
  86. package/build/hooks/padding.js.map +1 -1
  87. package/build/hooks/style.js +4 -50
  88. package/build/hooks/style.js.map +1 -1
  89. package/build/layouts/constrained.js +215 -0
  90. package/build/layouts/constrained.js.map +1 -0
  91. package/build/layouts/flex.js +1 -1
  92. package/build/layouts/flex.js.map +1 -1
  93. package/build/layouts/flow.js +7 -169
  94. package/build/layouts/flow.js.map +1 -1
  95. package/build/layouts/index.js +3 -1
  96. package/build/layouts/index.js.map +1 -1
  97. package/build/layouts/utils.js +43 -0
  98. package/build/layouts/utils.js.map +1 -1
  99. package/build/store/actions.js +25 -3
  100. package/build/store/actions.js.map +1 -1
  101. package/build/store/selectors.js +4 -6
  102. package/build/store/selectors.js.map +1 -1
  103. package/build-module/components/block-alignment-control/use-available-alignments.js +1 -1
  104. package/build-module/components/block-alignment-control/use-available-alignments.js.map +1 -1
  105. package/build-module/components/block-edit-visually-button/index.js +35 -0
  106. package/build-module/components/block-edit-visually-button/index.js.map +1 -0
  107. package/build-module/components/block-popover/inbetween.js +4 -2
  108. package/build-module/components/block-popover/inbetween.js.map +1 -1
  109. package/build-module/components/block-settings-menu/index.js +3 -6
  110. package/build-module/components/block-settings-menu/index.js.map +1 -1
  111. package/build-module/components/block-switcher/index.js +10 -16
  112. package/build-module/components/block-switcher/index.js.map +1 -1
  113. package/build-module/components/block-toolbar/index.js +4 -1
  114. package/build-module/components/block-toolbar/index.js.map +1 -1
  115. package/build-module/components/border-radius-control/all-input-control.js +32 -4
  116. package/build-module/components/border-radius-control/all-input-control.js.map +1 -1
  117. package/build-module/components/border-radius-control/index.js +20 -6
  118. package/build-module/components/border-radius-control/index.js.map +1 -1
  119. package/build-module/components/border-radius-control/input-controls.js +22 -7
  120. package/build-module/components/border-radius-control/input-controls.js.map +1 -1
  121. package/build-module/components/border-radius-control/utils.js +13 -16
  122. package/build-module/components/border-radius-control/utils.js.map +1 -1
  123. package/build-module/components/colors/with-colors.js +16 -3
  124. package/build-module/components/colors/with-colors.js.map +1 -1
  125. package/build-module/components/copy-handler/index.js +7 -1
  126. package/build-module/components/copy-handler/index.js.map +1 -1
  127. package/build-module/components/date-format-picker/index.js +2 -6
  128. package/build-module/components/date-format-picker/index.js.map +1 -1
  129. package/build-module/components/duotone/components.js +5 -5
  130. package/build-module/components/duotone/components.js.map +1 -1
  131. package/build-module/components/font-family/index.js +1 -1
  132. package/build-module/components/font-family/index.js.map +1 -1
  133. package/build-module/components/font-sizes/with-font-sizes.js +16 -3
  134. package/build-module/components/font-sizes/with-font-sizes.js.map +1 -1
  135. package/build-module/components/index.js +1 -0
  136. package/build-module/components/index.js.map +1 -1
  137. package/build-module/components/inserter/search-items.js +19 -5
  138. package/build-module/components/inserter/search-items.js.map +1 -1
  139. package/build-module/components/link-control/link-preview.js +0 -1
  140. package/build-module/components/link-control/link-preview.js.map +1 -1
  141. package/build-module/components/list-view/block-select-button.js +5 -2
  142. package/build-module/components/list-view/block-select-button.js.map +1 -1
  143. package/build-module/components/list-view/use-block-selection.js +1 -6
  144. package/build-module/components/list-view/use-block-selection.js.map +1 -1
  145. package/build-module/components/rich-text/use-enter.js +0 -4
  146. package/build-module/components/rich-text/use-enter.js.map +1 -1
  147. package/build-module/components/rich-text/use-format-types.js +8 -10
  148. package/build-module/components/rich-text/use-format-types.js.map +1 -1
  149. package/build-module/components/spacing-sizes-control/all-input-control.js +41 -0
  150. package/build-module/components/spacing-sizes-control/all-input-control.js.map +1 -0
  151. package/build-module/components/spacing-sizes-control/axial-input-controls.js +57 -0
  152. package/build-module/components/spacing-sizes-control/axial-input-controls.js.map +1 -0
  153. package/build-module/components/spacing-sizes-control/index.js +83 -0
  154. package/build-module/components/spacing-sizes-control/index.js.map +1 -0
  155. package/build-module/components/spacing-sizes-control/input-controls.js +41 -0
  156. package/build-module/components/spacing-sizes-control/input-controls.js.map +1 -0
  157. package/build-module/components/spacing-sizes-control/linked-button.js +28 -0
  158. package/build-module/components/spacing-sizes-control/linked-button.js.map +1 -0
  159. package/build-module/components/spacing-sizes-control/spacing-input-control.js +192 -0
  160. package/build-module/components/spacing-sizes-control/spacing-input-control.js.map +1 -0
  161. package/build-module/components/spacing-sizes-control/utils.js +174 -0
  162. package/build-module/components/spacing-sizes-control/utils.js.map +1 -0
  163. package/build-module/components/url-input/index.js +1 -1
  164. package/build-module/components/url-input/index.js.map +1 -1
  165. package/build-module/components/writing-flow/use-multi-selection.js +4 -2
  166. package/build-module/components/writing-flow/use-multi-selection.js.map +1 -1
  167. package/build-module/components/writing-flow/use-selection-observer.js +10 -2
  168. package/build-module/components/writing-flow/use-selection-observer.js.map +1 -1
  169. package/build-module/hooks/border-radius.js +2 -7
  170. package/build-module/hooks/border-radius.js.map +1 -1
  171. package/build-module/hooks/border.js +2 -2
  172. package/build-module/hooks/border.js.map +1 -1
  173. package/build-module/hooks/color.js +4 -1
  174. package/build-module/hooks/color.js.map +1 -1
  175. package/build-module/hooks/dimensions.js +13 -0
  176. package/build-module/hooks/dimensions.js.map +1 -1
  177. package/build-module/hooks/duotone.js +4 -4
  178. package/build-module/hooks/duotone.js.map +1 -1
  179. package/build-module/hooks/gap.js +3 -2
  180. package/build-module/hooks/gap.js.map +1 -1
  181. package/build-module/hooks/generated-class-name.js +1 -6
  182. package/build-module/hooks/generated-class-name.js.map +1 -1
  183. package/build-module/hooks/layout.js +20 -12
  184. package/build-module/hooks/layout.js.map +1 -1
  185. package/build-module/hooks/margin.js +26 -12
  186. package/build-module/hooks/margin.js.map +1 -1
  187. package/build-module/hooks/padding.js +17 -8
  188. package/build-module/hooks/padding.js.map +1 -1
  189. package/build-module/hooks/style.js +7 -53
  190. package/build-module/hooks/style.js.map +1 -1
  191. package/build-module/layouts/constrained.js +197 -0
  192. package/build-module/layouts/constrained.js.map +1 -0
  193. package/build-module/layouts/flex.js +1 -1
  194. package/build-module/layouts/flex.js.map +1 -1
  195. package/build-module/layouts/flow.js +8 -163
  196. package/build-module/layouts/flow.js.map +1 -1
  197. package/build-module/layouts/index.js +2 -1
  198. package/build-module/layouts/index.js.map +1 -1
  199. package/build-module/layouts/utils.js +40 -0
  200. package/build-module/layouts/utils.js.map +1 -1
  201. package/build-module/store/actions.js +25 -3
  202. package/build-module/store/actions.js.map +1 -1
  203. package/build-module/store/selectors.js +5 -7
  204. package/build-module/store/selectors.js.map +1 -1
  205. package/build-style/style-rtl.css +115 -20
  206. package/build-style/style.css +115 -20
  207. package/package.json +30 -28
  208. package/src/components/block-alignment-control/use-available-alignments.js +1 -1
  209. package/src/components/block-edit-visually-button/index.js +39 -0
  210. package/src/components/block-popover/inbetween.js +4 -1
  211. package/src/components/block-settings-menu/index.js +11 -15
  212. package/src/components/block-switcher/index.js +9 -13
  213. package/src/components/block-switcher/test/index.js +1 -0
  214. package/src/components/block-toolbar/index.js +2 -0
  215. package/src/components/border-radius-control/all-input-control.js +41 -4
  216. package/src/components/border-radius-control/index.js +25 -5
  217. package/src/components/border-radius-control/input-controls.js +40 -13
  218. package/src/components/border-radius-control/test/utils.js +22 -60
  219. package/src/components/border-radius-control/utils.js +12 -16
  220. package/src/components/colors/with-colors.js +11 -1
  221. package/src/components/copy-handler/index.js +18 -0
  222. package/src/components/date-format-picker/index.js +12 -14
  223. package/src/components/date-format-picker/style.scss +0 -4
  224. package/src/components/duotone/components.js +5 -5
  225. package/src/components/duotone-control/style.scss +0 -4
  226. package/src/components/font-appearance-control/style.scss +0 -2
  227. package/src/components/font-family/index.js +1 -1
  228. package/src/components/font-sizes/with-font-sizes.js +11 -1
  229. package/src/components/index.js +1 -0
  230. package/src/components/inserter/search-items.js +17 -5
  231. package/src/components/link-control/link-preview.js +0 -1
  232. package/src/components/link-control/test/index.js +540 -893
  233. package/src/components/list-view/block-select-button.js +7 -2
  234. package/src/components/list-view/style.scss +11 -4
  235. package/src/components/list-view/use-block-selection.js +2 -8
  236. package/src/components/media-replace-flow/style.scss +1 -0
  237. package/src/components/rich-text/use-enter.js +0 -3
  238. package/src/components/rich-text/use-format-types.js +6 -6
  239. package/src/components/spacing-sizes-control/all-input-control.js +40 -0
  240. package/src/components/spacing-sizes-control/axial-input-controls.js +62 -0
  241. package/src/components/spacing-sizes-control/index.js +91 -0
  242. package/src/components/spacing-sizes-control/input-controls.js +46 -0
  243. package/src/components/spacing-sizes-control/linked-button.js +25 -0
  244. package/src/components/spacing-sizes-control/spacing-input-control.js +280 -0
  245. package/src/components/spacing-sizes-control/style.scss +122 -0
  246. package/src/components/spacing-sizes-control/test/utils.js +156 -0
  247. package/src/components/spacing-sizes-control/utils.js +195 -0
  248. package/src/components/url-input/index.js +1 -1
  249. package/src/components/url-input/style.scss +2 -2
  250. package/src/components/url-popover/style.scss +0 -3
  251. package/src/components/writing-flow/use-multi-selection.js +4 -1
  252. package/src/components/writing-flow/use-selection-observer.js +10 -2
  253. package/src/hooks/border-radius.js +2 -6
  254. package/src/hooks/border.js +2 -2
  255. package/src/hooks/color.js +13 -3
  256. package/src/hooks/dimensions.js +15 -0
  257. package/src/hooks/duotone.js +4 -4
  258. package/src/hooks/gap.js +7 -2
  259. package/src/hooks/generated-class-name.js +6 -9
  260. package/src/hooks/layout.js +45 -14
  261. package/src/hooks/margin.js +49 -17
  262. package/src/hooks/padding.js +41 -14
  263. package/src/hooks/style.js +5 -56
  264. package/src/hooks/test/gap.js +22 -0
  265. package/src/hooks/typography.scss +0 -1
  266. package/src/layouts/constrained.js +217 -0
  267. package/src/layouts/flex.js +1 -1
  268. package/src/layouts/flow.js +6 -173
  269. package/src/layouts/index.js +2 -1
  270. package/src/layouts/test/constrained.js +21 -0
  271. package/src/layouts/utils.js +34 -0
  272. package/src/store/actions.js +32 -4
  273. package/src/store/selectors.js +5 -4
  274. package/src/style.scss +1 -0
  275. package/build/components/block-settings-menu/block-edit-visually-button.js +0 -70
  276. package/build/components/block-settings-menu/block-edit-visually-button.js.map +0 -1
  277. package/build-module/components/block-settings-menu/block-edit-visually-button.js +0 -56
  278. package/build-module/components/block-settings-menu/block-edit-visually-button.js.map +0 -1
  279. package/src/components/block-settings-menu/block-edit-visually-button.js +0 -52
@@ -90,8 +90,13 @@ function ListViewBlockSelectButton(
90
90
  <Truncate ellipsizeMode="auto">{ blockTitle }</Truncate>
91
91
  </span>
92
92
  { blockInformation?.anchor && (
93
- <span className="block-editor-list-view-block-select-button__anchor">
94
- { blockInformation.anchor }
93
+ <span className="block-editor-list-view-block-select-button__anchor-wrapper">
94
+ <Truncate
95
+ className="block-editor-list-view-block-select-button__anchor"
96
+ ellipsizeMode="auto"
97
+ >
98
+ { blockInformation.anchor }
99
+ </Truncate>
95
100
  </span>
96
101
  ) }
97
102
  { isLocked && (
@@ -312,14 +312,21 @@
312
312
  }
313
313
  }
314
314
 
315
+ .block-editor-list-view-block-select-button__anchor-wrapper {
316
+ position: relative;
317
+ max-width: min(110px, 40%);
318
+ width: 100%;
319
+ }
320
+
315
321
  .block-editor-list-view-block-select-button__anchor {
322
+ position: absolute;
323
+ right: 0;
324
+ transform: translateY(-50%);
316
325
  background: rgba($black, 0.1);
317
326
  border-radius: $radius-block-ui;
318
- display: inline-block;
319
327
  padding: 2px 6px;
320
- max-width: min(100px, 40%);
321
- overflow: hidden;
322
- text-overflow: ellipsis;
328
+ max-width: 100%;
329
+ box-sizing: border-box;
323
330
  }
324
331
 
325
332
  &.is-selected .block-editor-list-view-block-select-button__anchor {
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { difference } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -126,9 +121,8 @@ export default function useBlockSelection() {
126
121
  return;
127
122
  }
128
123
 
129
- const selectionDiff = difference(
130
- selectedBlocks,
131
- updatedSelectedBlocks
124
+ const selectionDiff = selectedBlocks.filter(
125
+ ( blockId ) => ! updatedSelectedBlocks.includes( blockId )
132
126
  );
133
127
 
134
128
  let label;
@@ -27,6 +27,7 @@
27
27
 
28
28
  .block-editor-url-input {
29
29
  padding: 0; // Cancel unnecessary default 1px padding in this case.
30
+ margin: 0; // Reset default LinkControl margins.
30
31
  }
31
32
 
32
33
  .components-base-control .components-base-control__field {
@@ -1,6 +1,3 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
1
  /**
5
2
  * WordPress dependencies
6
3
  */
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { mapKeys } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -35,7 +30,12 @@ const interactiveContentTags = new Set( [
35
30
 
36
31
  function prefixSelectKeys( selected, prefix ) {
37
32
  if ( typeof selected !== 'object' ) return { [ prefix ]: selected };
38
- return mapKeys( selected, ( value, key ) => `${ prefix }.${ key }` );
33
+ return Object.fromEntries(
34
+ Object.entries( selected ).map( ( [ key, value ] ) => [
35
+ `${ prefix }.${ key }`,
36
+ value,
37
+ ] )
38
+ );
39
39
  }
40
40
 
41
41
  function getPrefixedSelectKeys( selected, prefix ) {
@@ -0,0 +1,40 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __experimentalApplyValueToSides as applyValueToSides } from '@wordpress/components';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import SpacingInputControl from './spacing-input-control';
10
+ import { getAllRawValue, isValuesMixed, isValuesDefined } from './utils';
11
+
12
+ export default function AllInputControl( {
13
+ onChange,
14
+ values,
15
+ sides,
16
+ spacingSizes,
17
+ type,
18
+ minimumCustomValue,
19
+ } ) {
20
+ const allValue = getAllRawValue( values );
21
+ const hasValues = isValuesDefined( values );
22
+ const isMixed = hasValues && isValuesMixed( values, sides );
23
+
24
+ const handleOnChange = ( next ) => {
25
+ const nextValues = applyValueToSides( values, next, sides );
26
+ onChange( nextValues );
27
+ };
28
+
29
+ return (
30
+ <SpacingInputControl
31
+ value={ allValue }
32
+ onChange={ handleOnChange }
33
+ side={ 'all' }
34
+ spacingSizes={ spacingSizes }
35
+ isMixed={ isMixed }
36
+ type={ type }
37
+ minimumCustomValue={ minimumCustomValue }
38
+ />
39
+ );
40
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import SpacingInputControl from './spacing-input-control';
5
+ import { LABELS } from './utils';
6
+
7
+ const groupedSides = [ 'vertical', 'horizontal' ];
8
+
9
+ export default function AxialInputControls( {
10
+ onChange,
11
+ values,
12
+ sides,
13
+ spacingSizes,
14
+ type,
15
+ minimumCustomValue,
16
+ } ) {
17
+ const createHandleOnChange = ( side ) => ( next ) => {
18
+ if ( ! onChange ) {
19
+ return;
20
+ }
21
+ const nextValues = { ...values };
22
+
23
+ if ( side === 'vertical' ) {
24
+ nextValues.top = next;
25
+ nextValues.bottom = next;
26
+ }
27
+
28
+ if ( side === 'horizontal' ) {
29
+ nextValues.left = next;
30
+ nextValues.right = next;
31
+ }
32
+
33
+ onChange( nextValues );
34
+ };
35
+
36
+ // Filter sides if custom configuration provided, maintaining default order.
37
+ const filteredSides = sides?.length
38
+ ? groupedSides.filter( ( side ) => sides.includes( side ) )
39
+ : groupedSides;
40
+
41
+ return (
42
+ <>
43
+ { filteredSides.map( ( side ) => {
44
+ const axisValue =
45
+ side === 'vertical' ? values.top : values.left;
46
+ return (
47
+ <SpacingInputControl
48
+ value={ axisValue }
49
+ onChange={ createHandleOnChange( side ) }
50
+ label={ LABELS[ side ] }
51
+ key={ `spacing-sizes-control-${ side }` }
52
+ withInputField={ false }
53
+ side={ side }
54
+ spacingSizes={ spacingSizes }
55
+ type={ type }
56
+ minimumCustomValue={ minimumCustomValue }
57
+ />
58
+ );
59
+ } ) }
60
+ </>
61
+ );
62
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useState } from '@wordpress/element';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { __experimentalText as Text } from '@wordpress/components';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import AllInputControl from './all-input-control';
12
+ import InputControls from './input-controls';
13
+ import AxialInputControls from './axial-input-controls';
14
+ import LinkedButton from './linked-button';
15
+ import { DEFAULT_VALUES, isValuesMixed, isValuesDefined } from './utils';
16
+ import useSetting from '../use-setting';
17
+
18
+ export default function SpacingSizesControl( {
19
+ inputProps,
20
+ onChange,
21
+ label = __( 'Spacing Control' ),
22
+ values,
23
+ sides,
24
+ splitOnAxis = false,
25
+ useSelect,
26
+ minimumCustomValue = 0,
27
+ } ) {
28
+ const spacingSizes = [
29
+ { name: 0, slug: '0', size: 0 },
30
+ ...( useSetting( 'spacing.spacingSizes' ) || [] ),
31
+ ];
32
+
33
+ if ( spacingSizes.length > 8 ) {
34
+ spacingSizes.unshift( {
35
+ name: __( 'Default' ),
36
+ slug: 'default',
37
+ size: undefined,
38
+ } );
39
+ }
40
+
41
+ const inputValues = values || DEFAULT_VALUES;
42
+ const hasInitialValue = isValuesDefined( values );
43
+ const hasOneSide = sides?.length === 1;
44
+
45
+ const [ isLinked, setIsLinked ] = useState(
46
+ ! hasInitialValue || ! isValuesMixed( inputValues, sides ) || hasOneSide
47
+ );
48
+
49
+ const toggleLinked = () => {
50
+ setIsLinked( ! isLinked );
51
+ };
52
+
53
+ const handleOnChange = ( nextValue ) => {
54
+ const newValues = { ...values, ...nextValue };
55
+ onChange( newValues );
56
+ };
57
+
58
+ const inputControlProps = {
59
+ ...inputProps,
60
+ onChange: handleOnChange,
61
+ isLinked,
62
+ sides,
63
+ values: inputValues,
64
+ spacingSizes,
65
+ useSelect,
66
+ type: label,
67
+ minimumCustomValue,
68
+ };
69
+
70
+ return (
71
+ <fieldset role="region" className="component-spacing-sizes-control">
72
+ <Text as="legend">{ label }</Text>
73
+ { ! hasOneSide && (
74
+ <LinkedButton onClick={ toggleLinked } isLinked={ isLinked } />
75
+ ) }
76
+ { isLinked && (
77
+ <AllInputControl
78
+ aria-label={ label }
79
+ { ...inputControlProps }
80
+ />
81
+ ) }
82
+
83
+ { ! isLinked && splitOnAxis && (
84
+ <AxialInputControls { ...inputControlProps } />
85
+ ) }
86
+ { ! isLinked && ! splitOnAxis && (
87
+ <InputControls { ...inputControlProps } />
88
+ ) }
89
+ </fieldset>
90
+ );
91
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import SpacingInputControl from './spacing-input-control';
5
+ import { ALL_SIDES, LABELS } from './utils';
6
+
7
+ export default function BoxInputControls( {
8
+ values,
9
+ sides,
10
+ onChange,
11
+ spacingSizes,
12
+ type,
13
+ minimumCustomValue,
14
+ } ) {
15
+ // Filter sides if custom configuration provided, maintaining default order.
16
+ const filteredSides = sides?.length
17
+ ? ALL_SIDES.filter( ( side ) => sides.includes( side ) )
18
+ : ALL_SIDES;
19
+
20
+ const createHandleOnChange = ( side ) => ( next ) => {
21
+ const nextValues = { ...values };
22
+ nextValues[ side ] = next;
23
+
24
+ onChange( nextValues );
25
+ };
26
+
27
+ return (
28
+ <>
29
+ { filteredSides.map( ( side ) => {
30
+ return (
31
+ <SpacingInputControl
32
+ value={ values[ side ] }
33
+ label={ LABELS[ side ] }
34
+ key={ `spacing-sizes-control-${ side }` }
35
+ withInputField={ false }
36
+ side={ side }
37
+ onChange={ createHandleOnChange( side ) }
38
+ spacingSizes={ spacingSizes }
39
+ type={ type }
40
+ minimumCustomValue={ minimumCustomValue }
41
+ />
42
+ );
43
+ } ) }
44
+ </>
45
+ );
46
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { link, linkOff } from '@wordpress/icons';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { Button, Tooltip } from '@wordpress/components';
7
+
8
+ export default function LinkedButton( { isLinked, onClick } ) {
9
+ const label = isLinked ? __( 'Unlink Sides' ) : __( 'Link Sides' );
10
+
11
+ return (
12
+ <Tooltip text={ label }>
13
+ <span className="component-spacing-sizes-control__linked-button">
14
+ <Button
15
+ variant={ isLinked ? 'primary' : 'secondary' }
16
+ isSmall
17
+ icon={ isLinked ? link : linkOff }
18
+ iconSize={ 16 }
19
+ aria-label={ label }
20
+ onClick={ onClick }
21
+ />
22
+ </span>
23
+ </Tooltip>
24
+ );
25
+ }
@@ -0,0 +1,280 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { useState, useMemo } from '@wordpress/element';
10
+ import { useSelect } from '@wordpress/data';
11
+ import {
12
+ Button,
13
+ RangeControl,
14
+ CustomSelectControl,
15
+ __experimentalUnitControl as UnitControl,
16
+ __experimentalHStack as HStack,
17
+ __experimentalText as Text,
18
+ __experimentalUseCustomUnits as useCustomUnits,
19
+ __experimentalParseQuantityAndUnitFromRawValue as parseQuantityAndUnitFromRawValue,
20
+ } from '@wordpress/components';
21
+ import { __, sprintf } from '@wordpress/i18n';
22
+ import { settings } from '@wordpress/icons';
23
+
24
+ /**
25
+ * Internal dependencies
26
+ */
27
+ import useSetting from '../use-setting';
28
+ import { store as blockEditorStore } from '../../store';
29
+ import {
30
+ LABELS,
31
+ getSliderValueFromPreset,
32
+ getCustomValueFromPreset,
33
+ isValueSpacingPreset,
34
+ } from './utils';
35
+
36
+ export default function SpacingInputControl( {
37
+ spacingSizes,
38
+ value,
39
+ side,
40
+ onChange,
41
+ isMixed = false,
42
+ type,
43
+ minimumCustomValue,
44
+ } ) {
45
+ let selectListSizes = spacingSizes;
46
+ const showRangeControl = spacingSizes.length <= 8;
47
+
48
+ const disableCustomSpacingSizes = useSelect( ( select ) => {
49
+ const editorSettings = select( blockEditorStore ).getSettings();
50
+ return editorSettings?.disableCustomSpacingSizes;
51
+ } );
52
+
53
+ const [ showCustomValueControl, setShowCustomValueControl ] = useState(
54
+ ! disableCustomSpacingSizes &&
55
+ value !== undefined &&
56
+ ! isValueSpacingPreset( value )
57
+ );
58
+
59
+ const units = useCustomUnits( {
60
+ availableUnits: useSetting( 'spacing.units' ) || [ 'px', 'em', 'rem' ],
61
+ } );
62
+
63
+ let currentValue = null;
64
+
65
+ const showCustomValueInSelectList =
66
+ ! showRangeControl &&
67
+ ! showCustomValueControl &&
68
+ value !== undefined &&
69
+ ( ! isValueSpacingPreset( value ) ||
70
+ ( isValueSpacingPreset( value ) && isMixed ) );
71
+
72
+ if ( showCustomValueInSelectList ) {
73
+ selectListSizes = [
74
+ ...spacingSizes,
75
+ {
76
+ name: ! isMixed
77
+ ? // translators: A custom measurement, eg. a number followed by a unit like 12px.
78
+ sprintf( __( 'Custom (%s)' ), value )
79
+ : __( 'Mixed' ),
80
+ slug: 'custom',
81
+ size: value,
82
+ },
83
+ ];
84
+ currentValue = selectListSizes.length - 1;
85
+ } else if ( ! isMixed ) {
86
+ currentValue = ! showCustomValueControl
87
+ ? getSliderValueFromPreset( value, spacingSizes )
88
+ : getCustomValueFromPreset( value, spacingSizes );
89
+ }
90
+
91
+ const selectedUnit =
92
+ useMemo(
93
+ () => parseQuantityAndUnitFromRawValue( currentValue ),
94
+ [ currentValue ]
95
+ )[ 1 ] || units[ 0 ].value;
96
+
97
+ const setInitialValue = () => {
98
+ if ( value === undefined ) {
99
+ onChange( '0' );
100
+ }
101
+ };
102
+
103
+ const customTooltipContent = ( newValue ) =>
104
+ value === undefined ? undefined : spacingSizes[ newValue ]?.name;
105
+
106
+ const customRangeValue = parseInt( currentValue, 10 );
107
+
108
+ const getNewCustomValue = ( newSize ) => {
109
+ const isNumeric = ! isNaN( parseFloat( newSize ) );
110
+ const nextValue = isNumeric ? newSize : undefined;
111
+ return nextValue;
112
+ };
113
+
114
+ const getNewPresetValue = ( newSize, controlType ) => {
115
+ const size = parseInt( newSize, 10 );
116
+
117
+ if ( controlType === 'selectList' ) {
118
+ if ( size === 0 ) {
119
+ return undefined;
120
+ }
121
+ if ( size === 1 ) {
122
+ return '0';
123
+ }
124
+ } else if ( size === 0 ) {
125
+ return '0';
126
+ }
127
+ return `var:preset|spacing|${ spacingSizes[ newSize ]?.slug }`;
128
+ };
129
+
130
+ const handleCustomValueSliderChange = ( next ) => {
131
+ onChange( [ next, selectedUnit ].join( '' ) );
132
+ };
133
+
134
+ const allPlaceholder = isMixed ? __( 'Mixed' ) : null;
135
+
136
+ const currentValueHint = ! isMixed
137
+ ? customTooltipContent( currentValue )
138
+ : __( 'Mixed' );
139
+
140
+ const options = selectListSizes.map( ( size, index ) => ( {
141
+ key: index,
142
+ name: size.name,
143
+ } ) );
144
+
145
+ const marks = spacingSizes.map( ( newValue, index ) => ( {
146
+ value: index,
147
+ label: undefined,
148
+ } ) );
149
+
150
+ const ariaLabel = sprintf(
151
+ // translators: 1: The side of the block being modified (top, bottom, left, etc.). 2. Type of spacing being modified (Padding, margin, etc)
152
+ __( '%1$s %2$s' ),
153
+ LABELS[ side ],
154
+ type?.toLowerCase()
155
+ );
156
+
157
+ const showHint =
158
+ showRangeControl &&
159
+ ! showCustomValueControl &&
160
+ currentValueHint !== undefined;
161
+
162
+ return (
163
+ <>
164
+ { side !== 'all' && (
165
+ <HStack className="components-spacing-sizes-control__side-labels">
166
+ <Text className="components-spacing-sizes-control__side-label">
167
+ { LABELS[ side ] }
168
+ </Text>
169
+
170
+ { showHint && (
171
+ <Text className="components-spacing-sizes-control__hint-single">
172
+ { currentValueHint }
173
+ </Text>
174
+ ) }
175
+ </HStack>
176
+ ) }
177
+ { side === 'all' && showHint && (
178
+ <Text className="components-spacing-sizes-control__hint-all">
179
+ { currentValueHint }
180
+ </Text>
181
+ ) }
182
+
183
+ { ! disableCustomSpacingSizes && (
184
+ <Button
185
+ label={
186
+ showCustomValueControl
187
+ ? __( 'Use size preset' )
188
+ : __( 'Set custom size' )
189
+ }
190
+ icon={ settings }
191
+ onClick={ () => {
192
+ setShowCustomValueControl( ! showCustomValueControl );
193
+ } }
194
+ isPressed={ showCustomValueControl }
195
+ isSmall
196
+ className={ classnames( {
197
+ 'components-spacing-sizes-control__custom-toggle-all':
198
+ side === 'all',
199
+ 'components-spacing-sizes-control__custom-toggle-single':
200
+ side !== 'all',
201
+ } ) }
202
+ iconSize={ 24 }
203
+ />
204
+ ) }
205
+ { showCustomValueControl && (
206
+ <>
207
+ <UnitControl
208
+ onChange={ ( newSize ) =>
209
+ onChange( getNewCustomValue( newSize ) )
210
+ }
211
+ value={ currentValue }
212
+ units={ units }
213
+ min={ minimumCustomValue }
214
+ placeholder={ allPlaceholder }
215
+ disableUnits={ isMixed }
216
+ label={ ariaLabel }
217
+ hideLabelFromVision={ true }
218
+ className="components-spacing-sizes-control__custom-value-input"
219
+ />
220
+
221
+ <RangeControl
222
+ value={ customRangeValue }
223
+ min={ 0 }
224
+ max={ 100 }
225
+ withInputField={ false }
226
+ onChange={ handleCustomValueSliderChange }
227
+ className="components-spacing-sizes-control__custom-value-range"
228
+ />
229
+ </>
230
+ ) }
231
+ { showRangeControl && ! showCustomValueControl && (
232
+ <RangeControl
233
+ className="components-spacing-sizes-control__range-control"
234
+ value={ currentValue }
235
+ onChange={ ( newSize ) =>
236
+ onChange( getNewPresetValue( newSize ) )
237
+ }
238
+ onMouseDown={ ( event ) => {
239
+ // If mouse down is near start of range set initial value to 0, which
240
+ // prevents the user have to drag right then left to get 0 setting.
241
+ if ( event?.nativeEvent?.offsetX < 35 ) {
242
+ setInitialValue();
243
+ }
244
+ } }
245
+ withInputField={ false }
246
+ aria-valuenow={ currentValue }
247
+ aria-valuetext={ spacingSizes[ currentValue ]?.name }
248
+ renderTooltipContent={ customTooltipContent }
249
+ min={ 0 }
250
+ max={ spacingSizes.length - 1 }
251
+ marks={ marks }
252
+ label={ ariaLabel }
253
+ hideLabelFromVision={ true }
254
+ />
255
+ ) }
256
+ { ! showRangeControl && ! showCustomValueControl && (
257
+ <CustomSelectControl
258
+ className="components-spacing-sizes-control__custom-select-control"
259
+ value={
260
+ options.find(
261
+ ( option ) => option.key === currentValue
262
+ ) || '' // passing undefined here causes a downshift controlled/uncontrolled warning
263
+ }
264
+ onChange={ ( selection ) => {
265
+ onChange(
266
+ getNewPresetValue(
267
+ selection.selectedItem.key,
268
+ 'selectList'
269
+ )
270
+ );
271
+ } }
272
+ options={ options }
273
+ label={ ariaLabel }
274
+ hideLabelFromVision={ true }
275
+ __nextUnconstrainedWidth={ true }
276
+ />
277
+ ) }
278
+ </>
279
+ );
280
+ }