@wordpress/block-editor 14.2.1-next.5368f64a9.0 → 14.3.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 (144) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/background-image-control/index.js +566 -0
  3. package/build/components/background-image-control/index.js.map +1 -0
  4. package/build/components/block-card/index.js +5 -2
  5. package/build/components/block-card/index.js.map +1 -1
  6. package/build/components/block-list/use-block-props/use-zoom-out-mode-exit.js +4 -2
  7. package/build/components/block-list/use-block-props/use-zoom-out-mode-exit.js.map +1 -1
  8. package/build/components/global-styles/background-panel.js +20 -545
  9. package/build/components/global-styles/background-panel.js.map +1 -1
  10. package/build/components/global-styles/dimensions-panel.js +3 -0
  11. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  12. package/build/components/grid/grid-item-resizer.js +2 -2
  13. package/build/components/grid/grid-item-resizer.js.map +1 -1
  14. package/build/components/iframe/index.js +1 -0
  15. package/build/components/iframe/index.js.map +1 -1
  16. package/build/components/image-editor/use-save-image.js +6 -0
  17. package/build/components/image-editor/use-save-image.js.map +1 -1
  18. package/build/components/image-editor/use-transform-image.js +1 -0
  19. package/build/components/image-editor/use-transform-image.js.map +1 -1
  20. package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js +2 -4
  21. package/build/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js.map +1 -1
  22. package/build/components/inserter/block-patterns-tab/index.js +2 -4
  23. package/build/components/inserter/block-patterns-tab/index.js.map +1 -1
  24. package/build/components/inserter/media-tab/media-preview.js +4 -8
  25. package/build/components/inserter/media-tab/media-preview.js.map +1 -1
  26. package/build/components/inserter/media-tab/media-tab.js +2 -4
  27. package/build/components/inserter/media-tab/media-tab.js.map +1 -1
  28. package/build/components/inserter/quick-inserter.js +2 -4
  29. package/build/components/inserter/quick-inserter.js.map +1 -1
  30. package/build/components/inserter-listbox/item.js +2 -4
  31. package/build/components/inserter-listbox/item.js.map +1 -1
  32. package/build/components/link-control/index.js +14 -14
  33. package/build/components/link-control/index.js.map +1 -1
  34. package/build/components/link-control/search-input.js +4 -2
  35. package/build/components/link-control/search-input.js.map +1 -1
  36. package/build/components/rich-text/index.js +10 -4
  37. package/build/components/rich-text/index.js.map +1 -1
  38. package/build/components/spacing-sizes-control/index.js +8 -9
  39. package/build/components/spacing-sizes-control/index.js.map +1 -1
  40. package/build/components/spacing-sizes-control/linked-button.js +35 -0
  41. package/build/components/spacing-sizes-control/linked-button.js.map +1 -0
  42. package/build/components/spacing-sizes-control/utils.js +3 -2
  43. package/build/components/spacing-sizes-control/utils.js.map +1 -1
  44. package/build/components/url-input/index.js +7 -6
  45. package/build/components/url-input/index.js.map +1 -1
  46. package/build/hooks/block-bindings.js +65 -53
  47. package/build/hooks/block-bindings.js.map +1 -1
  48. package/build/hooks/block-hooks.js +1 -8
  49. package/build/hooks/block-hooks.js.map +1 -1
  50. package/build/store/private-selectors.js +10 -0
  51. package/build/store/private-selectors.js.map +1 -1
  52. package/build-module/components/background-image-control/index.js +556 -0
  53. package/build-module/components/background-image-control/index.js.map +1 -0
  54. package/build-module/components/block-card/index.js +6 -3
  55. package/build-module/components/block-card/index.js.map +1 -1
  56. package/build-module/components/block-list/use-block-props/use-zoom-out-mode-exit.js +4 -2
  57. package/build-module/components/block-list/use-block-props/use-zoom-out-mode-exit.js.map +1 -1
  58. package/build-module/components/global-styles/background-panel.js +22 -546
  59. package/build-module/components/global-styles/background-panel.js.map +1 -1
  60. package/build-module/components/global-styles/dimensions-panel.js +3 -0
  61. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  62. package/build-module/components/grid/grid-item-resizer.js +2 -2
  63. package/build-module/components/grid/grid-item-resizer.js.map +1 -1
  64. package/build-module/components/iframe/index.js +1 -0
  65. package/build-module/components/iframe/index.js.map +1 -1
  66. package/build-module/components/image-editor/use-save-image.js +6 -0
  67. package/build-module/components/image-editor/use-save-image.js.map +1 -1
  68. package/build-module/components/image-editor/use-transform-image.js +1 -0
  69. package/build-module/components/image-editor/use-transform-image.js.map +1 -1
  70. package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js +2 -4
  71. package/build-module/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js.map +1 -1
  72. package/build-module/components/inserter/block-patterns-tab/index.js +2 -4
  73. package/build-module/components/inserter/block-patterns-tab/index.js.map +1 -1
  74. package/build-module/components/inserter/media-tab/media-preview.js +4 -8
  75. package/build-module/components/inserter/media-tab/media-preview.js.map +1 -1
  76. package/build-module/components/inserter/media-tab/media-tab.js +2 -4
  77. package/build-module/components/inserter/media-tab/media-tab.js.map +1 -1
  78. package/build-module/components/inserter/quick-inserter.js +2 -4
  79. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  80. package/build-module/components/inserter-listbox/item.js +2 -4
  81. package/build-module/components/inserter-listbox/item.js.map +1 -1
  82. package/build-module/components/link-control/index.js +15 -15
  83. package/build-module/components/link-control/index.js.map +1 -1
  84. package/build-module/components/link-control/search-input.js +4 -2
  85. package/build-module/components/link-control/search-input.js.map +1 -1
  86. package/build-module/components/rich-text/index.js +10 -4
  87. package/build-module/components/rich-text/index.js.map +1 -1
  88. package/build-module/components/spacing-sizes-control/index.js +9 -10
  89. package/build-module/components/spacing-sizes-control/index.js.map +1 -1
  90. package/build-module/components/spacing-sizes-control/linked-button.js +28 -0
  91. package/build-module/components/spacing-sizes-control/linked-button.js.map +1 -0
  92. package/build-module/components/spacing-sizes-control/utils.js +3 -2
  93. package/build-module/components/spacing-sizes-control/utils.js.map +1 -1
  94. package/build-module/components/url-input/index.js +8 -7
  95. package/build-module/components/url-input/index.js.map +1 -1
  96. package/build-module/hooks/block-bindings.js +65 -53
  97. package/build-module/hooks/block-bindings.js.map +1 -1
  98. package/build-module/hooks/block-hooks.js +3 -10
  99. package/build-module/hooks/block-hooks.js.map +1 -1
  100. package/build-module/store/private-selectors.js +10 -0
  101. package/build-module/store/private-selectors.js.map +1 -1
  102. package/build-style/style-rtl.css +152 -285
  103. package/build-style/style.css +152 -285
  104. package/package.json +32 -32
  105. package/src/components/background-image-control/index.js +741 -0
  106. package/src/components/background-image-control/style.scss +170 -0
  107. package/src/components/background-image-control/test/index.js +47 -0
  108. package/src/components/block-card/index.js +12 -3
  109. package/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js +2 -5
  110. package/src/components/global-styles/background-panel.js +19 -730
  111. package/src/components/global-styles/dimensions-panel.js +3 -0
  112. package/src/components/global-styles/style.scss +0 -168
  113. package/src/components/global-styles/test/background-panel.js +1 -47
  114. package/src/components/grid/grid-item-resizer.js +2 -2
  115. package/src/components/image-editor/use-save-image.js +7 -0
  116. package/src/components/inserter/block-patterns-explorer/pattern-explorer-sidebar.js +1 -2
  117. package/src/components/inserter/block-patterns-tab/index.js +1 -2
  118. package/src/components/inserter/media-tab/media-preview.js +2 -4
  119. package/src/components/inserter/media-tab/media-tab.js +1 -2
  120. package/src/components/inserter/quick-inserter.js +1 -2
  121. package/src/components/inserter/style.scss +0 -10
  122. package/src/components/inserter-listbox/item.js +1 -5
  123. package/src/components/link-control/index.js +19 -14
  124. package/src/components/link-control/search-input.js +2 -0
  125. package/src/components/link-control/style.scss +0 -22
  126. package/src/components/list-view/style.scss +1 -1
  127. package/src/components/rich-text/index.js +20 -5
  128. package/src/components/spacing-sizes-control/index.js +10 -13
  129. package/src/components/spacing-sizes-control/linked-button.js +32 -0
  130. package/src/components/spacing-sizes-control/test/utils.js +22 -30
  131. package/src/components/spacing-sizes-control/utils.js +6 -2
  132. package/src/components/url-input/index.js +5 -4
  133. package/src/components/url-input/style.scss +3 -26
  134. package/src/hooks/block-bindings.js +64 -50
  135. package/src/hooks/block-hooks.js +3 -14
  136. package/src/hooks/block-hooks.scss +0 -9
  137. package/src/store/private-selectors.js +9 -0
  138. package/src/style.scss +1 -0
  139. package/src/utils/test/transform-styles.js +1 -1
  140. package/build/components/spacing-sizes-control/sides-dropdown/index.js +0 -86
  141. package/build/components/spacing-sizes-control/sides-dropdown/index.js.map +0 -1
  142. package/build-module/components/spacing-sizes-control/sides-dropdown/index.js +0 -81
  143. package/build-module/components/spacing-sizes-control/sides-dropdown/index.js.map +0 -1
  144. package/src/components/spacing-sizes-control/sides-dropdown/index.js +0 -91
