@wordpress/block-editor 15.15.0 → 15.16.1-next.v.202604091042.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 (197) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/autocomplete/index.cjs +1 -2
  3. package/build/components/autocomplete/index.cjs.map +3 -3
  4. package/build/components/block-inspector/index.cjs +2 -1
  5. package/build/components/block-inspector/index.cjs.map +2 -2
  6. package/build/components/block-list/block-crash-warning.cjs +4 -2
  7. package/build/components/block-list/block-crash-warning.cjs.map +2 -2
  8. package/build/components/block-list/block-html.cjs +6 -2
  9. package/build/components/block-list/block-html.cjs.map +2 -2
  10. package/build/components/block-mover/button.cjs +4 -3
  11. package/build/components/block-mover/button.cjs.map +2 -2
  12. package/build/components/block-mover/index.cjs +1 -8
  13. package/build/components/block-mover/index.cjs.map +2 -2
  14. package/build/components/block-visibility/modal.cjs +2 -2
  15. package/build/components/block-visibility/modal.cjs.map +1 -1
  16. package/build/components/block-visibility/viewport-visibility-info.cjs +6 -1
  17. package/build/components/block-visibility/viewport-visibility-info.cjs.map +2 -2
  18. package/build/components/global-styles/background-panel.cjs +142 -33
  19. package/build/components/global-styles/background-panel.cjs.map +2 -2
  20. package/build/components/global-styles/color-panel.cjs +18 -7
  21. package/build/components/global-styles/color-panel.cjs.map +2 -2
  22. package/build/components/global-styles/hooks.cjs +8 -4
  23. package/build/components/global-styles/hooks.cjs.map +2 -2
  24. package/build/components/iframe/get-compatibility-styles.cjs +1 -1
  25. package/build/components/iframe/get-compatibility-styles.cjs.map +2 -2
  26. package/build/components/inserter/media-tab/hooks.cjs +1 -1
  27. package/build/components/inserter/media-tab/hooks.cjs.map +2 -2
  28. package/build/components/inspector-controls-tabs/styles-tab.cjs +2 -1
  29. package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
  30. package/build/components/link-control/search-input.cjs +1 -1
  31. package/build/components/link-control/search-input.cjs.map +2 -2
  32. package/build/components/link-picker/link-preview.cjs +2 -1
  33. package/build/components/link-picker/link-preview.cjs.map +3 -3
  34. package/build/components/rich-text/index.cjs +1 -1
  35. package/build/components/rich-text/index.cjs.map +2 -2
  36. package/build/components/rich-text/input-event.cjs +3 -3
  37. package/build/components/rich-text/input-event.cjs.map +2 -2
  38. package/build/components/use-on-block-drop/index.cjs +1 -1
  39. package/build/components/use-on-block-drop/index.cjs.map +2 -2
  40. package/build/components/use-paste-styles/index.cjs +2 -2
  41. package/build/components/use-paste-styles/index.cjs.map +2 -2
  42. package/build/hooks/background.cjs +74 -21
  43. package/build/hooks/background.cjs.map +3 -3
  44. package/build/hooks/block-style-variation.cjs +5 -6
  45. package/build/hooks/block-style-variation.cjs.map +3 -3
  46. package/build/hooks/cross-origin-isolation.cjs +6 -6
  47. package/build/hooks/cross-origin-isolation.cjs.map +2 -2
  48. package/build/hooks/custom-css.cjs +5 -0
  49. package/build/hooks/custom-css.cjs.map +2 -2
  50. package/build/hooks/fit-text.cjs +46 -58
  51. package/build/hooks/fit-text.cjs.map +3 -3
  52. package/build/hooks/index.cjs +2 -2
  53. package/build/hooks/index.cjs.map +2 -2
  54. package/build/hooks/utils.cjs +5 -1
  55. package/build/hooks/utils.cjs.map +2 -2
  56. package/build/private-apis.cjs +1 -1
  57. package/build/private-apis.cjs.map +1 -1
  58. package/build/store/actions.cjs +8 -12
  59. package/build/store/actions.cjs.map +2 -2
  60. package/build/store/private-selectors.cjs +2 -2
  61. package/build/store/private-selectors.cjs.map +2 -2
  62. package/build/store/reducer.cjs +112 -146
  63. package/build/store/reducer.cjs.map +2 -2
  64. package/build/store/selectors.cjs +14 -15
  65. package/build/store/selectors.cjs.map +2 -2
  66. package/build/store/utils.cjs +1 -1
  67. package/build/store/utils.cjs.map +2 -2
  68. package/build/utils/pasting.cjs +1 -1
  69. package/build/utils/pasting.cjs.map +2 -2
  70. package/build-module/components/autocomplete/index.mjs +1 -2
  71. package/build-module/components/autocomplete/index.mjs.map +2 -2
  72. package/build-module/components/block-inspector/index.mjs +2 -1
  73. package/build-module/components/block-inspector/index.mjs.map +2 -2
  74. package/build-module/components/block-list/block-crash-warning.mjs +4 -2
  75. package/build-module/components/block-list/block-crash-warning.mjs.map +2 -2
  76. package/build-module/components/block-list/block-html.mjs +7 -3
  77. package/build-module/components/block-list/block-html.mjs.map +2 -2
  78. package/build-module/components/block-mover/button.mjs +4 -3
  79. package/build-module/components/block-mover/button.mjs.map +2 -2
  80. package/build-module/components/block-mover/index.mjs +1 -8
  81. package/build-module/components/block-mover/index.mjs.map +2 -2
  82. package/build-module/components/block-visibility/modal.mjs +2 -2
  83. package/build-module/components/block-visibility/modal.mjs.map +1 -1
  84. package/build-module/components/block-visibility/viewport-visibility-info.mjs +6 -1
  85. package/build-module/components/block-visibility/viewport-visibility-info.mjs.map +2 -2
  86. package/build-module/components/global-styles/background-panel.mjs +141 -34
  87. package/build-module/components/global-styles/background-panel.mjs.map +2 -2
  88. package/build-module/components/global-styles/color-panel.mjs +17 -7
  89. package/build-module/components/global-styles/color-panel.mjs.map +2 -2
  90. package/build-module/components/global-styles/hooks.mjs +8 -4
  91. package/build-module/components/global-styles/hooks.mjs.map +2 -2
  92. package/build-module/components/iframe/get-compatibility-styles.mjs +1 -1
  93. package/build-module/components/iframe/get-compatibility-styles.mjs.map +2 -2
  94. package/build-module/components/inserter/media-tab/hooks.mjs +1 -1
  95. package/build-module/components/inserter/media-tab/hooks.mjs.map +2 -2
  96. package/build-module/components/inspector-controls-tabs/styles-tab.mjs +2 -1
  97. package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
  98. package/build-module/components/link-control/search-input.mjs +1 -1
  99. package/build-module/components/link-control/search-input.mjs.map +2 -2
  100. package/build-module/components/link-picker/link-preview.mjs +2 -1
  101. package/build-module/components/link-picker/link-preview.mjs.map +2 -2
  102. package/build-module/components/rich-text/index.mjs +2 -2
  103. package/build-module/components/rich-text/index.mjs.map +2 -2
  104. package/build-module/components/rich-text/input-event.mjs +2 -2
  105. package/build-module/components/rich-text/input-event.mjs.map +2 -2
  106. package/build-module/components/use-on-block-drop/index.mjs +1 -1
  107. package/build-module/components/use-on-block-drop/index.mjs.map +2 -2
  108. package/build-module/components/use-paste-styles/index.mjs +2 -2
  109. package/build-module/components/use-paste-styles/index.mjs.map +2 -2
  110. package/build-module/hooks/background.mjs +76 -22
  111. package/build-module/hooks/background.mjs.map +2 -2
  112. package/build-module/hooks/block-style-variation.mjs +4 -5
  113. package/build-module/hooks/block-style-variation.mjs.map +2 -2
  114. package/build-module/hooks/cross-origin-isolation.mjs +6 -6
  115. package/build-module/hooks/cross-origin-isolation.mjs.map +2 -2
  116. package/build-module/hooks/custom-css.mjs +5 -0
  117. package/build-module/hooks/custom-css.mjs.map +2 -2
  118. package/build-module/hooks/fit-text.mjs +46 -58
  119. package/build-module/hooks/fit-text.mjs.map +2 -2
  120. package/build-module/hooks/index.mjs +2 -2
  121. package/build-module/hooks/index.mjs.map +2 -2
  122. package/build-module/hooks/utils.mjs +5 -1
  123. package/build-module/hooks/utils.mjs.map +2 -2
  124. package/build-module/private-apis.mjs +2 -2
  125. package/build-module/private-apis.mjs.map +1 -1
  126. package/build-module/store/actions.mjs +8 -12
  127. package/build-module/store/actions.mjs.map +2 -2
  128. package/build-module/store/private-selectors.mjs +2 -2
  129. package/build-module/store/private-selectors.mjs.map +2 -2
  130. package/build-module/store/reducer.mjs +112 -145
  131. package/build-module/store/reducer.mjs.map +2 -2
  132. package/build-module/store/selectors.mjs +14 -15
  133. package/build-module/store/selectors.mjs.map +2 -2
  134. package/build-module/store/utils.mjs +1 -1
  135. package/build-module/store/utils.mjs.map +2 -2
  136. package/build-module/utils/pasting.mjs +1 -1
  137. package/build-module/utils/pasting.mjs.map +2 -2
  138. package/build-style/content-rtl.css +2 -2
  139. package/build-style/content.css +2 -2
  140. package/build-style/style-rtl.css +35 -14
  141. package/build-style/style.css +35 -14
  142. package/package.json +38 -39
  143. package/src/autocompleters/style.scss +0 -8
  144. package/src/components/autocomplete/index.js +1 -2
  145. package/src/components/background-image-control/style.scss +0 -4
  146. package/src/components/block-draggable/test/helpers.native.js +1 -1
  147. package/src/components/block-inspector/index.js +1 -0
  148. package/src/components/block-list/block-crash-warning.js +3 -1
  149. package/src/components/block-list/block-crash-warning.native.js +3 -1
  150. package/src/components/block-list/block-html.js +13 -3
  151. package/src/components/block-mover/button.js +7 -4
  152. package/src/components/block-mover/index.js +1 -8
  153. package/src/components/block-visibility/viewport-visibility-info.js +8 -1
  154. package/src/components/fit-text-size-warning/style.scss +1 -5
  155. package/src/components/global-styles/background-panel.js +157 -11
  156. package/src/components/global-styles/color-panel.js +23 -7
  157. package/src/components/global-styles/hooks.js +12 -4
  158. package/src/components/global-styles/test/background-panel.js +44 -1
  159. package/src/components/iframe/get-compatibility-styles.js +1 -1
  160. package/src/components/inserter/media-tab/hooks.js +1 -1
  161. package/src/components/inspector-controls-tabs/styles-tab.js +1 -0
  162. package/src/components/link-control/README.md +2 -2
  163. package/src/components/link-control/search-input.js +1 -1
  164. package/src/components/link-picker/link-preview.js +2 -1
  165. package/src/components/rich-text/index.js +1 -1
  166. package/src/components/rich-text/index.native.js +1 -1
  167. package/src/components/rich-text/input-event.js +1 -1
  168. package/src/components/rich-text/input-event.native.js +1 -1
  169. package/src/components/rich-text/native/index.native.js +18 -17
  170. package/src/components/use-on-block-drop/index.js +1 -1
  171. package/src/components/use-paste-styles/index.js +2 -2
  172. package/src/hooks/background.js +122 -21
  173. package/src/hooks/background.scss +45 -0
  174. package/src/hooks/block-style-variation.js +3 -4
  175. package/src/hooks/cross-origin-isolation.js +6 -6
  176. package/src/hooks/custom-css.js +6 -0
  177. package/src/hooks/fit-text.js +73 -83
  178. package/src/hooks/index.js +1 -1
  179. package/src/hooks/test/cross-origin-isolation.js +7 -3
  180. package/src/hooks/utils.js +4 -0
  181. package/src/private-apis.js +2 -2
  182. package/src/store/actions.js +9 -16
  183. package/src/store/private-selectors.js +2 -2
  184. package/src/store/reducer.js +144 -193
  185. package/src/store/selectors.js +33 -23
  186. package/src/store/test/private-selectors.js +107 -71
  187. package/src/store/test/reducer.js +593 -152
  188. package/src/store/test/registry-selectors.js +1 -1
  189. package/src/store/test/selectors.js +345 -262
  190. package/src/store/utils.js +1 -1
  191. package/src/style.scss +1 -0
  192. package/src/utils/pasting.js +1 -1
  193. package/build/autocompleters/link.cjs +0 -81
  194. package/build/autocompleters/link.cjs.map +0 -7
  195. package/build-module/autocompleters/link.mjs +0 -50
  196. package/build-module/autocompleters/link.mjs.map +0 -7
  197. package/src/autocompleters/link.js +0 -63
