@wordpress/block-editor 8.0.5 → 8.0.9

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 (75) hide show
  1. package/build/components/block-tools/block-selection-button.js +7 -1
  2. package/build/components/block-tools/block-selection-button.js.map +1 -1
  3. package/build/components/colors/with-colors.js +9 -4
  4. package/build/components/colors/with-colors.js.map +1 -1
  5. package/build/components/colors-gradients/control.js +6 -2
  6. package/build/components/colors-gradients/control.js.map +1 -1
  7. package/build/components/colors-gradients/panel-color-gradient-settings.js +11 -70
  8. package/build/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  9. package/build/components/colors-gradients/use-common-single-multiple-selects.js +21 -0
  10. package/build/components/colors-gradients/use-common-single-multiple-selects.js.map +1 -0
  11. package/build/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +98 -0
  12. package/build/components/colors-gradients/use-multiple-origin-colors-and-gradients.js.map +1 -0
  13. package/build/components/gradients/use-gradient.js +7 -6
  14. package/build/components/gradients/use-gradient.js.map +1 -1
  15. package/build/components/use-setting/index.js +1 -1
  16. package/build/components/use-setting/index.js.map +1 -1
  17. package/build/hooks/border-color.js +12 -12
  18. package/build/hooks/border-color.js.map +1 -1
  19. package/build/hooks/color-panel.js +2 -1
  20. package/build/hooks/color-panel.js.map +1 -1
  21. package/build/hooks/color.js +45 -23
  22. package/build/hooks/color.js.map +1 -1
  23. package/build/hooks/typography.js +3 -0
  24. package/build/hooks/typography.js.map +1 -1
  25. package/build/hooks/use-color-props.js +19 -6
  26. package/build/hooks/use-color-props.js.map +1 -1
  27. package/build/store/selectors.js +37 -43
  28. package/build/store/selectors.js.map +1 -1
  29. package/build-module/components/block-tools/block-selection-button.js +7 -1
  30. package/build-module/components/block-tools/block-selection-button.js.map +1 -1
  31. package/build-module/components/colors/with-colors.js +9 -4
  32. package/build-module/components/colors/with-colors.js.map +1 -1
  33. package/build-module/components/colors-gradients/control.js +6 -2
  34. package/build-module/components/colors-gradients/control.js.map +1 -1
  35. package/build-module/components/colors-gradients/panel-color-gradient-settings.js +10 -72
  36. package/build-module/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  37. package/build-module/components/colors-gradients/use-common-single-multiple-selects.js +11 -0
  38. package/build-module/components/colors-gradients/use-common-single-multiple-selects.js.map +1 -0
  39. package/build-module/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +85 -0
  40. package/build-module/components/colors-gradients/use-multiple-origin-colors-and-gradients.js.map +1 -0
  41. package/build-module/components/gradients/use-gradient.js +7 -6
  42. package/build-module/components/gradients/use-gradient.js.map +1 -1
  43. package/build-module/components/use-setting/index.js +1 -1
  44. package/build-module/components/use-setting/index.js.map +1 -1
  45. package/build-module/hooks/border-color.js +11 -12
  46. package/build-module/hooks/border-color.js.map +1 -1
  47. package/build-module/hooks/color-panel.js +2 -1
  48. package/build-module/hooks/color-panel.js.map +1 -1
  49. package/build-module/hooks/color.js +46 -24
  50. package/build-module/hooks/color.js.map +1 -1
  51. package/build-module/hooks/typography.js +1 -2
  52. package/build-module/hooks/typography.js.map +1 -1
  53. package/build-module/hooks/use-color-props.js +16 -4
  54. package/build-module/hooks/use-color-props.js.map +1 -1
  55. package/build-module/store/selectors.js +37 -43
  56. package/build-module/store/selectors.js.map +1 -1
  57. package/build-style/style-rtl.css +4 -1
  58. package/build-style/style.css +4 -1
  59. package/package.json +3 -3
  60. package/src/components/block-tools/block-selection-button.js +5 -1
  61. package/src/components/colors/with-colors.js +16 -5
  62. package/src/components/colors-gradients/control.js +6 -0
  63. package/src/components/colors-gradients/panel-color-gradient-settings.js +8 -92
  64. package/src/components/colors-gradients/use-common-single-multiple-selects.js +11 -0
  65. package/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +107 -0
  66. package/src/components/gradients/use-gradient.js +18 -7
  67. package/src/components/link-control/style.scss +6 -2
  68. package/src/components/use-setting/index.js +1 -1
  69. package/src/hooks/border-color.js +15 -9
  70. package/src/hooks/color-panel.js +1 -0
  71. package/src/hooks/color.js +71 -31
  72. package/src/hooks/test/color.js +109 -0
  73. package/src/hooks/typography.js +1 -1
  74. package/src/hooks/use-color-props.js +30 -4
  75. package/src/store/selectors.js +14 -26
