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