@wordpress/block-editor 12.22.0 → 12.23.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 (273) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +4 -0
  3. package/build/components/block-list/block.js +11 -3
  4. package/build/components/block-list/block.js.map +1 -1
  5. package/build/components/block-mover/button.js +4 -1
  6. package/build/components/block-mover/button.js.map +1 -1
  7. package/build/components/block-mover/index.js +5 -1
  8. package/build/components/block-mover/index.js.map +1 -1
  9. package/build/components/block-patterns-list/index.js +4 -1
  10. package/build/components/block-patterns-list/index.js.map +1 -1
  11. package/build/components/block-settings-menu/block-settings-dropdown.js +7 -3
  12. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  13. package/build/components/block-switcher/index.js +4 -3
  14. package/build/components/block-switcher/index.js.map +1 -1
  15. package/build/components/block-toolbar/index.js +5 -4
  16. package/build/components/block-toolbar/index.js.map +1 -1
  17. package/build/components/block-toolbar/shuffle.js +18 -9
  18. package/build/components/block-toolbar/shuffle.js.map +1 -1
  19. package/build/components/block-tools/block-selection-button.js +48 -8
  20. package/build/components/block-tools/block-selection-button.js.map +1 -1
  21. package/build/components/block-tools/index.js +14 -2
  22. package/build/components/block-tools/index.js.map +1 -1
  23. package/build/components/global-styles/advanced-panel.js +9 -2
  24. package/build/components/global-styles/advanced-panel.js.map +1 -1
  25. package/build/components/global-styles/background-panel.js +444 -0
  26. package/build/components/global-styles/background-panel.js.map +1 -0
  27. package/build/components/global-styles/color-panel.js +2 -1
  28. package/build/components/global-styles/color-panel.js.map +1 -1
  29. package/build/components/global-styles/get-global-styles-changes.js +3 -0
  30. package/build/components/global-styles/get-global-styles-changes.js.map +1 -1
  31. package/build/components/global-styles/hooks.js +1 -1
  32. package/build/components/global-styles/hooks.js.map +1 -1
  33. package/build/components/global-styles/index.js +13 -0
  34. package/build/components/global-styles/index.js.map +1 -1
  35. package/build/components/global-styles/use-global-styles-output.js +15 -14
  36. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  37. package/build/components/global-styles/utils.js +2 -1
  38. package/build/components/global-styles/utils.js.map +1 -1
  39. package/build/components/iframe/index.js +9 -4
  40. package/build/components/iframe/index.js.map +1 -1
  41. package/build/components/inserter/block-patterns-tab/index.js.map +1 -1
  42. package/build/components/inserter/block-patterns-tab/pattern-category-preview-panel.js +5 -0
  43. package/build/components/inserter/block-patterns-tab/pattern-category-preview-panel.js.map +1 -1
  44. package/build/components/inserter/library.js +2 -0
  45. package/build/components/inserter/library.js.map +1 -1
  46. package/build/components/inserter/menu.js +8 -2
  47. package/build/components/inserter/menu.js.map +1 -1
  48. package/build/components/inserter/search-items.js +36 -15
  49. package/build/components/inserter/search-items.js.map +1 -1
  50. package/build/components/keyboard-shortcuts/index.js +11 -0
  51. package/build/components/keyboard-shortcuts/index.js.map +1 -1
  52. package/build/components/list-view/block-select-button.js +16 -0
  53. package/build/components/list-view/block-select-button.js.map +1 -1
  54. package/build/components/list-view/block.js +1 -1
  55. package/build/components/list-view/block.js.map +1 -1
  56. package/build/components/list-view/index.js +17 -2
  57. package/build/components/list-view/index.js.map +1 -1
  58. package/build/components/list-view/use-list-view-collapse-items.js +47 -0
  59. package/build/components/list-view/use-list-view-collapse-items.js.map +1 -0
  60. package/build/components/rich-text/index.js +14 -11
  61. package/build/components/rich-text/index.js.map +1 -1
  62. package/build/components/rich-text/index.native.js +17 -11
  63. package/build/components/rich-text/index.native.js.map +1 -1
  64. package/build/components/rich-text/native/get-format-colors.native.js +1 -1
  65. package/build/components/rich-text/native/get-format-colors.native.js.map +1 -1
  66. package/build/components/rich-text/native/index.native.js +2 -2
  67. package/build/components/rich-text/native/index.native.js.map +1 -1
  68. package/build/components/rich-text/with-deprecations.js +0 -3
  69. package/build/components/rich-text/with-deprecations.js.map +1 -1
  70. package/build/components/url-popover/image-url-input-ui.js +50 -36
  71. package/build/components/url-popover/image-url-input-ui.js.map +1 -1
  72. package/build/components/use-block-display-information/index.js +4 -6
  73. package/build/components/use-block-display-information/index.js.map +1 -1
  74. package/build/hooks/anchor.js +2 -2
  75. package/build/hooks/anchor.js.map +1 -1
  76. package/build/hooks/background.js +70 -424
  77. package/build/hooks/background.js.map +1 -1
  78. package/build/hooks/index.js +7 -0
  79. package/build/hooks/index.js.map +1 -1
  80. package/build/hooks/use-zoom-out.js +47 -0
  81. package/build/hooks/use-zoom-out.js.map +1 -0
  82. package/build/index.js +7 -0
  83. package/build/index.js.map +1 -1
  84. package/build/private-apis.js +6 -1
  85. package/build/private-apis.js.map +1 -1
  86. package/build/private-apis.native.js +3 -1
  87. package/build/private-apis.native.js.map +1 -1
  88. package/build/store/private-actions.js +13 -0
  89. package/build/store/private-actions.js.map +1 -1
  90. package/build/store/private-keys.js +2 -1
  91. package/build/store/private-keys.js.map +1 -1
  92. package/build/store/private-selectors.js +24 -3
  93. package/build/store/private-selectors.js.map +1 -1
  94. package/build/store/reducer.js +22 -0
  95. package/build/store/reducer.js.map +1 -1
  96. package/build/store/selectors.js +34 -32
  97. package/build/store/selectors.js.map +1 -1
  98. package/build/store/utils.js +7 -1
  99. package/build/store/utils.js.map +1 -1
  100. package/build/utils/transform-styles/index.js +2 -1
  101. package/build/utils/transform-styles/index.js.map +1 -1
  102. package/build-module/components/block-list/block.js +11 -3
  103. package/build-module/components/block-list/block.js.map +1 -1
  104. package/build-module/components/block-mover/button.js +4 -1
  105. package/build-module/components/block-mover/button.js.map +1 -1
  106. package/build-module/components/block-mover/index.js +5 -1
  107. package/build-module/components/block-mover/index.js.map +1 -1
  108. package/build-module/components/block-patterns-list/index.js +4 -1
  109. package/build-module/components/block-patterns-list/index.js.map +1 -1
  110. package/build-module/components/block-settings-menu/block-settings-dropdown.js +7 -3
  111. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  112. package/build-module/components/block-switcher/index.js +4 -3
  113. package/build-module/components/block-switcher/index.js.map +1 -1
  114. package/build-module/components/block-toolbar/index.js +5 -4
  115. package/build-module/components/block-toolbar/index.js.map +1 -1
  116. package/build-module/components/block-toolbar/shuffle.js +18 -9
  117. package/build-module/components/block-toolbar/shuffle.js.map +1 -1
  118. package/build-module/components/block-tools/block-selection-button.js +50 -10
  119. package/build-module/components/block-tools/block-selection-button.js.map +1 -1
  120. package/build-module/components/block-tools/index.js +14 -2
  121. package/build-module/components/block-tools/index.js.map +1 -1
  122. package/build-module/components/global-styles/advanced-panel.js +9 -2
  123. package/build-module/components/global-styles/advanced-panel.js.map +1 -1
  124. package/build-module/components/global-styles/background-panel.js +430 -0
  125. package/build-module/components/global-styles/background-panel.js.map +1 -0
  126. package/build-module/components/global-styles/color-panel.js +2 -1
  127. package/build-module/components/global-styles/color-panel.js.map +1 -1
  128. package/build-module/components/global-styles/get-global-styles-changes.js +3 -0
  129. package/build-module/components/global-styles/get-global-styles-changes.js.map +1 -1
  130. package/build-module/components/global-styles/hooks.js +1 -1
  131. package/build-module/components/global-styles/hooks.js.map +1 -1
  132. package/build-module/components/global-styles/index.js +1 -0
  133. package/build-module/components/global-styles/index.js.map +1 -1
  134. package/build-module/components/global-styles/use-global-styles-output.js +16 -15
  135. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  136. package/build-module/components/global-styles/utils.js +1 -0
  137. package/build-module/components/global-styles/utils.js.map +1 -1
  138. package/build-module/components/iframe/index.js +9 -4
  139. package/build-module/components/iframe/index.js.map +1 -1
  140. package/build-module/components/inserter/block-patterns-tab/index.js.map +1 -1
  141. package/build-module/components/inserter/block-patterns-tab/pattern-category-preview-panel.js +5 -0
  142. package/build-module/components/inserter/block-patterns-tab/pattern-category-preview-panel.js.map +1 -1
  143. package/build-module/components/inserter/library.js +2 -0
  144. package/build-module/components/inserter/library.js.map +1 -1
  145. package/build-module/components/inserter/menu.js +8 -2
  146. package/build-module/components/inserter/menu.js.map +1 -1
  147. package/build-module/components/inserter/search-items.js +33 -15
  148. package/build-module/components/inserter/search-items.js.map +1 -1
  149. package/build-module/components/keyboard-shortcuts/index.js +11 -0
  150. package/build-module/components/keyboard-shortcuts/index.js.map +1 -1
  151. package/build-module/components/list-view/block-select-button.js +16 -0
  152. package/build-module/components/list-view/block-select-button.js.map +1 -1
  153. package/build-module/components/list-view/block.js +1 -1
  154. package/build-module/components/list-view/block.js.map +1 -1
  155. package/build-module/components/list-view/index.js +17 -2
  156. package/build-module/components/list-view/index.js.map +1 -1
  157. package/build-module/components/list-view/use-list-view-collapse-items.js +40 -0
  158. package/build-module/components/list-view/use-list-view-collapse-items.js.map +1 -0
  159. package/build-module/components/rich-text/index.js +15 -12
  160. package/build-module/components/rich-text/index.js.map +1 -1
  161. package/build-module/components/rich-text/index.native.js +16 -11
  162. package/build-module/components/rich-text/index.native.js.map +1 -1
  163. package/build-module/components/rich-text/native/get-format-colors.native.js +1 -1
  164. package/build-module/components/rich-text/native/get-format-colors.native.js.map +1 -1
  165. package/build-module/components/rich-text/native/index.native.js +2 -2
  166. package/build-module/components/rich-text/native/index.native.js.map +1 -1
  167. package/build-module/components/rich-text/with-deprecations.js +0 -3
  168. package/build-module/components/rich-text/with-deprecations.js.map +1 -1
  169. package/build-module/components/url-popover/image-url-input-ui.js +50 -36
  170. package/build-module/components/url-popover/image-url-input-ui.js.map +1 -1
  171. package/build-module/components/use-block-display-information/index.js +5 -7
  172. package/build-module/components/use-block-display-information/index.js.map +1 -1
  173. package/build-module/hooks/anchor.js +2 -2
  174. package/build-module/hooks/anchor.js.map +1 -1
  175. package/build-module/hooks/background.js +67 -419
  176. package/build-module/hooks/background.js.map +1 -1
  177. package/build-module/hooks/index.js +1 -0
  178. package/build-module/hooks/index.js.map +1 -1
  179. package/build-module/hooks/use-zoom-out.js +41 -0
  180. package/build-module/hooks/use-zoom-out.js.map +1 -0
  181. package/build-module/index.js +1 -1
  182. package/build-module/index.js.map +1 -1
  183. package/build-module/private-apis.js +7 -2
  184. package/build-module/private-apis.js.map +1 -1
  185. package/build-module/private-apis.native.js +3 -1
  186. package/build-module/private-apis.native.js.map +1 -1
  187. package/build-module/store/private-actions.js +12 -0
  188. package/build-module/store/private-actions.js.map +1 -1
  189. package/build-module/store/private-keys.js +1 -0
  190. package/build-module/store/private-keys.js.map +1 -1
  191. package/build-module/store/private-selectors.js +22 -4
  192. package/build-module/store/private-selectors.js.map +1 -1
  193. package/build-module/store/reducer.js +21 -0
  194. package/build-module/store/reducer.js.map +1 -1
  195. package/build-module/store/selectors.js +35 -33
  196. package/build-module/store/selectors.js.map +1 -1
  197. package/build-module/store/utils.js +6 -1
  198. package/build-module/store/utils.js.map +1 -1
  199. package/build-module/utils/transform-styles/index.js +2 -1
  200. package/build-module/utils/transform-styles/index.js.map +1 -1
  201. package/build-style/content-rtl.css +4 -1
  202. package/build-style/content.css +4 -1
  203. package/build-style/style-rtl.css +84 -79
  204. package/build-style/style.css +84 -79
  205. package/package.json +31 -31
  206. package/src/components/block-list/block.js +19 -3
  207. package/src/components/block-mover/button.js +4 -1
  208. package/src/components/block-mover/index.js +8 -1
  209. package/src/components/block-patterns-list/index.js +22 -17
  210. package/src/components/block-preview/style.scss +28 -0
  211. package/src/components/block-settings-menu/block-settings-dropdown.js +8 -2
  212. package/src/components/block-switcher/index.js +5 -3
  213. package/src/components/block-switcher/style.scss +1 -1
  214. package/src/components/block-toolbar/index.js +22 -19
  215. package/src/components/block-toolbar/shuffle.js +19 -13
  216. package/src/components/block-toolbar/style.scss +1 -1
  217. package/src/components/block-tools/block-selection-button.js +66 -9
  218. package/src/components/block-tools/index.js +18 -1
  219. package/src/components/button-block-appender/content.scss +5 -1
  220. package/src/components/default-block-appender/content.scss +2 -2
  221. package/src/components/global-styles/advanced-panel.js +8 -2
  222. package/src/components/global-styles/background-panel.js +591 -0
  223. package/src/components/global-styles/color-panel.js +2 -1
  224. package/src/components/global-styles/get-global-styles-changes.js +3 -0
  225. package/src/components/global-styles/hooks.js +1 -0
  226. package/src/components/global-styles/index.js +4 -0
  227. package/src/components/global-styles/style.scss +78 -1
  228. package/src/{hooks/test/background.js → components/global-styles/test/background-panel.js} +36 -1
  229. package/src/components/global-styles/test/get-global-styles-changes.js +22 -3
  230. package/src/components/global-styles/test/use-global-styles-output.js +9 -9
  231. package/src/components/global-styles/use-global-styles-output.js +27 -16
  232. package/src/components/global-styles/utils.js +1 -0
  233. package/src/components/iframe/index.js +19 -9
  234. package/src/components/inserter/block-patterns-tab/index.js +1 -0
  235. package/src/components/inserter/block-patterns-tab/pattern-category-preview-panel.js +5 -0
  236. package/src/components/inserter/library.js +4 -0
  237. package/src/components/inserter/menu.js +8 -1
  238. package/src/components/inserter/search-items.js +37 -15
  239. package/src/components/inserter/style.scss +6 -12
  240. package/src/components/keyboard-shortcuts/index.js +11 -0
  241. package/src/components/list-view/block-select-button.js +13 -1
  242. package/src/components/list-view/block.js +1 -1
  243. package/src/components/list-view/index.js +18 -1
  244. package/src/components/list-view/style.scss +4 -4
  245. package/src/components/list-view/use-list-view-collapse-items.js +33 -0
  246. package/src/components/rich-text/index.js +30 -13
  247. package/src/components/rich-text/index.native.js +14 -11
  248. package/src/components/rich-text/native/get-format-colors.native.js +1 -1
  249. package/src/components/rich-text/native/index.native.js +2 -2
  250. package/src/components/rich-text/with-deprecations.js +0 -3
  251. package/src/components/url-popover/image-url-input-ui.js +68 -51
  252. package/src/components/use-block-display-information/index.js +8 -10
  253. package/src/hooks/anchor.js +11 -9
  254. package/src/hooks/background.js +77 -538
  255. package/src/hooks/index.js +1 -0
  256. package/src/hooks/use-zoom-out.js +36 -0
  257. package/src/index.js +1 -0
  258. package/src/private-apis.js +13 -1
  259. package/src/private-apis.native.js +2 -0
  260. package/src/store/private-actions.js +12 -0
  261. package/src/store/private-keys.js +1 -0
  262. package/src/store/private-selectors.js +54 -27
  263. package/src/store/reducer.js +22 -0
  264. package/src/store/selectors.js +195 -180
  265. package/src/store/test/private-actions.js +10 -0
  266. package/src/store/test/private-selectors.js +13 -0
  267. package/src/store/test/reducer.js +26 -0
  268. package/src/store/test/selectors.js +90 -199
  269. package/src/store/utils.js +13 -0
  270. package/src/style.scss +0 -2
  271. package/src/utils/transform-styles/index.js +2 -1
  272. package/src/hooks/anchor.scss +0 -4
  273. package/src/hooks/background.scss +0 -75
