@wordpress/block-editor 8.0.5 → 8.0.6

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 (46) hide show
  1. package/build/components/colors/with-colors.js +6 -4
  2. package/build/components/colors/with-colors.js.map +1 -1
  3. package/build/components/colors-gradients/control.js +4 -2
  4. package/build/components/colors-gradients/control.js.map +1 -1
  5. package/build/components/colors-gradients/panel-color-gradient-settings.js +5 -3
  6. package/build/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  7. package/build/components/gradients/use-gradient.js +7 -6
  8. package/build/components/gradients/use-gradient.js.map +1 -1
  9. package/build/components/use-setting/index.js +1 -1
  10. package/build/components/use-setting/index.js.map +1 -1
  11. package/build/hooks/color.js +29 -21
  12. package/build/hooks/color.js.map +1 -1
  13. package/build/hooks/typography.js +3 -0
  14. package/build/hooks/typography.js.map +1 -1
  15. package/build/hooks/use-color-props.js +13 -4
  16. package/build/hooks/use-color-props.js.map +1 -1
  17. package/build/store/selectors.js +37 -43
  18. package/build/store/selectors.js.map +1 -1
  19. package/build-module/components/colors/with-colors.js +6 -4
  20. package/build-module/components/colors/with-colors.js.map +1 -1
  21. package/build-module/components/colors-gradients/control.js +4 -2
  22. package/build-module/components/colors-gradients/control.js.map +1 -1
  23. package/build-module/components/colors-gradients/panel-color-gradient-settings.js +5 -3
  24. package/build-module/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  25. package/build-module/components/gradients/use-gradient.js +8 -6
  26. package/build-module/components/gradients/use-gradient.js.map +1 -1
  27. package/build-module/components/use-setting/index.js +1 -1
  28. package/build-module/components/use-setting/index.js.map +1 -1
  29. package/build-module/hooks/color.js +30 -22
  30. package/build-module/hooks/color.js.map +1 -1
  31. package/build-module/hooks/typography.js +1 -2
  32. package/build-module/hooks/typography.js.map +1 -1
  33. package/build-module/hooks/use-color-props.js +11 -3
  34. package/build-module/hooks/use-color-props.js.map +1 -1
  35. package/build-module/store/selectors.js +37 -43
  36. package/build-module/store/selectors.js.map +1 -1
  37. package/package.json +3 -3
  38. package/src/components/colors/with-colors.js +11 -5
  39. package/src/components/colors-gradients/control.js +2 -0
  40. package/src/components/colors-gradients/panel-color-gradient-settings.js +4 -2
  41. package/src/components/gradients/use-gradient.js +16 -7
  42. package/src/components/use-setting/index.js +1 -1
  43. package/src/hooks/color.js +58 -26
  44. package/src/hooks/typography.js +1 -1
  45. package/src/hooks/use-color-props.js +23 -4
  46. package/src/store/selectors.js +14 -26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "8.0.5",
3
+ "version": "8.0.6",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -38,7 +38,7 @@
38
38
  "@wordpress/blob": "^3.2.2",
39
39
  "@wordpress/block-serialization-default-parser": "^4.2.3",
40
40
  "@wordpress/blocks": "^11.1.4",
41
- "@wordpress/components": "^19.0.5",
41
+ "@wordpress/components": "^19.1.0",
42
42
  "@wordpress/compose": "^5.0.6",
43
43
  "@wordpress/data": "^6.1.4",
44
44
  "@wordpress/deprecated": "^3.2.3",
@@ -75,5 +75,5 @@
75
75
  "publishConfig": {
76
76
  "access": "public"
77
77
  },
78
- "gitHead": "518e7a279a0f596612232c55c83a351460f8816d"
78
+ "gitHead": "6d3bd917064b4b194677233ee426f5988fa441b9"
79
79
  }
@@ -6,7 +6,7 @@ import { isString, kebabCase, reduce, upperFirst } from 'lodash';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { Component } from '@wordpress/element';
9
+ import { useMemo, Component } from '@wordpress/element';
10
10
  import { compose, createHigherOrderComponent } from '@wordpress/compose';