@@ -1,41 +1,19 @@
1
- /**
2
- * External dependencies
3
- */
4
- import clsx from 'clsx';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
9
- import { __experimentalToolsPanel as ToolsPanel, __experimentalToolsPanelItem as ToolsPanelItem, ToggleControl, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, __experimentalUnitControl as UnitControl, __experimentalVStack as VStack, DropZone, FlexItem, FocalPointPicker, MenuItem, VisuallyHidden, __experimentalItemGroup as ItemGroup, __experimentalHStack as HStack, __experimentalTruncate as Truncate, Dropdown, Placeholder, Spinner, __experimentalDropdownContentWrapper as DropdownContentWrapper } from '@wordpress/components';
10
- import { __, _x, sprintf } from '@wordpress/i18n';
11
- import { store as noticesStore } from '@wordpress/notices';
12
- import { getFilename } from '@wordpress/url';
13
- import { useCallback, Platform, useRef, useState, useEffect, useMemo } from '@wordpress/element';
14
- import { useDispatch, useSelect } from '@wordpress/data';
15
- import { focus } from '@wordpress/dom';
16
- import { isBlobURL } from '@wordpress/blob';
17
-
4
+ import { __experimentalToolsPanel as ToolsPanel, __experimentalToolsPanelItem as ToolsPanelItem } from '@wordpress/components';
5
+ import { useCallback, Platform } from '@wordpress/element';
18
6
  /**
19
7
  * Internal dependencies
20
8
  */