@@ -1,77 +1,28 @@
1
- /**
2
- * External dependencies
3
- */
4
- import classnames from 'classnames';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
- import { isBlobURL } from '@wordpress/blob';
10
4
  import { getBlockSupport } from '@wordpress/blocks';
11
- import { focus } from '@wordpress/dom';
12
- import {
13
- ToggleControl,
14
- __experimentalToggleGroupControl as ToggleGroupControl,
15
- __experimentalToggleGroupControlOption as ToggleGroupControlOption,
16
- __experimentalToolsPanelItem as ToolsPanelItem,
17
- __experimentalUnitControl as UnitControl,
18
- __experimentalVStack as VStack,
19
- DropZone,
20
- FlexItem,
21
- FocalPointPicker,
22
- MenuItem,
23
- VisuallyHidden,
24
- __experimentalItemGroup as ItemGroup,
25
- __experimentalHStack as HStack,
26
- __experimentalTruncate as Truncate,
27
- } from '@wordpress/components';
28
- import { useDispatch, useSelect } from '@wordpress/data';
29
- import { Platform, useCallback, useRef } from '@wordpress/element';
30
- import { __, sprintf } from '@wordpress/i18n';
31
- import { store as noticesStore } from '@wordpress/notices';
32
- import { getFilename } from '@wordpress/url';
5
+ import { useSelect } from '@wordpress/data';
6
+ import { useCallback } from '@wordpress/element';
33
7
 