11
11
 
12
12
  /**
@@ -20,8 +20,6 @@ import {
20
20
  } from './utils';
21
21
  import useSetting from '../use-setting';
22
22
 
23
- const DEFAULT_COLORS = [];
24
-
25
23
  /**
26
24
  * Higher order component factory for injecting the `colorsArray` argument as
27
25
  * the colors prop in the `withCustomColors` HOC.
@@ -47,8 +45,16 @@ const withCustomColorPalette = ( colorsArray ) =>
47
45
  const withEditorColorPalette = () =>
48
46
  createHigherOrderComponent(
49
47
  ( WrappedComponent ) => ( props ) => {
50
- const colors = useSetting( 'color.palette' ) || DEFAULT_COLORS;
51
- return <WrappedComponent { ...props } colors={ colors } />;
48
+ const { palette: colorPerOrigin } = useSetting( 'color' ) || {};
49
+ const allColors = useMemo(
50
+ () => [
51
+ ...( colorPerOrigin?.custom || [] ),
52
+ ...( colorPerOrigin?.theme || [] ),
53
+ ...( colorPerOrigin?.default || [] ),
54
+ ],
55
+ [ colorPerOrigin ]
56
+ );
57
+ return <WrappedComponent { ...props } colors={ allColors } />;
52
58
  },
53
59
  'withEditorColorPalette'
54
60
  );
@@ -44,6 +44,7 @@ function ColorGradientControlInner( {
44
44
  gradientValue,
45
45
  clearable,
46
46
  showTitle = true,
47
+ enableAlpha,
47
48
  } ) {
48
49
  const canChooseAColor =
49
50
  onColorChange && ( ! isEmpty( colors ) || ! disableCustomColors );
@@ -109,6 +110,7 @@ function ColorGradientControlInner( {
109
110
  __experimentalHasMultipleOrigins
110
111
  }
111
112
  clearable={ clearable }
113
+ enableAlpha={ enableAlpha }
112
114
  />
113
115
  ) }
114
116
  { ( currentTab === 'gradient' || ! canChooseAColor ) && (
@@ -92,6 +92,7 @@ export const PanelColorGradientSettingsInner = ( {
92
92
  title,
93
93
  showTitle = true,
94
94
  __experimentalHasMultipleOrigins,
95
+ enableAlpha,
95
96
  ...props
96
97
  } ) => {
97
98
  if (
@@ -143,6 +144,7 @@ export const PanelColorGradientSettingsInner = ( {
143
144
  disableCustomColors,
144
145
  disableCustomGradients,
145
146
  __experimentalHasMultipleOrigins,
147
+ enableAlpha,
146
148
  ...setting,
147
149
  } }
148
150
  />
@@ -172,7 +174,7 @@ const PanelColorGradientSettingsSingleSelect = ( props ) => {
172
174
 
173
175
  const PanelColorGradientSettingsMultipleSelect = ( props ) => {
174
176
  const colorGradientSettings = useCommonSingleMultipleSelects();
175
- const customColors = useSetting( 'color.palette.user' );
177
+ const customColors = useSetting( 'color.palette.custom' );
176
178
  const themeColors = useSetting( 'color.palette.theme' );
177
179
  const defaultColors = useSetting( 'color.palette.default' );
178
180
  const shouldDisplayDefaultColors = useSetting( 'color.defaultPalette' );
@@ -213,7 +215,7 @@ const PanelColorGradientSettingsMultipleSelect = ( props ) => {
213
215
  return result;
214
216
  }, [ defaultColors, themeColors, customColors ] );
215
217
 
216
- const customGradients = useSetting( 'color.gradients.user' );
218
+ const customGradients = useSetting( 'color.gradients.custom' );
217
219
  const themeGradients = useSetting( 'color.gradients.theme' );
218
220
  const defaultGradients = useSetting( 'color.gradients.default' );
219
221
  const shouldDisplayDefaultGradients = useSetting(
@@ -6,7 +6,7 @@ import { find } from 'lodash';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { useCallback } from '@wordpress/element';
9
+ import { useCallback, useMemo } from '@wordpress/element';
10
10
  import { useSelect, useDispatch } from '@wordpress/data';
11
11
 
12
12
  /**
@@ -16,8 +16,6 @@ import { useBlockEditContext } from '../block-edit';
16
16
  import useSetting from '../use-setting';
17
17
  import { store as blockEditorStore } from '../../store';
18
18
 
19
- const EMPTY_ARRAY = [];
20
-
21
19
  export function __experimentalGetGradientClass( gradientSlug ) {
22
20
  if ( ! gradientSlug ) {
23
21
  return undefined;
@@ -67,7 +65,15 @@ export function __experimentalUseGradient( {
67
65
  } = {} ) {
68
66
  const { clientId } = useBlockEditContext();
69
67
 
70
- const gradients = useSetting( 'color.gradients' ) || EMPTY_ARRAY;
68
+ const { gradients: gradientsPerOrigin } = useSetting( 'color' ) || {};
69
+ const allGradients = useMemo(
70
+ () => [
71
+ ...( gradientsPerOrigin?.custom || [] ),
72
+ ...( gradientsPerOrigin?.theme || [] ),
73
+ ...( gradientsPerOrigin?.default || [] ),
74
+ ],
75
+ [ gradientsPerOrigin ]
76
+ );
71
77
  const { gradient, customGradient } = useSelect(
72
78
  ( select ) => {
73
79
  const { getBlockAttributes } = select( blockEditorStore );
@@ -83,7 +89,10 @@ export function __experimentalUseGradient( {
83
89
  const { updateBlockAttributes } = useDispatch( blockEditorStore );
84
90
  const setGradient = useCallback(
85
91
  ( newGradientValue ) => {
86
- const slug = getGradientSlugByValue( gradients, newGradientValue );
92
+ const slug = getGradientSlugByValue(
93
+ allGradients,
94
+ newGradientValue
95
+ );
87
96
  if ( slug ) {
88
97
  updateBlockAttributes( clientId, {
89
98
  [ gradientAttribute ]: slug,
@@ -96,13 +105,13 @@ export function __experimentalUseGradient( {
96
105
  [ customGradientAttribute ]: newGradientValue,
97
106
  } );
98
107
  },
99
- [ gradients, clientId, updateBlockAttributes ]
108
+ [ allGradients, clientId, updateBlockAttributes ]
100
109
  );
101
110
 
102
111
  const gradientClass = __experimentalGetGradientClass( gradient );
103
112
  let gradientValue;
104
113
  if ( gradient ) {
105
- gradientValue = getGradientValueBySlug( gradients, gradient );
114
+ gradientValue = getGradientValueBySlug( allGradients, gradient );
106
115
  } else {
107
116
  gradientValue = customGradient;
108
117
  }
@@ -117,7 +117,7 @@ export default function useSetting( path ) {
117
117
  if ( experimentalFeaturesResult !== undefined ) {
118
118
  if ( PATHS_WITH_MERGE[ normalizedPath ] ) {
119
119
  return (
120
- experimentalFeaturesResult.user ??
120
+ experimentalFeaturesResult.custom ??
121
121
  experimentalFeaturesResult.theme ??
122
122
  experimentalFeaturesResult.default
123
123
  );
@@ -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,6 @@ 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 = [];
35
34
 
36
35
  const hasColorSupport = ( blockType ) => {
37
36
  const colorSupport = getBlockSupport( blockType, COLOR_SUPPORT_KEY );
@@ -217,13 +216,43 @@ function immutableSet( object, path, value ) {
217
216
  */