@@ -7,17 +7,33 @@ import {
7
7
  } from '@wordpress/components';
8
8
  import { useCallback, Platform } from '@wordpress/element';
9
9
  import { __ } from '@wordpress/i18n';
10
+ import { getValueFromVariable } from '@wordpress/global-styles-engine';
11
+
10
12
  /**
11
13
  * Internal dependencies
12
14
  */
13
15
  import BackgroundImageControl from '../background-image-control';
16
+ import { ColorPanelDropdown } from './color-panel';
17
+ import { useGradientsPerOrigin } from './hooks';
14
18
  import { useToolsPanelDropdownMenuProps } from './utils';
15
19
  import { setImmutably } from '../../utils/object';
16
20
 
17
21
  const DEFAULT_CONTROLS = {
18
22
  backgroundImage: true,
23
+ gradient: true,
19
24
  };
20
25
 
26
+ /**
27
+ * Checks site settings to see if the requested feature's control may be used.
28
+ *
29
+ * @param {Object} settings Site settings.
30
+ * @param {string} feature Background feature to check.
31
+ * @return {boolean} Whether site settings has activated background panel.
32
+ */
33
+ export function useHasBackgroundControl( settings, feature ) {
34
+ return Platform.OS === 'web' && settings?.background?.[ feature ];
35
+ }
36
+
21
37
  /**
22
38
  * Checks site settings to see if the background panel may be used.
23
39
  * `settings.background.backgroundSize` exists also,
@@ -27,7 +43,8 @@ const DEFAULT_CONTROLS = {
27
43
  * @return {boolean} Whether site settings has activated background panel.
28
44
  */