34
8
  /**
35
9
  * Internal dependencies
36
10
  */
37
11
  import InspectorControls from '../components/inspector-controls';
38
- import MediaReplaceFlow from '../components/media-replace-flow';
39
- import { useSettings } from '../components/use-settings';
40
12
  import { cleanEmptyObject } from './utils';
41
13
  import { store as blockEditorStore } from '../store';
14
+ import {
15
+ default as StylesBackgroundPanel,
16
+ useHasBackgroundPanel,
17
+ hasBackgroundImageValue,
18
+ } from '../components/global-styles/background-panel';
42
19
 
43
20
  export const BACKGROUND_SUPPORT_KEY = 'background';
44
- export const IMAGE_BACKGROUND_TYPE = 'image';
45
-
46
- /**
47
- * Checks if there is a current value in the background image block support
48
- * attributes.
49
- *
50
- * @param {Object} style Style attribute.
51
- * @return {boolean} Whether or not the block has a background image value set.
52
- */
53
- export function hasBackgroundImageValue( style ) {
54
- const hasValue =
55
- !! style?.background?.backgroundImage?.id ||
56
- !! style?.background?.backgroundImage?.url;
57
-
58
- return hasValue;
59
- }
60
21
 
61
- /**
62
- * Checks if there is a current value in the background size block support
63
- * attributes. Background size values include background size as well
64
- * as background position.
65
- *
66
- * @param {Object} style Style attribute.
67
- * @return {boolean} Whether or not the block has a background size value set.
68
- */
69
- export function hasBackgroundSizeValue( style ) {
70
- return (
71
- style?.background?.backgroundPosition !== undefined ||
72
- style?.background?.backgroundSize !== undefined
73
- );
74
- }
22
+ // Initial control values where no block style is set.
23
+ const BACKGROUND_BLOCK_DEFAULT_VALUES = {
24
+ backgroundSize: 'cover',
25
+ };
75
26
 