@@ -10,7 +10,7 @@ import { isObject, setWith, clone } from 'lodash';
10
10
  import { addFilter } from '@wordpress/hooks';
11
11
  import { getBlockSupport } from '@wordpress/blocks';
12
12
  import { __ } from '@wordpress/i18n';
13
- import { useRef, useEffect, Platform } from '@wordpress/element';
13
+ import { useRef, useEffect, useMemo, Platform } from '@wordpress/element';
14
14
  import { createHigherOrderComponent } from '@wordpress/compose';
15
15
 
16
16
  /**
@@ -31,7 +31,8 @@ import ColorPanel from './color-panel';
31
31
  import useSetting from '../components/use-setting';
32
32
 
33
33
  export const COLOR_SUPPORT_KEY = 'color';
34
- const EMPTY_ARRAY = [];
34
+
35
+ const EMPTY_OBJECT = {};
35
36
 
36
37
  const hasColorSupport = ( blockType ) => {
37
38
  const colorSupport = getBlockSupport( blockType, COLOR_SUPPORT_KEY );
@@ -217,13 +218,43 @@ function immutableSet( object, path, value ) {
217
218
  */
218
219
  export function ColorEdit( props ) {
219
220
  const { name: blockName, attributes } = props;
220
- const solids = useSetting( 'color.palette' ) || EMPTY_ARRAY;
221
- const gradients = useSetting( 'color.gradients' ) || EMPTY_ARRAY;
221
+ // Some color settings have a special handling for deprecated flags in `useSetting`,
222
+ // so we can't unwrap them by doing const { ... } = useSetting('color')
223
+ // until https://github.com/WordPress/gutenberg/issues/37094 is fixed.
224
+ const userPalette = useSetting( 'color.palette.custom' );
225
+ const themePalette = useSetting( 'color.palette.theme' );
226
+ const defaultPalette = useSetting( 'color.palette.default' );
227
+ const allSolids = useMemo(
228
+ () => [
229
+ ...( userPalette || [] ),
230
+ ...( themePalette || [] ),
231
+ ...( defaultPalette || [] ),
232
+ ],
233
+ [ userPalette, themePalette, defaultPalette ]
234
+ );
235
+ const gradientsPerOrigin = useSetting( 'color.gradients' ) || EMPTY_OBJECT;
222
236
  const areCustomSolidsEnabled = useSetting( 'color.custom' );
223
237
  const areCustomGradientsEnabled = useSetting( 'color.customGradient' );
238
+ const isBackgroundEnabled = useSetting( 'color.background' );
224
239
  const isLinkEnabled = useSetting( 'color.link' );
225
240
  const isTextEnabled = useSetting( 'color.text' );
226
- const isBackgroundEnabled = useSetting( 'color.background' );
241
+
242
+ const solidsEnabled =
243
+ areCustomSolidsEnabled || ! themePalette || themePalette?.length > 0;
244
+
245
+ const gradientsEnabled =
246
+ areCustomGradientsEnabled ||
247
+ ! gradientsPerOrigin?.theme ||
248
+ gradientsPerOrigin?.theme?.length > 0;
249
+
250
+ const allGradients = useMemo(
251
+ () => [
252
+ ...( gradientsPerOrigin?.custom || [] ),
253
+ ...( gradientsPerOrigin?.theme || [] ),
254
+ ...( gradientsPerOrigin?.default || [] ),
255
+ ],
256
+ [ gradientsPerOrigin ]
257
+ );
227
258
 
228
259
  // Shouldn't be needed but right now the ColorGradientsPanel
229
260
  // can trigger both onChangeColor and onChangeBackground
@@ -239,20 +270,15 @@ export function ColorEdit( props ) {
239
270
  }
240
271
 
241
272
  const hasLinkColor =
242
- hasLinkColorSupport( blockName ) &&
243
- isLinkEnabled &&
244
- ( solids.length > 0 || areCustomSolidsEnabled );
273
+ hasLinkColorSupport( blockName ) && isLinkEnabled && solidsEnabled;
245
274
  const hasTextColor =
246
- hasTextColorSupport( blockName ) &&
247
- isTextEnabled &&
248
- ( solids.length > 0 || areCustomSolidsEnabled );
275
+ hasTextColorSupport( blockName ) && isTextEnabled && solidsEnabled;
249
276
  const hasBackgroundColor =
250
277
  hasBackgroundColorSupport( blockName ) &&
251
278
  isBackgroundEnabled &&
252
- ( solids.length > 0 || areCustomSolidsEnabled );
279
+ solidsEnabled;
253
280
  const hasGradientColor =
254
- hasGradientSupport( blockName ) &&
255
- ( gradients.length > 0 || areCustomGradientsEnabled );
281
+ hasGradientSupport( blockName ) && gradientsEnabled;
256
282
 
257
283
  if (
258
284
  ! hasLinkColor &&
@@ -266,13 +292,13 @@ export function ColorEdit( props ) {
266
292
  const { style, textColor, backgroundColor, gradient } = attributes;
267
293
  let gradientValue;
268
294
  if ( hasGradientColor && gradient ) {
269
- gradientValue = getGradientValueBySlug( gradients, gradient );
295
+ gradientValue = getGradientValueBySlug( allGradients, gradient );
270
296
  } else if ( hasGradientColor ) {
271
297
  gradientValue = style?.color?.gradient;
272
298
  }
273
299
 
274
300
  const onChangeColor = ( name ) => ( value ) => {
275
- const colorObject = getColorObjectByColorValue( solids, value );
301
+ const colorObject = getColorObjectByColorValue( allSolids, value );
276
302
  const attributeName = name + 'Color';
277
303
  const newStyle = {
278
304
  ...localAttributes.current.style,
@@ -296,7 +322,7 @@ export function ColorEdit( props ) {
296
322
  };
297
323
 
298
324
  const onChangeGradient = ( value ) => {
299
- const slug = getGradientSlugByValue( gradients, value );
325
+ const slug = getGradientSlugByValue( allGradients, value );
300
326
  let newAttributes;
301
327
  if ( slug ) {
302
328
  const newStyle = {
@@ -331,7 +357,7 @@ export function ColorEdit( props ) {
331
357
  };
332
358
 
333
359
  const onChangeLinkColor = ( value ) => {
334
- const colorObject = getColorObjectByColorValue( solids, value );
360
+ const colorObject = getColorObjectByColorValue( allSolids, value );
335
361
  const newLinkColorValue = colorObject?.slug
336
362
  ? `var:preset|color|${ colorObject.slug }`
337
363
  : value;
@@ -360,7 +386,7 @@ export function ColorEdit( props ) {
360
386
  label: __( 'Text color' ),
361
387
  onColorChange: onChangeColor( 'text' ),
362
388
  colorValue: getColorObjectByAttributeValues(
363
- solids,
389
+ allSolids,
364
390
  textColor,
365
391
  style?.color?.text
366
392
  ).color,
@@ -375,7 +401,7 @@ export function ColorEdit( props ) {
375
401
  ? onChangeColor( 'background' )
376
402
  : undefined,
377
403
  colorValue: getColorObjectByAttributeValues(
378
- solids,
404
+ allSolids,
379
405
  backgroundColor,
380
406
  style?.color?.background
381
407
  ).color,
@@ -392,7 +418,7 @@ export function ColorEdit( props ) {
392
418
  label: __( 'Link Color' ),
393
419
  onColorChange: onChangeLinkColor,
394
420
  colorValue: getLinkColorFromAttributeValue(
395
- solids,
421
+ allSolids,
396
422
  style?.elements?.link?.color?.text
397
423
  ),
398
424
  clearable: !! style?.elements?.link?.color
@@ -417,20 +443,34 @@ export const withColorPaletteStyles = createHigherOrderComponent(
417
443
  ( BlockListBlock ) => ( props ) => {
418
444
  const { name, attributes } = props;
419
445
  const { backgroundColor, textColor } = attributes;
420
- const colors = useSetting( 'color.palette' ) || EMPTY_ARRAY;
446
+ const userPalette = useSetting( 'color.palette.custom' ) || [];
447
+ const themePalette = useSetting( 'color.palette.theme' ) || [];
448
+ const defaultPalette = useSetting( 'color.palette.default' ) || [];
449
+ const colors = useMemo(
450
+ () => [
451
+ ...( userPalette || [] ),
452
+ ...( themePalette || [] ),
453
+ ...( defaultPalette || [] ),
454
+ ],
455
+ [ userPalette, themePalette, defaultPalette ]
456
+ );
421
457
  if ( ! hasColorSupport( name ) || shouldSkipSerialization( name ) ) {
422
458
  return <BlockListBlock { ...props } />;
423
459
  }
460
+ const extraStyles = {};
424
461
 
425
- const extraStyles = {
426
- color: textColor
427
- ? getColorObjectByAttributeValues( colors, textColor )?.color
428
- : undefined,
429
- backgroundColor: backgroundColor
430
- ? getColorObjectByAttributeValues( colors, backgroundColor )
431
- ?.color
432
- : undefined,
433
- };
462
+ if ( textColor ) {
463
+ extraStyles.color = getColorObjectByAttributeValues(
464
+ colors,
465
+ textColor
466
+ )?.color;
467
+ }
468
+ if ( backgroundColor ) {
469
+ extraStyles.backgroundColor = getColorObjectByAttributeValues(
470
+ colors,
471
+ backgroundColor
472
+ )?.color;
473
+ }
434
474
 
435
475
  let wrapperProps = props.wrapperProps;
436
476
  wrapperProps = {
@@ -1,7 +1,19 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render } from '@testing-library/react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { registerBlockType, unregisterBlockType } from '@wordpress/blocks';
10
+
1
11
  /**
2
12
  * Internal dependencies
3
13
  */
14
+ import BlockEditorProvider from '../../components/provider';
4
15
  import { cleanEmptyObject } from '../utils';
16
+ import { withColorPaletteStyles } from '../color';
5
17
 
6
18
  describe( 'cleanEmptyObject', () => {
7
19
  it( 'should remove nested keys', () => {
@@ -10,3 +22,100 @@ describe( 'cleanEmptyObject', () => {
10
22
  );
11
23
  } );
12
24
  } );
25
+
26
+ describe( 'withColorPaletteStyles', () => {
27
+ const settings = {
28
+ __experimentalFeatures: {
29
+ color: {
30
+ palette: {
31
+ default: [
32
+ {
33
+ name: 'Pale pink',
34
+ slug: 'pale-pink',
35
+ color: '#f78da7',
36
+ },
37
+ {
38
+ name: 'Vivid green cyan',
39
+ slug: 'vivid-green-cyan',
40
+ color: '#00d084',
41
+ },
42
+ ],
43
+ },
44
+ },
45
+ },
46
+ };
47
+
48
+ const EnhancedComponent = withColorPaletteStyles(
49
+ ( { getStyleObj, wrapperProps } ) => (
50
+ <div>{ getStyleObj( wrapperProps.style ) }</div>
51
+ )
52
+ );
53
+
54
+ beforeAll( () => {
55
+ registerBlockType( 'core/test-block', {
56
+ save: () => undefined,
57
+ edit: () => undefined,
58
+ category: 'text',
59
+ title: 'test block',
60
+ supports: {
61
+ color: {
62
+ text: true,
63
+ background: true,
64
+ },
65
+ },
66
+ } );
67
+ } );
68
+
69
+ afterAll( () => {
70
+ unregisterBlockType( 'core/test-block' );
71
+ } );
72
+
73
+ it( 'should add color styles from attributes', () => {
74
+ const getStyleObj = jest.fn();
75
+
76
+ render(
77
+ <BlockEditorProvider settings={ settings } value={ [] }>
78
+ <EnhancedComponent
79
+ attributes={ {
80
+ backgroundColor: 'vivid-green-cyan',
81
+ textColor: 'pale-pink',
82
+ } }
83
+ name="core/test-block"
84
+ getStyleObj={ getStyleObj }
85
+ />
86
+ </BlockEditorProvider>
87
+ );
88
+
89
+ expect( getStyleObj ).toHaveBeenLastCalledWith( {
90
+ color: '#f78da7',
91
+ backgroundColor: '#00d084',
92
+ } );
93
+ } );
94
+
95
+ it( 'should not add undefined style values', () => {
96
+ // This test ensures that undefined `color` and `backgroundColor` styles
97
+ // are not added to the styles object. An undefined `backgroundColor`
98
+ // style causes a React warning when gradients are used, as the gradient
99
+ // style currently uses the `background` shorthand syntax.
100
+ // See: https://github.com/WordPress/gutenberg/issues/36899.
101
+ const getStyleObj = jest.fn();
102
+
103
+ render(
104
+ <BlockEditorProvider settings={ settings } value={ [] }>
105
+ <EnhancedComponent
106
+ attributes={ {
107
+ backgroundColor: undefined,
108
+ textColor: undefined,
109
+ } }
110
+ name="core/test-block"
111
+ getStyleObj={ getStyleObj }
112
+ />
113
+ </BlockEditorProvider>
114
+ );
115
+ // Check explictly for the object used in the call, because
116
+ // `toHaveBeenCalledWith` does not check for empty keys.
117
+ expect(
118
+ getStyleObj.mock.calls[ getStyleObj.mock.calls.length - 1 ][ 0 ]
119
+ ).toStrictEqual( {} );
120
+ } );
121
+ } );
@@ -231,7 +231,7 @@ export function TypographyPanel( props ) {
231
231
  );
232
232
  }
233
233
 
234
- const hasTypographySupport = ( blockName ) => {
234
+ export const hasTypographySupport = ( blockName ) => {
235
235
  return TYPOGRAPHY_SUPPORT_KEYS.some( ( key ) =>
236
236
  hasBlockSupport( blockName, key )
237
237
  );
@@ -3,6 +3,11 @@
3
3
  */
4
4
  import classnames from 'classnames';
5
5
 
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { useMemo } from '@wordpress/element';
10
+
6
11
  /**
7
12
  * Internal dependencies
8
13
  */
@@ -24,8 +29,6 @@ import useSetting from '../components/use-setting';
24
29
  // block support is being skipped for a block but the color related CSS classes
25
30
  // & styles still need to be generated so they can be applied to inner elements.
26
31
 
27
- const EMPTY_ARRAY = [];
28
-
29
32
  /**
30
33
  * Provides the CSS class names and inline styles for a block's color support
31
34
  * attributes.
@@ -70,6 +73,8 @@ export function getColorClassesAndStyles( attributes ) {
70
73
  };
71
74
  }
72
75
 
76
+ const EMPTY_OBJECT = {};
77
+
73
78
  /**
74
79
  * Determines the color related props for a block derived from its color block
75
80
  * support attributes.
@@ -84,8 +89,29 @@ export function getColorClassesAndStyles( attributes ) {
84
89
  export function useColorProps( attributes ) {
85
90
  const { backgroundColor, textColor, gradient } = attributes;
86
91
 
87
- const colors = useSetting( 'color.palette' ) || EMPTY_ARRAY;
88
- const gradients = useSetting( 'color.gradients' ) || EMPTY_ARRAY;
92
+ // Some color settings have a special handling for deprecated flags in `useSetting`,
93
+ // so we can't unwrap them by doing const { ... } = useSetting('color')
94
+ // until https://github.com/WordPress/gutenberg/issues/37094 is fixed.
95
+ const userPalette = useSetting( 'color.palette.custom' ) || [];
96
+ const themePalette = useSetting( 'color.palette.theme' ) || [];
97
+ const defaultPalette = useSetting( 'color.palette.default' ) || [];
98
+ const gradientsPerOrigin = useSetting( 'color.gradients' ) || EMPTY_OBJECT;
99
+ const colors = useMemo(
100
+ () => [
101
+ ...( userPalette || [] ),
102
+ ...( themePalette || [] ),
103
+ ...( defaultPalette || [] ),
104
+ ],
105
+ [ userPalette, themePalette, defaultPalette ]
106
+ );
107
+ const gradients = useMemo(
108
+ () => [
109
+ ...( gradientsPerOrigin?.custom || [] ),
110
+ ...( gradientsPerOrigin?.theme || [] ),
111
+ ...( gradientsPerOrigin?.default || [] ),
112
+ ],
113
+ [ gradientsPerOrigin ]
114
+ );
89
115
 
90
116
  const colorProps = getColorClassesAndStyles( attributes );
91
117
 
@@ -1643,22 +1643,19 @@ export const getInserterItems = createSelector(
1643
1643
  ? getReusableBlocks( state ).map( buildReusableBlockInserterItem )
1644
1644
  : [];
1645
1645
 
1646
- // Exclude any block type item that is to be replaced by a default
1647
- // variation.
1648
- const visibleBlockTypeInserterItems = blockTypeInserterItems.filter(
1649
- ( { variations = [] } ) =>
1650
- ! variations.some( ( { isDefault } ) => isDefault )
1651
- );
1652
-
1653
- const blockVariations = [];
1654
- // Show all available blocks with variations
1655
- for ( const item of blockTypeInserterItems ) {
1646
+ const items = blockTypeInserterItems.reduce( ( accumulator, item ) => {
1656
1647
  const { variations = [] } = item;
1648
+ // Exclude any block type item that is to be replaced by a default variation
1649
+ if ( ! variations.some( ( { isDefault } ) => isDefault ) ) {
1650
+ accumulator.push( item );
1651
+ }
1657
1652
  if ( variations.length ) {
1658
1653
  const variationMapper = getItemFromVariation( state, item );
1659
- blockVariations.push( ...variations.map( variationMapper ) );
1654
+ accumulator.push( ...variations.map( variationMapper ) );
1660
1655
  }
1661
- }
1656
+ return accumulator;
1657
+ }, [] );
1658
+
1662
1659
  // Ensure core blocks are prioritized in the returned results,
1663
1660
  // because third party blocks can be registered earlier than
1664
1661
  // the core blocks (usually by using the `init` action),
@@ -1671,20 +1668,11 @@ export const getInserterItems = createSelector(
1671
1668
  type.push( block );
1672
1669
  return blocks;
1673
1670
  };
1674
- const items = visibleBlockTypeInserterItems.reduce( groupByType, {
1675
- core: [],
1676
- noncore: [],
1677
- } );
1678
- const variations = blockVariations.reduce( groupByType, {
1679
- core: [],
1680
- noncore: [],
1681
- } );
1682
- const sortedBlockTypes = [
1683
- ...items.core,
1684
- ...variations.core,
1685
- ...items.noncore,
1686
- ...variations.noncore,
1687
- ];
1671
+ const {
1672
+ core: coreItems,
1673
+ noncore: nonCoreItems,
1674
+ } = items.reduce( groupByType, { core: [], noncore: [] } );
1675
+ const sortedBlockTypes = [ ...coreItems, ...nonCoreItems ];
1688
1676
  return [ ...sortedBlockTypes, ...reusableBlockInserterItems ];
1689
1677
  },
1690
1678
  ( state, rootClientId ) => [