29
45
  export function useHasBackgroundPanel( settings ) {
30
- return Platform.OS === 'web' && settings?.background?.backgroundImage;
46
+ const { backgroundImage, gradient } = settings?.background || {};
47
+ return Platform.OS === 'web' && ( backgroundImage || gradient );
31
48
  }
32
49
 
33
50
  /**
@@ -61,6 +78,20 @@ export function hasBackgroundImageValue( style ) {
61
78
  );
62
79
  }
63
80
 
81
+ /**
82
+ * Checks if there is a current value in the background gradient block support
83
+ * attributes.
84
+ *
85
+ * @param {Object} style Style attribute.
86
+ * @return {boolean} Whether the block has a background gradient value set.
87
+ */
88
+ export function hasBackgroundGradientValue( style ) {
89
+ return (
90
+ 'string' === typeof style?.background?.gradient &&
91
+ style?.background?.gradient !== ''
92
+ );
93
+ }
94
+
64
95
  function BackgroundToolsPanel( {
65
96
  resetAllFilter,
66
97
  onChange,
@@ -80,9 +111,15 @@ function BackgroundToolsPanel( {
80
111
  label={ headerLabel }
81
112
  resetAll={ resetAll }
82
113
  panelId={ panelId }
114
+ hasInnerWrapper
115
+ className="background-block-support-panel"
116
+ __experimentalFirstVisibleItemClass="first"
117
+ __experimentalLastVisibleItemClass="last"
83
118
  dropdownMenuProps={ dropdownMenuProps }
84
119
  >
85
- { children }
120
+ <div className="background-block-support-panel__inner-wrapper">
121
+ { children }
122
+ </div>
86
123
  </ToolsPanel>
87
124
  );
88
125
  }
@@ -98,15 +135,97 @@ export default function BackgroundImagePanel( {
98
135
  defaultValues = {},
99
136
  headerLabel = __( 'Background' ),
100
137
  } ) {
101
- const showBackgroundImageControl = useHasBackgroundPanel( settings );
138
+ const gradients = useGradientsPerOrigin( settings );
139
+ const areCustomGradientsEnabled = settings?.color?.customGradient;
140
+ const hasGradientColors = gradients.length > 0 || areCustomGradientsEnabled;
141
+
142
+ const hasBackgroundGradientControl = useHasBackgroundControl(
143
+ settings,
144
+ 'gradient'
145
+ );
146
+ const showBackgroundGradientControl =
147
+ hasGradientColors && hasBackgroundGradientControl;
148
+ const showBackgroundImageControl = useHasBackgroundControl(
149
+ settings,
150
+ 'backgroundImage'
151
+ );
152
+
153
+ const resetAllFilter = useCallback(
154
+ ( previousValue ) => {
155
+ return {
156
+ ...previousValue,
157
+ background: {},
158
+ color: hasBackgroundGradientControl
159
+ ? {
160
+ ...previousValue?.color,
161
+ gradient: undefined,
162
+ }
163
+ : previousValue?.color,
164
+ };
165
+ },
166
+ [ hasBackgroundGradientControl ]
167
+ );
168
+
169
+ if ( ! showBackgroundGradientControl && ! showBackgroundImageControl ) {
170
+ return null;
171
+ }
172
+
173
+ const decodeValue = ( rawValue ) =>
174
+ getValueFromVariable( { settings }, '', rawValue );
175
+ const encodeGradientValue = ( gradientValue ) => {
176
+ const allGradients = gradients.flatMap(
177
+ ( { gradients: originGradients } ) => originGradients
178
+ );
179
+ const gradientObject = allGradients.find(
180
+ ( { gradient } ) => gradient === gradientValue
181
+ );
182
+ return gradientObject
183
+ ? 'var:preset|gradient|' + gradientObject.slug
184
+ : gradientValue;
185
+ };
186
+
102
187
  const resetBackground = () =>
103
- onChange( setImmutably( value, [ 'background' ], {} ) );
104
- const resetAllFilter = useCallback( ( previousValue ) => {
105
- return {
106
- ...previousValue,
107
- background: {},
108
- };
109
- }, [] );
188
+ onChange(
189
+ setImmutably(
190
+ value,
191
+ [ 'background', 'backgroundImage' ],
192
+ undefined
193
+ )
194
+ );
195
+
196
+ const resetGradient = () => {
197
+ let newValue = setImmutably(
198
+ value,
199
+ [ 'background', 'gradient' ],
200
+ undefined
201
+ );
202
+ newValue = setImmutably( newValue, [ 'color', 'gradient' ], undefined );
203
+ onChange( newValue );
204
+ };
205
+
206
+ // Get current gradient value, decoding preset slug references.
207
+ // Fall back to color.gradient for legacy blocks that haven't migrated
208
+ // to background.gradient yet (mirrors block inspector fallback in
209
+ // packages/block-editor/src/hooks/background.js).
210
+ const currentGradient = decodeValue(
211
+ value?.background?.gradient ?? value?.color?.gradient
212
+ );
213
+ const inheritedGradient = decodeValue(
214
+ inheritedValue?.background?.gradient ?? inheritedValue?.color?.gradient
215
+ );
216
+
217
+ // Set gradient value, encoding preset matches as slug references.
218
+ // Also clear color.gradient to migrate from the legacy location,
219
+ // matching the block inspector behavior in hooks/background.js.
220
+ const setGradient = ( newGradient ) => {
221
+ let newValue = setImmutably(
222
+ value,
223
+ [ 'background', 'gradient' ],
224
+ encodeGradientValue( newGradient )
225
+ );
226
+ newValue = setImmutably( newValue, [ 'color', 'gradient' ], undefined );
227
+ onChange( newValue );
228
+ };
110
229
 
111
230
  return (
112
231
  <Wrapper
@@ -118,7 +237,8 @@ export default function BackgroundImagePanel( {
118
237
  >
119
238
  { showBackgroundImageControl && (
120
239
  <ToolsPanelItem
121
- hasValue={ () => !! value?.background }
240
+ className="block-editor-background-panel__item"
241
+ hasValue={ () => hasBackgroundImageValue( value ) }
122
242
  label={ __( 'Image' ) }
123
243
  onDeselect={ resetBackground }
124
244
  isShownByDefault={ defaultControls.backgroundImage }
@@ -134,6 +254,32 @@ export default function BackgroundImagePanel( {
134
254
  />
135
255
  </ToolsPanelItem>
136
256
  ) }
257
+ { showBackgroundGradientControl && (
258
+ <ColorPanelDropdown
259
+ className="block-editor-background-panel__item"
260
+ label={ __( 'Gradient' ) }
261
+ hasValue={ () => hasBackgroundGradientValue( value ) }
262
+ resetValue={ resetGradient }
263
+ isShownByDefault={ defaultControls.gradient }
264
+ indicators={ [ currentGradient ] }
265
+ tabs={ [
266
+ {
267
+ key: 'gradient',
268
+ label: __( 'Gradient' ),
269
+ inheritedValue:
270
+ currentGradient ?? inheritedGradient,
271
+ setValue: setGradient,
272
+ userValue: currentGradient,
273
+ isGradient: true,
274
+ },
275
+ ] }
276
+ colorGradientControlSettings={ {
277
+ gradients,
278
+ disableCustomGradients: ! areCustomGradientsEnabled,
279
+ } }
280
+ panelId={ panelId }
281
+ />
282
+ ) }
137
283
  </Wrapper>
138
284
  );
139
285
  }
@@ -201,7 +201,7 @@ function ColorPanelTab( {
201
201
  );
202
202
  }
203
203
 
204
- function ColorPanelDropdown( {
204
+ export function ColorPanelDropdown( {
205
205
  label,
206
206
  hasValue,
207
207
  resetValue,
@@ -210,13 +210,14 @@ function ColorPanelDropdown( {
210
210
  tabs,
211
211
  colorGradientControlSettings,
212
212
  panelId,
213
+ className = 'block-editor-tools-panel-color-gradient-settings__item',
213
214
  } ) {
214
215
  const currentTab = tabs.find( ( tab ) => tab.userValue !== undefined );
215
216
  const { key: firstTabKey, ...firstTab } = tabs[ 0 ] ?? {};
216
217
  const colorGradientDropdownButtonRef = useRef( undefined );
217
218
  return (
218
219
  <ToolsPanelItem
219
- className="block-editor-tools-panel-color-gradient-settings__item"
220
+ className={ className }
220
221
  hasValue={ hasValue }
221
222
  label={ label }
222
223
  onDeselect={ resetValue }
@@ -336,6 +337,12 @@ export default function ColorPanel( {
336
337
  const areCustomGradientsEnabled = settings?.color?.customGradient;
337
338
  const hasSolidColors = colors.length > 0 || areCustomSolidsEnabled;
338
339
  const hasGradientColors = gradients.length > 0 || areCustomGradientsEnabled;
340
+ // When a block opts into background.gradient support, the gradient
341
+ // picker moves to the Background panel. Hide it here to avoid
342
+ // showing duplicate gradient controls.
343
+ const hasBackgroundGradientSupport = !! settings?.background?.gradient;
344
+ const showGradientColors =
345
+ hasGradientColors && ! hasBackgroundGradientSupport;
339
346
  const decodeValue = ( rawValue ) =>
340
347
  getValueFromVariable( { settings }, '', rawValue );
341
348
  const encodeColorValue = ( colorValue ) => {
@@ -367,14 +374,18 @@ export default function ColorPanel( {
367
374
  const userBackgroundColor = decodeValue( value?.color?.background );
368
375
  const gradient = decodeValue( inheritedValue?.color?.gradient );
369
376
  const userGradient = decodeValue( value?.color?.gradient );
370
- const hasBackground = () => !! userBackgroundColor || !! userGradient;
377
+ const hasBackground = () =>
378
+ !! userBackgroundColor ||
379
+ ( ! hasBackgroundGradientSupport && !! userGradient );
371
380
  const setBackgroundColor = ( newColor ) => {
372
381
  const newValue = setImmutably(
373
382
  value,
374
383
  [ 'color', 'background' ],
375
384
  encodeColorValue( newColor )
376
385
  );
377
- newValue.color.gradient = undefined;
386
+ if ( ! hasBackgroundGradientSupport ) {
387
+ newValue.color.gradient = undefined;
388
+ }
378
389
  onChange( newValue );
379
390
  };
380
391
  const setGradient = ( newGradient ) => {
@@ -392,7 +403,9 @@ export default function ColorPanel( {
392
403
  [ 'color', 'background' ],
393
404
  undefined
394
405
  );
395
- newValue.color.gradient = undefined;
406
+ if ( ! hasBackgroundGradientSupport ) {
407
+ newValue.color.gradient = undefined;
408
+ }
396
409
  onChange( newValue );
397
410
  };
398
411
 
@@ -566,7 +579,10 @@ export default function ColorPanel( {
566
579
  hasValue: hasBackground,
567
580
  resetValue: resetBackground,
568
581
  isShownByDefault: defaultControls.background,
569
- indicators: [ gradient ?? backgroundColor ],
582
+ indicators: [
583
+ ( showGradientColors ? gradient : undefined ) ??
584
+ backgroundColor,
585
+ ],
570
586
  tabs: [
571
587
  hasSolidColors && {
572
588
  key: 'background',
@@ -575,7 +591,7 @@ export default function ColorPanel( {
575
591
  setValue: setBackgroundColor,
576
592
  userValue: userBackgroundColor,
577
593
  },
578
- hasGradientColors && {
594
+ showGradientColors && {
579
595
  key: 'gradient',
580
596
  label: __( 'Gradient' ),
581
597
  inheritedValue: gradient,
@@ -81,7 +81,11 @@ export function useSettingsForBlockElement(
81
81
  };
82
82
 
83
83
  // Some blocks can enable background colors but disable gradients.
84
- if ( ! supportedStyles.includes( 'background' ) ) {
84
+ // Preserve gradient settings when background.gradient is supported.
85
+ if (
86
+ ! supportedStyles.includes( 'background' ) &&
87
+ ! supportedStyles.includes( 'backgroundGradient' )
88
+ ) {
85
89
  updatedSettings.color.gradients = [];
86
90
  updatedSettings.color.customGradient = false;
87
91
  }
@@ -184,11 +188,15 @@ export function useSettingsForBlockElement(
184
188
  }
185
189
  } );
186
190
 
187
- [ 'backgroundImage', 'backgroundSize' ].forEach( ( key ) => {
188
- if ( ! supportedStyles.includes( key ) ) {
191
+ [
192
+ [ 'backgroundImage', 'backgroundImage' ],
193
+ [ 'backgroundSize', 'backgroundSize' ],
194
+ [ 'backgroundGradient', 'gradient' ],
195
+ ].forEach( ( [ styleKey, settingKey ] ) => {
196
+ if ( ! supportedStyles.includes( styleKey ) ) {
189
197
  updatedSettings.background = {
190
198
  ...updatedSettings.background,
191
- [ key ]: false,
199
+ [ settingKey ]: false,
192
200
  };
193
201
  }
194
202
  } );
@@ -2,7 +2,10 @@
2
2
  * Internal dependencies
3
3
  */
4
4
 
5
- import { hasBackgroundImageValue } from '../background-panel';
5
+ import {
6
+ hasBackgroundImageValue,
7
+ hasBackgroundGradientValue,
8
+ } from '../background-panel';
6
9
 
7
10
  describe( 'hasBackgroundImageValue', () => {
8
11
  it( 'should return `true` when id and url exist', () => {
@@ -37,3 +40,43 @@ describe( 'hasBackgroundImageValue', () => {
37
40
  ).toBe( false );
38
41
  } );
39
42
  } );
43
+
44
+ describe( 'hasBackgroundGradientValue', () => {
45
+ it( 'should return `true` when a gradient string is set', () => {
46
+ expect(
47
+ hasBackgroundGradientValue( {
48
+ background: {
49
+ gradient: 'linear-gradient(135deg, red 0%, blue 100%)',
50
+ },
51
+ } )
52
+ ).toBe( true );
53
+ } );
54
+
55
+ it( 'should return `true` for a preset slug reference', () => {
56
+ expect(
57
+ hasBackgroundGradientValue( {
58
+ background: { gradient: 'var:preset|gradient|vivid-cyan-blue' },
59
+ } )
60
+ ).toBe( true );
61
+ } );
62
+
63
+ it( 'should return `false` when gradient is undefined', () => {
64
+ expect( hasBackgroundGradientValue( { background: {} } ) ).toBe(
65
+ false
66
+ );
67
+ } );
68
+
69
+ it( 'should return `false` when gradient is an empty string', () => {
70
+ expect(
71
+ hasBackgroundGradientValue( { background: { gradient: '' } } )
72
+ ).toBe( false );
73
+ } );
74
+
75
+ it( 'should return `false` when background is undefined', () => {
76
+ expect( hasBackgroundGradientValue( {} ) ).toBe( false );
77
+ } );
78
+
79
+ it( 'should return `false` when style is undefined', () => {
80
+ expect( hasBackgroundGradientValue( undefined ) ).toBe( false );
81
+ } );
82
+ } );
@@ -21,7 +21,7 @@ export function getCompatibilityStyles() {
21
21
  // May fail for external styles.
22
22
  // eslint-disable-next-line no-unused-expressions
23
23
  styleSheet.cssRules;
24
- } catch ( e ) {
24
+ } catch {
25
25
  return accumulator;
26
26
  }
27
27
 
@@ -100,7 +100,7 @@ export function useMediaCategories( rootClientId ) {
100
100
  results = await category.fetch( {
101
101
  per_page: 1,
102
102
  } );
103
- } catch ( e ) {
103
+ } catch {
104
104
  // If the request fails, we shallow the error and just don't show
105
105
  // the category, in order to not break the media tab.
106
106
  }
@@ -88,6 +88,7 @@ const StylesTab = ( {
88
88
  <InspectorControls.Slot
89
89
  group="background"
90
90
  label={ __( 'Background image' ) }
91
+ className="background-block-support-panel__inner-wrapper"
91
92
  />
92
93
  <InspectorControls.Slot group="filter" />
93
94
  <InspectorControls.Slot
@@ -275,14 +275,14 @@ If passed, children are rendered after the input.
275
275
 
276
276
  ```jsx
277
277
  <LinkControlSearchInput>
278
- <HStack justify="right">
278
+ <Stack justify="flex-end">
279
279
  <Button
280
280
  type="submit"
281
281
  label={ __( 'Submit' ) }
282
282
  icon={ keyboardReturn }
283
283
  className="block-editor-link-control__search-submit"
284
284
  />
285
- </HStack>
285
+ </Stack>
286
286
  </LinkControlSearchInput>
287
287
  ```
288
288
 
@@ -99,7 +99,7 @@ const LinkControlSearchInput = forwardRef(
99
99
  if ( suggestion?.url ) {
100
100
  onSelect( suggestion );
101
101
  }
102
- } catch ( e ) {}
102
+ } catch {}
103
103
  return;
104
104
  }
105
105
 
@@ -9,6 +9,7 @@ import {
9
9
  privateApis as componentsPrivateApis,
10
10
  } from '@wordpress/components';
11
11
  import { Icon, chevronDown } from '@wordpress/icons';
12
+ import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
12
13
 
13
14
  /**
14
15
  * Internal dependencies
@@ -50,7 +51,7 @@ export function LinkPreview( { title, url, image, badges } ) {
50
51
  numberOfLines={ 1 }
51
52
  className="link-preview-button__title"
52
53
  >
53
- { title }
54
+ { stripHTML( title ) }
54
55
  </Truncate>
55
56
  { url && (
56
57
  <Truncate
@@ -555,4 +555,4 @@ PublicForwardedRichTextContainer.isEmpty = ( value ) => {
555
555
  export default PublicForwardedRichTextContainer;
556
556
  export { RichTextShortcut } from './shortcut';
557
557
  export { RichTextToolbarButton } from './toolbar-button';
558
- export { __unstableRichTextInputEvent } from './input-event';
558
+ export { RichTextInputEvent as __unstableRichTextInputEvent } from './input-event';
@@ -698,4 +698,4 @@ PrivateRichText.Raw = forwardRef( ( props, ref ) => (
698
698
  export default PrivateRichText;
699
699
  export { RichTextShortcut } from './shortcut';
700
700
  export { RichTextToolbarButton } from './toolbar-button';
701
- export { __unstableRichTextInputEvent } from './input-event';
701
+ export { RichTextInputEvent as __unstableRichTextInputEvent } from './input-event';
@@ -8,7 +8,7 @@ import { useEffect, useContext, useRef } from '@wordpress/element';
8
8
  */
9
9
  import { inputEventContext } from './';
10
10
 
11
- export function __unstableRichTextInputEvent( { inputType, onInput } ) {
11
+ export function RichTextInputEvent( { inputType, onInput } ) {
12
12
  const callbacks = useContext( inputEventContext );
13
13
  const onInputRef = useRef();
14
14
  onInputRef.current = onInput;
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { Component } from '@wordpress/element';
5
5
 
6
- export class __unstableRichTextInputEvent extends Component {
6
+ export class RichTextInputEvent extends Component {
7
7
  render() {
8
8
  return null;
9
9
  }
@@ -15,7 +15,6 @@ import {
15
15
  showUserSuggestions,
16
16
  showXpostSuggestions,
17
17
  } from '@wordpress/react-native-bridge';
18
- import { BlockFormatControls } from '@wordpress/block-editor';
19
18
  import { getPxFromCssUnit } from '@wordpress/components';
20
19
  import { Component } from '@wordpress/element';
21
20
  import {
@@ -42,6 +41,7 @@ import {
42
41
  isCollapsed,
43
42
  remove,
44
43
  } from '@wordpress/rich-text';
44
+ import { BlockFormatControls } from '@wordpress/block-editor';
45
45
 
46
46
  /**
47
47
  * Internal dependencies
@@ -1342,22 +1342,23 @@ RichText.defaultProps = {
1342
1342
  tagName: 'div',
1343
1343
  };
1344
1344
 
1345
- const withFormatTypes = ( WrappedComponent ) => ( props ) => {
1346
- const {
1347
- clientId,
1348
- identifier,
1349
- withoutInteractiveFormatting,
1350
- allowedFormats,
1351
- } = props;
1352
- const { formatTypes } = useFormatTypes( {
1353
- clientId,
1354
- identifier,
1355
- withoutInteractiveFormatting,
1356
- allowedFormats,
1357
- } );
1358
-
1359
- return <WrappedComponent { ...props } formatTypes={ formatTypes } />;
1360
- };
1345
+ const withFormatTypes = ( WrappedComponent ) =>
1346
+ function WithFormatTypes( props ) {
1347
+ const {
1348
+ clientId,
1349
+ identifier,
1350
+ withoutInteractiveFormatting,
1351
+ allowedFormats,
1352
+ } = props;
1353
+ const { formatTypes } = useFormatTypes( {
1354
+ clientId,
1355
+ identifier,
1356
+ withoutInteractiveFormatting,
1357
+ allowedFormats,
1358
+ } );
1359
+
1360
+ return <WrappedComponent { ...props } formatTypes={ formatTypes } />;
1361
+ };
1361
1362
 
1362
1363
  export default compose( [
1363
1364
  withSelect( ( select, { clientId } ) => {
@@ -46,7 +46,7 @@ export function parseDropEvent( event ) {
46
46
  result,
47
47
  JSON.parse( event.dataTransfer.getData( 'wp-blocks' ) )
48
48
  );
49
- } catch ( err ) {
49
+ } catch {
50
50
  return result;
51
51
  }
52
52
 
@@ -44,7 +44,7 @@ function hasSerializedBlocks( text ) {
44
44
  return false;
45
45
  }
46
46
  return true;
47
- } catch ( err ) {
47
+ } catch {
48
48
  // Parsing error, the text is not serialized blocks.
49
49
  // (Even though that it technically won't happen)
50
50
  return false;
@@ -153,7 +153,7 @@ export default function usePasteStyles() {
153
153
  }
154
154
 
155
155
  html = await window.navigator.clipboard.readText();
156
- } catch ( error ) {
156
+ } catch {
157
157
  // Possibly the permission is denied.
158
158
  createErrorNotice(
159
159
  __(