76
27
  /**
77
28
  * Determine whether there is block support for background.
@@ -82,10 +33,6 @@ export function hasBackgroundSizeValue( style ) {
82
33
  * @return {boolean} Whether there is support.
83
34
  */
84
35
  export function hasBackgroundSupport( blockName, feature = 'any' ) {
85
- if ( Platform.OS !== 'web' ) {
86
- return false;
87
- }
88
-
89
36
  const support = getBlockSupport( blockName, BACKGROUND_SUPPORT_KEY );
90
37
 
91
38
  if ( support === true ) {
@@ -103,84 +50,54 @@ export function hasBackgroundSupport( blockName, feature = 'any' ) {
103
50
  return !! support?.[ feature ];
104
51
  }
105
52
 
106
- function useBlockProps( { name, style } ) {
107
- if (
108
- ! hasBackgroundSupport( name ) ||
109
- ! style?.background?.backgroundImage
110
- ) {
53
+ export function setBackgroundStyleDefaults( backgroundStyle ) {
54
+ if ( ! backgroundStyle ) {
111
55
  return;
112
56
  }
113
57
 
114
- const backgroundImage = style?.background?.backgroundImage;
115
- let props;
58
+ const backgroundImage = backgroundStyle?.backgroundImage;
59
+ let backgroundStylesWithDefaults;
116
60
 
117
61
  // Set block background defaults.
118
62
  if ( backgroundImage?.source === 'file' && !! backgroundImage?.url ) {
119
- if ( ! style?.background?.backgroundSize ) {
120
- props = {
121
- style: {
122
- backgroundSize: 'cover',
123
- },
63
+ if ( ! backgroundStyle?.backgroundSize ) {
64
+ backgroundStylesWithDefaults = {
65
+ backgroundSize: 'cover',
124
66
  };
125
67
  }
126
68
 
127
69
  if (
128
- 'contain' === style?.background?.backgroundSize &&
129
- ! style?.background?.backgroundPosition
70
+ 'contain' === backgroundStyle?.backgroundSize &&
71
+ ! backgroundStyle?.backgroundPosition
130
72
  ) {
131
- props = {
132
- style: {
133
- backgroundPosition: 'center',
134
- },
73
+ backgroundStylesWithDefaults = {
74
+ backgroundPosition: 'center',
135
75
  };
136
76
  }
137
77
  }
138
78
 
139
- if ( ! props ) {
79
+ return backgroundStylesWithDefaults;
80
+ }
81
+
82
+ function useBlockProps( { name, style } ) {
83
+ if (
84
+ ! hasBackgroundSupport( name ) ||
85
+ ! style?.background?.backgroundImage
86
+ ) {
140
87
  return;
141
88
  }
142
89
 
143
- return props;
144
- }
90
+ const backgroundStyles = setBackgroundStyleDefaults( style?.background );
145
91
 
146
- /**
147
- * Resets the background image block support attributes. This can be used when disabling
148
- * the background image controls for a block via a `ToolsPanel`.
149
- *
150
- * @param {Object} style Style attribute.
151
- * @param {Function} setAttributes Function to set block's attributes.
152
- */
153
- export function resetBackgroundImage( style = {}, setAttributes ) {
154
- setAttributes( {
155
- style: cleanEmptyObject( {
156
- ...style,
157
- background: {
158
- ...style?.background,
159
- backgroundImage: undefined,
160
- },
161
- } ),
162
- } );
163
- }
92
+ if ( ! backgroundStyles ) {
93
+ return;
94
+ }
164
95
 
165
- /**
166
- * Resets the background size block support attributes. This can be used when disabling
167
- * the background size controls for a block via a `ToolsPanel`.
168
- *
169
- * @param {Object} style Style attribute.
170
- * @param {Function} setAttributes Function to set block's attributes.
171
- */
172
- function resetBackgroundSize( style = {}, setAttributes ) {
173
- setAttributes( {
174
- style: cleanEmptyObject( {
175
- ...style,
176
- background: {
177
- ...style?.background,
178
- backgroundPosition: undefined,
179
- backgroundRepeat: undefined,
180
- backgroundSize: undefined,
181
- },
182
- } ),
183
- } );
96
+ return {
97
+ style: {
98
+ ...backgroundStyles,
99
+ },
100
+ };
184
101
  }
185
102
 
186
103
  /**
@@ -194,252 +111,28 @@ export function getBackgroundImageClasses( style ) {
194
111
  return hasBackgroundImageValue( style ) ? 'has-background' : '';
195
112
  }
196
113
 
197
- function InspectorImagePreview( { label, filename, url: imgUrl } ) {
198
- const imgLabel = label || getFilename( imgUrl );
199
- return (
200
- <ItemGroup as="span">
201
- <HStack justify="flex-start" as="span">
202
- <span
203
- className={ classnames(
204
- 'block-editor-hooks__background__inspector-image-indicator-wrapper',
205
- {
206
- 'has-image': imgUrl,
207
- }
208
- ) }
209
- aria-hidden
210
- >
211
- { imgUrl && (
212
- <span
213
- className="block-editor-hooks__background__inspector-image-indicator"
214
- style={ {
215
- backgroundImage: `url(${ imgUrl })`,
216
- } }
217
- />
218
- ) }
219
- </span>
220
- <FlexItem as="span">
221
- <Truncate
222
- numberOfLines={ 1 }
223
- className="block-editor-hooks__background__inspector-media-replace-title"
224
- >
225
- { imgLabel }
226
- </Truncate>
227
- <VisuallyHidden as="span">
228
- { filename
229
- ? sprintf(
230
- /* translators: %s: file name */
231
- __( 'Selected image: %s' ),
232
- filename
233
- )
234
- : __( 'No image selected' ) }
235
- </VisuallyHidden>
236
- </FlexItem>
237
- </HStack>
238
- </ItemGroup>
239
- );
240
- }
241
-
242
- function BackgroundImagePanelItem( {
243
- clientId,
244
- isShownByDefault,
245
- setAttributes,
246
- } ) {
247
- const { style, mediaUpload } = useSelect(
248
- ( select ) => {
249
- const { getBlockAttributes, getSettings } =
250
- select( blockEditorStore );
251
-
252
- return {
253
- style: getBlockAttributes( clientId )?.style,
254
- mediaUpload: getSettings().mediaUpload,
255
- };
256
- },
257
- [ clientId ]
258
- );
259
- const { id, title, url } = style?.background?.backgroundImage || {};
260
-
261
- const replaceContainerRef = useRef();
262
-
263
- const { createErrorNotice } = useDispatch( noticesStore );
264
- const onUploadError = ( message ) => {
265
- createErrorNotice( message, { type: 'snackbar' } );
266
- };
267
-
268
- const onSelectMedia = ( media ) => {
269
- if ( ! media || ! media.url ) {
270
- const newStyle = {
271
- ...style,
272
- background: {
273
- ...style?.background,
274
- backgroundImage: undefined,
275
- },
276
- };
277
-
278
- const newAttributes = {
279
- style: cleanEmptyObject( newStyle ),
280
- };
281
-
282
- setAttributes( newAttributes );
283
- return;
284
- }
285
-
286
- if ( isBlobURL( media.url ) ) {
287
- return;
288
- }
289
-
290
- // For media selections originated from a file upload.
291
- if (
292
- ( media.media_type &&
293
- media.media_type !== IMAGE_BACKGROUND_TYPE ) ||
294
- ( ! media.media_type &&
295
- media.type &&
296
- media.type !== IMAGE_BACKGROUND_TYPE )
297
- ) {
298
- onUploadError(
299
- __( 'Only images can be used as a background image.' )
300
- );
301
- return;
302
- }
303
-
304
- const newStyle = {
305
- ...style,
306
- background: {
307
- ...style?.background,
308
- backgroundImage: {
309
- url: media.url,
310
- id: media.id,
311
- source: 'file',
312
- title: media.title || undefined,
313
- },
314
- },
315
- };
316
-
317
- const newAttributes = {
318
- style: cleanEmptyObject( newStyle ),
319
- };
320
-
321
- setAttributes( newAttributes );
322
- };
323
-
324
- const onFilesDrop = ( filesList ) => {
325
- mediaUpload( {
326
- allowedTypes: [ 'image' ],
327
- filesList,
328
- onFileChange( [ image ] ) {
329
- if ( isBlobURL( image?.url ) ) {
330
- return;
331
- }
332
- onSelectMedia( image );
333
- },
334
- onError: onUploadError,
335
- } );
336
- };
337
-
338
- const resetAllFilter = useCallback( ( previousValue ) => {
114
+ function BackgroundInspectorControl( { children } ) {
115
+ const resetAllFilter = useCallback( ( attributes ) => {
339
116
  return {
340
- ...previousValue,
117
+ ...attributes,
341
118
  style: {
342
- ...previousValue.style,
119
+ ...attributes.style,
343
120
  background: undefined,
344
121
  },
345
122
  };
346
123
  }, [] );
347
-
348
- const hasValue = hasBackgroundImageValue( style );
349
-
350
124
  return (
351
- <ToolsPanelItem
352
- className="single-column"
353
- hasValue={ () => hasValue }
354
- label={ __( 'Background image' ) }
355
- onDeselect={ () => resetBackgroundImage( style, setAttributes ) }
356
- isShownByDefault={ isShownByDefault }
357
- resetAllFilter={ resetAllFilter }
358
- panelId={ clientId }
359
- >
360
- <div
361
- className="block-editor-hooks__background__inspector-media-replace-container"
362
- ref={ replaceContainerRef }
363
- >
364
- <MediaReplaceFlow
365
- mediaId={ id }
366
- mediaURL={ url }
367
- allowedTypes={ [ IMAGE_BACKGROUND_TYPE ] }
368
- accept="image/*"
369
- onSelect={ onSelectMedia }
370
- name={
371
- <InspectorImagePreview
372
- label={ __( 'Background image' ) }
373
- filename={ title }
374
- url={ url }
375
- />
376
- }
377
- variant="secondary"
378
- >
379
- { hasValue && (
380
- <MenuItem
381
- onClick={ () => {
382
- const [ toggleButton ] = focus.tabbable.find(
383
- replaceContainerRef.current
384
- );
385
- // Focus the toggle button and close the dropdown menu.
386
- // This ensures similar behaviour as to selecting an image, where the dropdown is
387
- // closed and focus is redirected to the dropdown toggle button.
388
- toggleButton?.focus();
389
- toggleButton?.click();
390
- resetBackgroundImage( style, setAttributes );
391
- } }
392
- >
393
- { __( 'Reset ' ) }
394
- </MenuItem>
395
- ) }
396
- </MediaReplaceFlow>
397
- <DropZone
398
- onFilesDrop={ onFilesDrop }
399
- label={ __( 'Drop to upload' ) }
400
- />
401
- </div>
402
- </ToolsPanelItem>
125
+ <InspectorControls group="background" resetAllFilter={ resetAllFilter }>
126
+ { children }
127
+ </InspectorControls>
403
128
  );
404
129
  }
405
130
 
406
- function backgroundSizeHelpText( value ) {
407
- if ( value === 'cover' || value === undefined ) {
408
- return __( 'Image covers the space evenly.' );
409
- }
410
- if ( value === 'contain' ) {
411
- return __( 'Image is contained without distortion.' );
412
- }
413
- return __( 'Specify a fixed width.' );
414
- }
415
-
416
- export const coordsToBackgroundPosition = ( value ) => {
417
- if ( ! value || ( isNaN( value.x ) && isNaN( value.y ) ) ) {
418
- return undefined;
419
- }
420
-
421
- const x = isNaN( value.x ) ? 0.5 : value.x;
422
- const y = isNaN( value.y ) ? 0.5 : value.y;
423
-
424
- return `${ x * 100 }% ${ y * 100 }%`;
425
- };
426
-
427
- export const backgroundPositionToCoords = ( value ) => {
428
- if ( ! value ) {
429
- return { x: undefined, y: undefined };
430
- }
431
-
432
- let [ x, y ] = value.split( ' ' ).map( ( v ) => parseFloat( v ) / 100 );
433
- x = isNaN( x ) ? undefined : x;
434
- y = isNaN( y ) ? x : y;
435
-
436
- return { x, y };
437
- };
438
-
439
- function BackgroundSizePanelItem( {
131
+ export function BackgroundImagePanel( {
440
132
  clientId,
441
- isShownByDefault,
133
+ name,
442
134
  setAttributes,
135
+ settings,
443
136
  } ) {
444
137
  const style = useSelect(
445
138
  ( select ) =>
@@ -447,198 +140,44 @@ function BackgroundSizePanelItem( {
447
140
  [ clientId ]
448
141
  );
449
142
 
450
- const sizeValue = style?.background?.backgroundSize;
451
- const repeatValue = style?.background?.backgroundRepeat;
452
-
453
- // An `undefined` value is treated as `cover` by the toggle group control.
454
- // An empty string is treated as `auto` by the toggle group control. This
455
- // allows a user to select "Size" and then enter a custom value, with an
456
- // empty value being treated as `auto`.
457
- const currentValueForToggle =
458
- ( sizeValue !== undefined &&
459
- sizeValue !== 'cover' &&
460
- sizeValue !== 'contain' ) ||
461
- sizeValue === ''
462
- ? 'auto'
463
- : sizeValue || 'cover';
464
-
465
- // If the current value is `cover` and the repeat value is `undefined`, then
466
- // the toggle should be unchecked as the default state. Otherwise, the toggle
467
- // should reflect the current repeat value.
468
- const repeatCheckedValue = ! (
469
- repeatValue === 'no-repeat' ||
470
- ( currentValueForToggle === 'cover' && repeatValue === undefined )
471
- );
472
-
473
- const hasValue = hasBackgroundSizeValue( style );
474
-
475
- const resetAllFilter = useCallback( ( previousValue ) => {
476
- return {
477
- ...previousValue,
478
- style: {
479
- ...previousValue.style,
480
- background: {
481
- ...previousValue.style?.background,
482
- backgroundRepeat: undefined,
483
- backgroundSize: undefined,
484
- },
485
- },
486
- };
487
- }, [] );
488
-
489
- const updateBackgroundSize = ( next ) => {
490
- // When switching to 'contain' toggle the repeat off.
491
- let nextRepeat = repeatValue;
492
-
493
- if ( next === 'contain' ) {
494
- nextRepeat = 'no-repeat';
495
- }
496
-
497
- if (
498
- ( currentValueForToggle === 'cover' ||
499
- currentValueForToggle === 'contain' ) &&
500
- next === 'auto'
501
- ) {
502
- nextRepeat = undefined;
503
- }
504
-
505
- setAttributes( {
506
- style: cleanEmptyObject( {
507
- ...style,
508
- background: {
509
- ...style?.background,
510
- backgroundRepeat: nextRepeat,
511
- backgroundSize: next,
512
- },
513
- } ),
514
- } );
515
- };
516
-
517
- const updateBackgroundPosition = ( next ) => {
518
- setAttributes( {
519
- style: cleanEmptyObject( {
520
- ...style,
521
- background: {
522
- ...style?.background,
523
- backgroundPosition: coordsToBackgroundPosition( next ),
524
- },
525
- } ),
526
- } );
527
- };
528
-
529
- const toggleIsRepeated = () => {
530
- setAttributes( {
531
- style: cleanEmptyObject( {
532
- ...style,
533
- background: {
534
- ...style?.background,
535
- backgroundRepeat:
536
- repeatCheckedValue === true ? 'no-repeat' : undefined,
537
- },
538
- } ),
539
- } );
540
- };
541
-
542
- return (
543
- <VStack
544
- as={ ToolsPanelItem }
545
- spacing={ 2 }
546
- className="single-column"
547
- hasValue={ () => hasValue }
548
- label={ __( 'Size' ) }
549
- onDeselect={ () => resetBackgroundSize( style, setAttributes ) }
550
- isShownByDefault={ isShownByDefault }
551
- resetAllFilter={ resetAllFilter }
552
- panelId={ clientId }
553
- >
554
- <FocalPointPicker
555
- __next40pxDefaultSize
556
- label={ __( 'Position' ) }
557
- url={ style?.background?.backgroundImage?.url }
558
- value={ backgroundPositionToCoords(
559
- style?.background?.backgroundPosition
560
- ) }
561
- onChange={ updateBackgroundPosition }
562
- />
563
- <ToggleGroupControl
564
- size={ '__unstable-large' }
565
- label={ __( 'Size' ) }
566
- value={ currentValueForToggle }
567
- onChange={ updateBackgroundSize }
568
- isBlock
569
- help={ backgroundSizeHelpText( sizeValue ) }
570
- >
571
- <ToggleGroupControlOption
572
- key={ 'cover' }
573
- value={ 'cover' }
574
- label={ __( 'Cover' ) }
575
- />
576
- <ToggleGroupControlOption
577
- key={ 'contain' }
578
- value={ 'contain' }
579
- label={ __( 'Contain' ) }
580
- />
581
- <ToggleGroupControlOption
582
- key={ 'fixed' }
583
- value={ 'auto' }
584
- label={ __( 'Fixed' ) }
585
- />
586
- </ToggleGroupControl>
587
- { sizeValue !== undefined &&
588
- sizeValue !== 'cover' &&
589
- sizeValue !== 'contain' ? (
590
- <UnitControl
591
- size={ '__unstable-large' }
592
- onChange={ updateBackgroundSize }
593
- value={ sizeValue }
594
- />
595
- ) : null }
596
- { currentValueForToggle !== 'cover' && (
597
- <ToggleControl
598
- label={ __( 'Repeat' ) }
599
- checked={ repeatCheckedValue }
600
- onChange={ toggleIsRepeated }
601
- />
602
- ) }
603
- </VStack>
604
- );
605
- }
606
-
607
- export function BackgroundImagePanel( props ) {
608
- const [ backgroundImage, backgroundSize ] = useSettings(
609
- 'background.backgroundImage',
610
- 'background.backgroundSize'
611
- );
612
-
613
143
  if (
614
- ! backgroundImage ||
615
- ! hasBackgroundSupport( props.name, 'backgroundImage' )
144
+ ! useHasBackgroundPanel( settings ) ||
145
+ ! hasBackgroundSupport( name, 'backgroundImage' )
616
146
  ) {
617
147
  return null;
618
148
  }
619
149
 
620
- const showBackgroundSize = !! (
621
- backgroundSize && hasBackgroundSupport( props.name, 'backgroundSize' )
622
- );
623
-
624
- const defaultControls = getBlockSupport( props.name, [
150
+ const defaultControls = getBlockSupport( name, [
625
151
  BACKGROUND_SUPPORT_KEY,
626
152
  '__experimentalDefaultControls',
627
153
  ] );
628
154
 
155
+ const onChange = ( newStyle ) => {
156
+ setAttributes( {
157
+ style: cleanEmptyObject( newStyle ),
158
+ } );
159
+ };
160
+
161
+ const updatedSettings = {
162
+ ...settings,
163
+ background: {
164
+ ...settings.background,
165
+ backgroundSize:
166
+ settings?.background?.backgroundSize &&
167
+ hasBackgroundSupport( name, 'backgroundSize' ),
168
+ },
169
+ };
170
+
629
171
  return (
630
- <InspectorControls group="background">
631
- <BackgroundImagePanelItem
632
- isShownByDefault={ defaultControls?.backgroundImage }
633
- { ...props }
634
- />
635
- { showBackgroundSize && (
636
- <BackgroundSizePanelItem
637
- isShownByDefault={ defaultControls?.backgroundSize }
638
- { ...props }
639
- />
640
- ) }
641
- </InspectorControls>
172
+ <StylesBackgroundPanel
173
+ as={ BackgroundInspectorControl }
174
+ panelId={ clientId }
175
+ defaultControls={ defaultControls }
176
+ defaultValues={ BACKGROUND_BLOCK_DEFAULT_VALUES }
177
+ settings={ updatedSettings }
178
+ onChange={ onChange }
179
+ value={ style }
180
+ />
642
181
  );
643
182
  }
644
183
 
@@ -80,3 +80,4 @@ export { getSpacingClassesAndStyles } from './use-spacing-props';
80
80
  export { getTypographyClassesAndStyles } from './use-typography-props';
81
81
  export { getGapCSSValue } from './gap';
82
82
  export { useCachedTruthy } from './use-cached-truthy';
83
+ export { useZoomOut } from './use-zoom-out';