21
- import { useToolsPanelDropdownMenuProps, getResolvedValue } from './utils';
9
+ import BackgroundImageControl from '../background-image-control';
10
+ import { useToolsPanelDropdownMenuProps } from './utils';
22
11
  import { setImmutably } from '../../utils/object';
23
- import MediaReplaceFlow from '../media-replace-flow';
24
- import { store as blockEditorStore } from '../../store';
25
- import { globalStylesDataKey, globalStylesLinksDataKey } from '../../store/private-keys';
12
+ import { __ } from '@wordpress/i18n';
26
13
  import { jsx as _jsx } from "react/jsx-runtime";
27
- import { jsxs as _jsxs } from "react/jsx-runtime";
28
- const IMAGE_BACKGROUND_TYPE = 'image';
29
14
  const DEFAULT_CONTROLS = {
30
15
  backgroundImage: true
31
16
  };
32
- const BACKGROUND_POPOVER_PROPS = {
33
- placement: 'left-start',
34
- offset: 36,
35
- shift: true,
36
- className: 'block-editor-global-styles-background-panel__popover'
37
- };
38
- const noop = () => {};
39
17
 
40
18
  /**
41
19
  * Checks site settings to see if the background panel may be used.
@@ -73,429 +51,6 @@ export function hasBackgroundImageValue(style) {
73
51
  // Supports url() string values in theme.json.
74
52
  'string' === typeof style?.background?.backgroundImage || !!style?.background?.backgroundImage?.url;
75
53
  }
76
-
77
- /**
78
- * Get the help text for the background size control.
79
- *
80
- * @param {string} value backgroundSize value.
81
- * @return {string} Translated help text.
82
- */
83
- function backgroundSizeHelpText(value) {
84
- if (value === 'cover' || value === undefined) {
85
- return __('Image covers the space evenly.');
86
- }
87
- if (value === 'contain') {
88
- return __('Image is contained without distortion.');
89
- }
90
- return __('Image has a fixed width.');
91
- }
92
-
93
- /**
94
- * Converts decimal x and y coords from FocalPointPicker to percentage-based values
95
- * to use as backgroundPosition value.
96
- *
97
- * @param {{x?:number, y?:number}} value FocalPointPicker coords.
98
- * @return {string} backgroundPosition value.
99
- */
100
- export const coordsToBackgroundPosition = value => {
101
- if (!value || isNaN(value.x) && isNaN(value.y)) {
102
- return undefined;
103
- }
104
- const x = isNaN(value.x) ? 0.5 : value.x;
105
- const y = isNaN(value.y) ? 0.5 : value.y;
106
- return `${x * 100}% ${y * 100}%`;
107
- };
108
-
109
- /**
110
- * Converts backgroundPosition value to x and y coords for FocalPointPicker.
111
- *
112
- * @param {string} value backgroundPosition value.
113
- * @return {{x?:number, y?:number}} FocalPointPicker coords.
114
- */
115
- export const backgroundPositionToCoords = value => {
116
- if (!value) {
117
- return {
118
- x: undefined,
119
- y: undefined
120
- };
121
- }
122
- let [x, y] = value.split(' ').map(v => parseFloat(v) / 100);
123
- x = isNaN(x) ? undefined : x;
124
- y = isNaN(y) ? x : y;
125
- return {
126
- x,
127
- y
128
- };
129
- };
130
- function InspectorImagePreviewItem({
131
- as = 'span',
132
- imgUrl,
133
- toggleProps = {},
134
- filename,
135
- label,
136
- className,
137
- onToggleCallback = noop
138
- }) {
139
- useEffect(() => {
140
- if (typeof toggleProps?.isOpen !== 'undefined') {
141
- onToggleCallback(toggleProps?.isOpen);
142
- }
143
- }, [toggleProps?.isOpen, onToggleCallback]);
144
- return /*#__PURE__*/_jsx(ItemGroup, {
145
- as: as,
146
- className: className,
147
- ...toggleProps,
148
- children: /*#__PURE__*/_jsxs(HStack, {
149
- justify: "flex-start",
150
- as: "span",
151
- className: "block-editor-global-styles-background-panel__inspector-preview-inner",
152
- children: [imgUrl && /*#__PURE__*/_jsx("span", {
153
- className: "block-editor-global-styles-background-panel__inspector-image-indicator-wrapper",
154
- "aria-hidden": true,
155
- children: /*#__PURE__*/_jsx("span", {
156
- className: "block-editor-global-styles-background-panel__inspector-image-indicator",
157
- style: {
158
- backgroundImage: `url(${imgUrl})`
159
- }
160
- })
161
- }), /*#__PURE__*/_jsxs(FlexItem, {
162
- as: "span",
163
- style: imgUrl ? {} : {
164
- flexGrow: 1
165
- },
166
- children: [/*#__PURE__*/_jsx(Truncate, {
167
- numberOfLines: 1,
168
- className: "block-editor-global-styles-background-panel__inspector-media-replace-title",
169
- children: label
170
- }), /*#__PURE__*/_jsx(VisuallyHidden, {
171
- as: "span",
172
- children: imgUrl ? sprintf( /* translators: %s: file name */
173
- __('Background image: %s'), filename || label) : __('No background image selected')
174
- })]
175
- })]
176
- })
177
- });
178
- }
179
- function BackgroundControlsPanel({
180
- label,
181
- filename,
182
- url: imgUrl,
183
- children,
184
- onToggle: onToggleCallback = noop,
185
- hasImageValue
186
- }) {
187
- if (!hasImageValue) {
188
- return;
189
- }
190
- const imgLabel = label || getFilename(imgUrl) || __('Add background image');
191
- return /*#__PURE__*/_jsx(Dropdown, {
192
- popoverProps: BACKGROUND_POPOVER_PROPS,
193
- renderToggle: ({
194
- onToggle,
195
- isOpen
196
- }) => {
197
- const toggleProps = {
198
- onClick: onToggle,
199
- className: 'block-editor-global-styles-background-panel__dropdown-toggle',
200
- 'aria-expanded': isOpen,
201
- 'aria-label': __('Background size, position and repeat options.'),
202
- isOpen
203
- };
204
- return /*#__PURE__*/_jsx(InspectorImagePreviewItem, {
205
- imgUrl: imgUrl,
206
- filename: filename,
207
- label: imgLabel,
208
- toggleProps: toggleProps,
209
- as: "button",
210
- onToggleCallback: onToggleCallback
211
- });
212
- },
213
- renderContent: () => /*#__PURE__*/_jsx(DropdownContentWrapper, {
214
- className: "block-editor-global-styles-background-panel__dropdown-content-wrapper",
215
- paddingSize: "medium",
216
- children: children
217
- })
218
- });
219
- }
220
- function LoadingSpinner() {
221
- return /*#__PURE__*/_jsx(Placeholder, {
222
- className: "block-editor-global-styles-background-panel__loading",
223
- children: /*#__PURE__*/_jsx(Spinner, {})
224
- });
225
- }
226
- function BackgroundImageControls({
227
- onChange,
228
- style,
229
- inheritedValue,
230
- onRemoveImage = noop,
231
- onResetImage = noop,
232
- displayInPanel,
233
- defaultValues
234
- }) {
235
- const [isUploading, setIsUploading] = useState(false);
236
- const {
237
- getSettings
238
- } = useSelect(blockEditorStore);
239
- const {
240
- id,
241
- title,
242
- url
243
- } = style?.background?.backgroundImage || {
244
- ...inheritedValue?.background?.backgroundImage
245
- };
246
- const replaceContainerRef = useRef();
247
- const {
248
- createErrorNotice
249
- } = useDispatch(noticesStore);
250
- const onUploadError = message => {
251
- createErrorNotice(message, {
252
- type: 'snackbar'
253
- });
254
- setIsUploading(false);
255
- };
256
- const resetBackgroundImage = () => onChange(setImmutably(style, ['background', 'backgroundImage'], undefined));
257
- const onSelectMedia = media => {
258
- if (!media || !media.url) {
259
- resetBackgroundImage();
260
- setIsUploading(false);
261
- return;
262
- }
263
- if (isBlobURL(media.url)) {
264
- setIsUploading(true);
265
- return;
266
- }
267
-
268
- // For media selections originated from a file upload.
269
- if (media.media_type && media.media_type !== IMAGE_BACKGROUND_TYPE || !media.media_type && media.type && media.type !== IMAGE_BACKGROUND_TYPE) {
270
- onUploadError(__('Only images can be used as a background image.'));
271
- return;
272
- }
273
- const sizeValue = style?.background?.backgroundSize || defaultValues?.backgroundSize;
274
- const positionValue = style?.background?.backgroundPosition;
275
- onChange(setImmutably(style, ['background'], {
276
- ...style?.background,
277
- backgroundImage: {
278
- url: media.url,
279
- id: media.id,
280
- source: 'file',
281
- title: media.title || undefined
282
- },
283
- backgroundPosition:
284
- /*
285
- * A background image uploaded and set in the editor receives a default background position of '50% 0',
286
- * when the background image size is the equivalent of "Tile".
287
- * This is to increase the chance that the image's focus point is visible.
288
- * This is in-editor only to assist with the user experience.
289
- */
290
- !positionValue && ('auto' === sizeValue || !sizeValue) ? '50% 0' : positionValue,
291
- backgroundSize: sizeValue
292
- }));
293
- setIsUploading(false);
294
- };
295
-
296
- // Drag and drop callback, restricting image to one.
297
- const onFilesDrop = filesList => {
298
- if (filesList?.length > 1) {
299
- onUploadError(__('Only one image can be used as a background image.'));
300
- return;
301
- }
302
- getSettings().mediaUpload({
303
- allowedTypes: [IMAGE_BACKGROUND_TYPE],
304
- filesList,
305
- onFileChange([image]) {
306
- onSelectMedia(image);
307
- },
308
- onError: onUploadError
309
- });
310
- };
311
- const hasValue = hasBackgroundImageValue(style);
312
- const closeAndFocus = () => {
313
- const [toggleButton] = focus.tabbable.find(replaceContainerRef.current);
314
- // Focus the toggle button and close the dropdown menu.
315
- // This ensures similar behaviour as to selecting an image, where the dropdown is
316
- // closed and focus is redirected to the dropdown toggle button.
317
- toggleButton?.focus();
318
- toggleButton?.click();
319
- };
320
- const onRemove = () => onChange(setImmutably(style, ['background'], {
321
- backgroundImage: 'none'
322
- }));
323
- const canRemove = !hasValue && hasBackgroundImageValue(inheritedValue);
324
- const imgLabel = title || getFilename(url) || __('Add background image');
325
- return /*#__PURE__*/_jsxs("div", {
326
- ref: replaceContainerRef,
327
- className: "block-editor-global-styles-background-panel__image-tools-panel-item",
328
- children: [isUploading && /*#__PURE__*/_jsx(LoadingSpinner, {}), /*#__PURE__*/_jsx(MediaReplaceFlow, {
329
- mediaId: id,
330
- mediaURL: url,
331
- allowedTypes: [IMAGE_BACKGROUND_TYPE],
332
- accept: "image/*",
333
- onSelect: onSelectMedia,
334
- popoverProps: {
335
- className: clsx({
336
- 'block-editor-global-styles-background-panel__media-replace-popover': displayInPanel
337
- })
338
- },
339
- name: /*#__PURE__*/_jsx(InspectorImagePreviewItem, {
340
- className: "block-editor-global-styles-background-panel__image-preview",
341
- imgUrl: url,
342
- filename: title,
343
- label: imgLabel
344
- }),
345
- variant: "secondary",
346
- onError: onUploadError,
347
- onReset: () => {
348
- closeAndFocus();
349
- onResetImage();
350
- },
351
- children: canRemove && /*#__PURE__*/_jsx(MenuItem, {
352
- onClick: () => {
353
- closeAndFocus();
354
- onRemove();
355
- onRemoveImage();
356
- },
357
- children: __('Remove')
358
- })
359
- }), /*#__PURE__*/_jsx(DropZone, {
360
- onFilesDrop: onFilesDrop,
361
- label: __('Drop to upload')
362
- })]
363
- });
364
- }
365
- function BackgroundSizeControls({
366
- onChange,
367
- style,
368
- inheritedValue,
369
- defaultValues
370
- }) {
371
- const sizeValue = style?.background?.backgroundSize || inheritedValue?.background?.backgroundSize;
372
- const repeatValue = style?.background?.backgroundRepeat || inheritedValue?.background?.backgroundRepeat;
373
- const imageValue = style?.background?.backgroundImage?.url || inheritedValue?.background?.backgroundImage?.url;
374
- const isUploadedImage = style?.background?.backgroundImage?.id;
375
- const positionValue = style?.background?.backgroundPosition || inheritedValue?.background?.backgroundPosition;
376
- const attachmentValue = style?.background?.backgroundAttachment || inheritedValue?.background?.backgroundAttachment;
377
-
378
- /*
379
- * Set default values for uploaded images.
380
- * The default values are passed by the consumer.
381
- * Block-level controls may have different defaults to root-level controls.
382
- * A falsy value is treated by default as `auto` (Tile).
383
- */
384
- let currentValueForToggle = !sizeValue && isUploadedImage ? defaultValues?.backgroundSize : sizeValue || 'auto';
385
- /*
386
- * The incoming value could be a value + unit, e.g. '20px'.
387
- * In this case set the value to 'tile'.
388
- */
389
- currentValueForToggle = !['cover', 'contain', 'auto'].includes(currentValueForToggle) ? 'auto' : currentValueForToggle;
390
- /*
391
- * If the current value is `cover` and the repeat value is `undefined`, then
392
- * the toggle should be unchecked as the default state. Otherwise, the toggle
393
- * should reflect the current repeat value.
394
- */
395
- const repeatCheckedValue = !(repeatValue === 'no-repeat' || currentValueForToggle === 'cover' && repeatValue === undefined);
396
- const updateBackgroundSize = next => {
397
- // When switching to 'contain' toggle the repeat off.
398
- let nextRepeat = repeatValue;
399
- let nextPosition = positionValue;
400
- if (next === 'contain') {
401
- nextRepeat = 'no-repeat';
402
- nextPosition = undefined;
403
- }
404
- if (next === 'cover') {
405
- nextRepeat = undefined;
406
- nextPosition = undefined;
407
- }
408
- if ((currentValueForToggle === 'cover' || currentValueForToggle === 'contain') && next === 'auto') {
409
- nextRepeat = undefined;
410
- /*
411
- * A background image uploaded and set in the editor (an image with a record id),
412
- * receives a default background position of '50% 0',
413
- * when the toggle switches to "Tile". This is to increase the chance that
414
- * the image's focus point is visible.
415
- * This is in-editor only to assist with the user experience.
416
- */
417
- if (!!style?.background?.backgroundImage?.id) {
418
- nextPosition = '50% 0';
419
- }
420
- }
421
-
422
- /*
423
- * Next will be null when the input is cleared,
424
- * in which case the value should be 'auto'.
425
- */
426
- if (!next && currentValueForToggle === 'auto') {
427
- next = 'auto';
428
- }
429
- onChange(setImmutably(style, ['background'], {
430
- ...style?.background,
431
- backgroundPosition: nextPosition,
432
- backgroundRepeat: nextRepeat,
433
- backgroundSize: next
434
- }));
435
- };
436
- const updateBackgroundPosition = next => {
437
- onChange(setImmutably(style, ['background', 'backgroundPosition'], coordsToBackgroundPosition(next)));
438
- };
439
- const toggleIsRepeated = () => onChange(setImmutably(style, ['background', 'backgroundRepeat'], repeatCheckedValue === true ? 'no-repeat' : 'repeat'));
440
- const toggleScrollWithPage = () => onChange(setImmutably(style, ['background', 'backgroundAttachment'], attachmentValue === 'fixed' ? 'scroll' : 'fixed'));
441
-
442
- // Set a default background position for non-site-wide, uploaded images with a size of 'contain'.
443
- const backgroundPositionValue = !positionValue && isUploadedImage && 'contain' === sizeValue ? defaultValues?.backgroundPosition : positionValue;
444
- return /*#__PURE__*/_jsxs(VStack, {
445
- spacing: 3,
446
- className: "single-column",
447
- children: [/*#__PURE__*/_jsx(FocalPointPicker, {
448
- __nextHasNoMarginBottom: true,
449
- label: __('Focal point'),
450
- url: imageValue,
451
- value: backgroundPositionToCoords(backgroundPositionValue),
452
- onChange: updateBackgroundPosition
453
- }), /*#__PURE__*/_jsx(ToggleControl, {
454
- __nextHasNoMarginBottom: true,
455
- label: __('Fixed background'),
456
- checked: attachmentValue === 'fixed',
457
- onChange: toggleScrollWithPage
458
- }), /*#__PURE__*/_jsxs(ToggleGroupControl, {
459
- __nextHasNoMarginBottom: true,
460
- size: "__unstable-large",
461
- label: __('Size'),
462
- value: currentValueForToggle,
463
- onChange: updateBackgroundSize,
464
- isBlock: true,
465
- help: backgroundSizeHelpText(sizeValue || defaultValues?.backgroundSize),
466
- children: [/*#__PURE__*/_jsx(ToggleGroupControlOption, {
467
- value: "cover",
468
- label: _x('Cover', 'Size option for background image control')
469
- }, "cover"), /*#__PURE__*/_jsx(ToggleGroupControlOption, {
470
- value: "contain",
471
- label: _x('Contain', 'Size option for background image control')
472
- }, "contain"), /*#__PURE__*/_jsx(ToggleGroupControlOption, {
473
- value: "auto",
474
- label: _x('Tile', 'Size option for background image control')
475
- }, "tile")]
476
- }), /*#__PURE__*/_jsxs(HStack, {
477
- justify: "flex-start",
478
- spacing: 2,
479
- as: "span",
480
- children: [/*#__PURE__*/_jsx(UnitControl, {
481
- "aria-label": __('Background image width'),
482
- onChange: updateBackgroundSize,
483
- value: sizeValue,
484
- size: "__unstable-large",
485
- __unstableInputWidth: "100px",
486
- min: 0,
487
- placeholder: __('Auto'),
488
- disabled: currentValueForToggle !== 'auto' || currentValueForToggle === undefined
489
- }), /*#__PURE__*/_jsx(ToggleControl, {
490
- __nextHasNoMarginBottom: true,
491
- label: __('Repeat'),
492
- checked: repeatCheckedValue,
493
- onChange: toggleIsRepeated,
494
- disabled: currentValueForToggle === 'cover'
495
- })]
496
- })]
497
- });
498
- }
499
54
  function BackgroundToolsPanel({
500
55
  resetAllFilter,
501
56
  onChange,
@@ -517,123 +72,44 @@ function BackgroundToolsPanel({
517
72
  children: children
518
73
  });
519
74
  }
520
- export default function BackgroundPanel({
75
+ export default function BackgroundImagePanel({
521
76
  as: Wrapper = BackgroundToolsPanel,
522
77
  value,
523
78
  onChange,
524
- inheritedValue = value,
79
+ inheritedValue,
525
80
  settings,
526
81
  panelId,
527
82
  defaultControls = DEFAULT_CONTROLS,
528
83
  defaultValues = {},
529
84
  headerLabel = __('Background image')
530
85
  }) {
531
- /*
532
- * Resolve any inherited "ref" pointers.
533
- * Should the block editor need resolved, inherited values
534
- * across all controls, this could be abstracted into a hook,
535
- * e.g., useResolveGlobalStyle
536
- */
537
- const {
538
- globalStyles,
539
- _links
540
- } = useSelect(select => {
541
- const {
542
- getSettings
543
- } = select(blockEditorStore);
544
- const _settings = getSettings();
545
- return {
546
- globalStyles: _settings[globalStylesDataKey],
547
- _links: _settings[globalStylesLinksDataKey]
548
- };
549
- }, []);
550
- const resolvedInheritedValue = useMemo(() => {
551
- const resolvedValues = {
552
- background: {}
553
- };
554
- if (!inheritedValue?.background) {
555
- return inheritedValue;
556
- }
557
- Object.entries(inheritedValue?.background).forEach(([key, backgroundValue]) => {
558
- resolvedValues.background[key] = getResolvedValue(backgroundValue, {
559
- styles: globalStyles,
560
- _links
561
- });
562
- });
563
- return resolvedValues;
564
- }, [globalStyles, _links, inheritedValue]);
86
+ const showBackgroundImageControl = useHasBackgroundPanel(settings);
87
+ const resetBackground = () => onChange(setImmutably(value, ['background'], {}));
565
88
  const resetAllFilter = useCallback(previousValue => {
566
89
  return {
567
90
  ...previousValue,
568
91
  background: {}
569
92
  };
570
93
  }, []);
571
- const resetBackground = () => onChange(setImmutably(value, ['background'], {}));
572
- const {
573
- title,
574
- url
575
- } = value?.background?.backgroundImage || {
576
- ...resolvedInheritedValue?.background?.backgroundImage
577
- };
578
- const hasImageValue = hasBackgroundImageValue(value) || hasBackgroundImageValue(resolvedInheritedValue);
579
- const imageValue = value?.background?.backgroundImage || inheritedValue?.background?.backgroundImage;
580
- const shouldShowBackgroundImageControls = hasImageValue && 'none' !== imageValue && (settings?.background?.backgroundSize || settings?.background?.backgroundPosition || settings?.background?.backgroundRepeat);
581
- const [isDropDownOpen, setIsDropDownOpen] = useState(false);
582
94
  return /*#__PURE__*/_jsx(Wrapper, {
583
95
  resetAllFilter: resetAllFilter,
584
96
  value: value,
585
97
  onChange: onChange,
586
98
  panelId: panelId,
587
99
  headerLabel: headerLabel,
588
- children: /*#__PURE__*/_jsx("div", {
589
- className: clsx('block-editor-global-styles-background-panel__inspector-media-replace-container', {
590
- 'is-open': isDropDownOpen
591
- }),
592
- children: /*#__PURE__*/_jsx(ToolsPanelItem, {
593
- hasValue: () => !!value?.background,
594
- label: __('Image'),
595
- onDeselect: resetBackground,
596
- isShownByDefault: defaultControls.backgroundImage,
597
- panelId: panelId,
598
- children: shouldShowBackgroundImageControls ? /*#__PURE__*/_jsx(BackgroundControlsPanel, {
599
- label: title,
600
- filename: title,
601
- url: url,
602
- onToggle: setIsDropDownOpen,
603
- hasImageValue: hasImageValue,
604
- children: /*#__PURE__*/_jsxs(VStack, {
605
- spacing: 3,
606
- className: "single-column",
607
- children: [/*#__PURE__*/_jsx(BackgroundImageControls, {
608
- onChange: onChange,
609
- style: value,
610
- inheritedValue: resolvedInheritedValue,
611
- displayInPanel: true,
612
- onResetImage: () => {
613
- setIsDropDownOpen(false);
614
- resetBackground();
615
- },
616
- onRemoveImage: () => setIsDropDownOpen(false),
617
- defaultValues: defaultValues
618
- }), /*#__PURE__*/_jsx(BackgroundSizeControls, {
619
- onChange: onChange,
620
- panelId: panelId,
621
- style: value,
622
- defaultValues: defaultValues,
623
- inheritedValue: resolvedInheritedValue
624
- })]
625
- })
626
- }) : /*#__PURE__*/_jsx(BackgroundImageControls, {
627
- onChange: onChange,
628
- style: value,
629
- inheritedValue: resolvedInheritedValue,
630
- defaultValues: defaultValues,
631
- onResetImage: () => {
632
- setIsDropDownOpen(false);
633
- resetBackground();
634
- },
635
- onRemoveImage: () => setIsDropDownOpen(false)
636
- })
100
+ children: showBackgroundImageControl && /*#__PURE__*/_jsx(ToolsPanelItem, {
101
+ hasValue: () => !!value?.background,
102
+ label: __('Image'),
103
+ onDeselect: resetBackground,
104
+ isShownByDefault: defaultControls.backgroundImage,
105
+ panelId: panelId,
106
+ children: /*#__PURE__*/_jsx(BackgroundImageControl, {
107
+ value: value,
108
+ onChange: onChange,
109
+ settings: settings,
110
+ inheritedValue: inheritedValue,
111
+ defaultControls: defaultControls,
112
+ defaultValues: defaultValues
637
113
  })
638
114
  })
639
115
  });