218
217
  export function ColorEdit( props ) {
219
218
  const { name: blockName, attributes } = props;
220
- const solids = useSetting( 'color.palette' ) || EMPTY_ARRAY;
221
- const gradients = useSetting( 'color.gradients' ) || EMPTY_ARRAY;
222
- const areCustomSolidsEnabled = useSetting( 'color.custom' );
223
- const areCustomGradientsEnabled = useSetting( 'color.customGradient' );
224
- const isLinkEnabled = useSetting( 'color.link' );
225
- const isTextEnabled = useSetting( 'color.text' );
226
- const isBackgroundEnabled = useSetting( 'color.background' );
219
+ const {
220
+ palette: solidsPerOrigin,
221
+ gradients: gradientsPerOrigin,
222
+ customGradient: areCustomGradientsEnabled,
223
+ custom: areCustomSolidsEnabled,
224
+ text: isTextEnabled,
225
+ background: isBackgroundEnabled,
226
+ link: isLinkEnabled,
227
+ } = useSetting( 'color' ) || {};
228
+
229
+ const solidsEnabled =
230
+ areCustomSolidsEnabled ||
231
+ ! solidsPerOrigin?.theme ||
232
+ solidsPerOrigin?.theme?.length > 0;
233
+
234
+ const gradientsEnabled =
235
+ areCustomGradientsEnabled ||
236
+ ! gradientsPerOrigin?.theme ||
237
+ gradientsPerOrigin?.theme?.length > 0;
238
+
239
+ const allSolids = useMemo(
240
+ () => [
241
+ ...( solidsPerOrigin?.custom || [] ),
242
+ ...( solidsPerOrigin?.theme || [] ),
243
+ ...( solidsPerOrigin?.default || [] ),
244
+ ],
245
+ [ solidsPerOrigin ]
246
+ );
247
+
248
+ const allGradients = useMemo(
249
+ () => [
250
+ ...( gradientsPerOrigin?.custom || [] ),
251
+ ...( gradientsPerOrigin?.theme || [] ),
252
+ ...( gradientsPerOrigin?.default || [] ),
253
+ ],
254
+ [ gradientsPerOrigin ]
255
+ );
227
256
 
228
257
  // Shouldn't be needed but right now the ColorGradientsPanel
229
258
  // can trigger both onChangeColor and onChangeBackground
@@ -239,20 +268,15 @@ export function ColorEdit( props ) {
239
268
  }
240
269
 
241
270
  const hasLinkColor =
242
- hasLinkColorSupport( blockName ) &&
243
- isLinkEnabled &&
244
- ( solids.length > 0 || areCustomSolidsEnabled );
271
+ hasLinkColorSupport( blockName ) && isLinkEnabled && solidsEnabled;
245
272
  const hasTextColor =
246
- hasTextColorSupport( blockName ) &&
247
- isTextEnabled &&
248
- ( solids.length > 0 || areCustomSolidsEnabled );
273
+ hasTextColorSupport( blockName ) && isTextEnabled && solidsEnabled;
249
274
  const hasBackgroundColor =
250
275
  hasBackgroundColorSupport( blockName ) &&
251
276
  isBackgroundEnabled &&
252
- ( solids.length > 0 || areCustomSolidsEnabled );
277
+ solidsEnabled;
253
278
  const hasGradientColor =
254
- hasGradientSupport( blockName ) &&
255
- ( gradients.length > 0 || areCustomGradientsEnabled );
279
+ hasGradientSupport( blockName ) && gradientsEnabled;
256
280
 
257
281
  if (
258
282
  ! hasLinkColor &&
@@ -266,13 +290,13 @@ export function ColorEdit( props ) {
266
290
  const { style, textColor, backgroundColor, gradient } = attributes;
267
291
  let gradientValue;
268
292
  if ( hasGradientColor && gradient ) {
269
- gradientValue = getGradientValueBySlug( gradients, gradient );
293
+ gradientValue = getGradientValueBySlug( allGradients, gradient );
270
294
  } else if ( hasGradientColor ) {
271
295
  gradientValue = style?.color?.gradient;
272
296
  }
273
297
 
274
298
  const onChangeColor = ( name ) => ( value ) => {
275
- const colorObject = getColorObjectByColorValue( solids, value );
299
+ const colorObject = getColorObjectByColorValue( allSolids, value );
276
300
  const attributeName = name + 'Color';
277
301
  const newStyle = {
278
302
  ...localAttributes.current.style,
@@ -296,7 +320,7 @@ export function ColorEdit( props ) {
296
320
  };
297
321
 
298
322
  const onChangeGradient = ( value ) => {
299
- const slug = getGradientSlugByValue( gradients, value );
323
+ const slug = getGradientSlugByValue( allGradients, value );
300
324
  let newAttributes;
301
325
  if ( slug ) {
302
326
  const newStyle = {
@@ -331,7 +355,7 @@ export function ColorEdit( props ) {
331
355
  };
332
356
 
333
357
  const onChangeLinkColor = ( value ) => {
334
- const colorObject = getColorObjectByColorValue( solids, value );
358
+ const colorObject = getColorObjectByColorValue( allSolids, value );
335
359
  const newLinkColorValue = colorObject?.slug
336
360
  ? `var:preset|color|${ colorObject.slug }`
337
361
  : value;
@@ -360,7 +384,7 @@ export function ColorEdit( props ) {
360
384
  label: __( 'Text color' ),
361
385
  onColorChange: onChangeColor( 'text' ),
362
386
  colorValue: getColorObjectByAttributeValues(
363
- solids,
387
+ allSolids,
364
388
  textColor,
365
389
  style?.color?.text
366
390
  ).color,
@@ -375,7 +399,7 @@ export function ColorEdit( props ) {
375
399
  ? onChangeColor( 'background' )
376
400
  : undefined,
377
401
  colorValue: getColorObjectByAttributeValues(
378
- solids,
402
+ allSolids,
379
403
  backgroundColor,
380
404
  style?.color?.background
381
405
  ).color,
@@ -392,7 +416,7 @@ export function ColorEdit( props ) {
392
416
  label: __( 'Link Color' ),
393
417
  onColorChange: onChangeLinkColor,
394
418
  colorValue: getLinkColorFromAttributeValue(
395
- solids,
419
+ allSolids,
396
420
  style?.elements?.link?.color?.text
397
421
  ),
398
422
  clearable: !! style?.elements?.link?.color
@@ -417,7 +441,15 @@ export const withColorPaletteStyles = createHigherOrderComponent(
417
441
  ( BlockListBlock ) => ( props ) => {
418
442
  const { name, attributes } = props;
419
443
  const { backgroundColor, textColor } = attributes;
420
- const colors = useSetting( 'color.palette' ) || EMPTY_ARRAY;
444
+ const { palette: solidsPerOrigin } = useSetting( 'color' ) || {};
445
+ const colors = useMemo(
446
+ () => [
447
+ ...( solidsPerOrigin?.custom || [] ),
448
+ ...( solidsPerOrigin?.theme || [] ),
449
+ ...( solidsPerOrigin?.default || [] ),
450
+ ],
451
+ [ solidsPerOrigin ]
452
+ );
421
453
  if ( ! hasColorSupport( name ) || shouldSkipSerialization( name ) ) {
422
454
  return <BlockListBlock { ...props } />;
423
455
  }
@@ -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.
@@ -84,8 +87,24 @@ export function getColorClassesAndStyles( attributes ) {
84
87
  export function useColorProps( attributes ) {
85
88
  const { backgroundColor, textColor, gradient } = attributes;
86
89
 
87
- const colors = useSetting( 'color.palette' ) || EMPTY_ARRAY;
88
- const gradients = useSetting( 'color.gradients' ) || EMPTY_ARRAY;
90
+ const { palette: solidsPerOrigin, gradients: gradientsPerOrigin } =
91
+ useSetting( 'color' ) || {};
92
+ const colors = useMemo(
93
+ () => [
94
+ ...( solidsPerOrigin?.custom || [] ),
95
+ ...( solidsPerOrigin?.theme || [] ),
96
+ ...( solidsPerOrigin?.default || [] ),
97
+ ],
98
+ [ solidsPerOrigin ]
99
+ );
100
+ const gradients = useMemo(
101
+ () => [
102
+ ...( gradientsPerOrigin?.custom || [] ),
103
+ ...( gradientsPerOrigin?.theme || [] ),
104
+ ...( gradientsPerOrigin?.default || [] ),
105
+ ],
106
+ [ gradientsPerOrigin ]
107
+ );
89
108
 
90
109
  const colorProps = getColorClassesAndStyles( attributes );
91
110
 
@@ -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 ) => [