@wordpress/edit-site 4.11.0 → 4.13.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 (180) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/add-new-template/add-custom-template-modal.js +4 -2
  3. package/build/components/add-new-template/add-custom-template-modal.js.map +1 -1
  4. package/build/components/add-new-template/new-template.js +29 -4
  5. package/build/components/add-new-template/new-template.js.map +1 -1
  6. package/build/components/add-new-template/utils.js +152 -28
  7. package/build/components/add-new-template/utils.js.map +1 -1
  8. package/build/components/block-editor/resizable-editor.js +26 -12
  9. package/build/components/block-editor/resizable-editor.js.map +1 -1
  10. package/build/components/global-styles/border-panel.js +3 -3
  11. package/build/components/global-styles/border-panel.js.map +1 -1
  12. package/build/components/global-styles/dimensions-panel.js +98 -8
  13. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  14. package/build/components/global-styles/hooks.js +4 -4
  15. package/build/components/global-styles/hooks.js.map +1 -1
  16. package/build/components/global-styles/screen-color-palette.js +1 -1
  17. package/build/components/global-styles/screen-color-palette.js.map +1 -1
  18. package/build/components/global-styles/screen-colors.js +51 -7
  19. package/build/components/global-styles/screen-colors.js.map +1 -1
  20. package/build/components/global-styles/screen-heading-color.js +157 -0
  21. package/build/components/global-styles/screen-heading-color.js.map +1 -0
  22. package/build/components/global-styles/screen-typography-element.js +4 -0
  23. package/build/components/global-styles/screen-typography-element.js.map +1 -1
  24. package/build/components/global-styles/screen-typography.js +5 -0
  25. package/build/components/global-styles/screen-typography.js.map +1 -1
  26. package/build/components/global-styles/typography-panel.js +82 -14
  27. package/build/components/global-styles/typography-panel.js.map +1 -1
  28. package/build/components/global-styles/typography-utils.js +217 -0
  29. package/build/components/global-styles/typography-utils.js.map +1 -0
  30. package/build/components/global-styles/ui.js +11 -0
  31. package/build/components/global-styles/ui.js.map +1 -1
  32. package/build/components/global-styles/use-global-styles-output.js +102 -49
  33. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  34. package/build/components/global-styles/utils.js +54 -5
  35. package/build/components/global-styles/utils.js.map +1 -1
  36. package/build/components/header/document-actions/index.js +1 -0
  37. package/build/components/header/document-actions/index.js.map +1 -1
  38. package/build/components/header/index.js +20 -6
  39. package/build/components/header/index.js.map +1 -1
  40. package/build/components/header/mode-switcher/index.js +0 -4
  41. package/build/components/header/mode-switcher/index.js.map +1 -1
  42. package/build/components/header/more-menu/index.js +13 -3
  43. package/build/components/header/more-menu/index.js.map +1 -1
  44. package/build/components/header/undo-redo/redo.js +2 -1
  45. package/build/components/header/undo-redo/redo.js.map +1 -1
  46. package/build/components/list/actions/index.js +1 -1
  47. package/build/components/list/actions/index.js.map +1 -1
  48. package/build/components/save-button/index.js +2 -3
  49. package/build/components/save-button/index.js.map +1 -1
  50. package/build/components/sidebar/default-sidebar.js +11 -1
  51. package/build/components/sidebar/default-sidebar.js.map +1 -1
  52. package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js +2 -2
  53. package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -1
  54. package/build/components/sidebar/plugin-sidebar/index.js +11 -1
  55. package/build/components/sidebar/plugin-sidebar/index.js.map +1 -1
  56. package/build/components/sidebar/template-card/template-actions.js +1 -1
  57. package/build/components/sidebar/template-card/template-actions.js.map +1 -1
  58. package/build/components/template-details/edit-template-title.js +1 -1
  59. package/build/components/template-details/edit-template-title.js.map +1 -1
  60. package/build/components/template-details/index.js +19 -9
  61. package/build/components/template-details/index.js.map +1 -1
  62. package/build/components/template-details/template-areas.js +1 -1
  63. package/build/components/template-details/template-areas.js.map +1 -1
  64. package/build/components/template-details/template-part-area-selector.js +47 -0
  65. package/build/components/template-details/template-part-area-selector.js.map +1 -0
  66. package/build/components/template-part-converter/convert-to-template-part.js +4 -1
  67. package/build/components/template-part-converter/convert-to-template-part.js.map +1 -1
  68. package/build/index.js +1 -1
  69. package/build/index.js.map +1 -1
  70. package/build-module/components/add-new-template/add-custom-template-modal.js +4 -2
  71. package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -1
  72. package/build-module/components/add-new-template/new-template.js +29 -6
  73. package/build-module/components/add-new-template/new-template.js.map +1 -1
  74. package/build-module/components/add-new-template/utils.js +147 -26
  75. package/build-module/components/add-new-template/utils.js.map +1 -1
  76. package/build-module/components/block-editor/resizable-editor.js +26 -12
  77. package/build-module/components/block-editor/resizable-editor.js.map +1 -1
  78. package/build-module/components/global-styles/border-panel.js +3 -3
  79. package/build-module/components/global-styles/border-panel.js.map +1 -1
  80. package/build-module/components/global-styles/dimensions-panel.js +96 -9
  81. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  82. package/build-module/components/global-styles/hooks.js +4 -4
  83. package/build-module/components/global-styles/hooks.js.map +1 -1
  84. package/build-module/components/global-styles/screen-color-palette.js +1 -1
  85. package/build-module/components/global-styles/screen-color-palette.js.map +1 -1
  86. package/build-module/components/global-styles/screen-colors.js +51 -7
  87. package/build-module/components/global-styles/screen-colors.js.map +1 -1
  88. package/build-module/components/global-styles/screen-heading-color.js +143 -0
  89. package/build-module/components/global-styles/screen-heading-color.js.map +1 -0
  90. package/build-module/components/global-styles/screen-typography-element.js +4 -0
  91. package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
  92. package/build-module/components/global-styles/screen-typography.js +5 -0
  93. package/build-module/components/global-styles/screen-typography.js.map +1 -1
  94. package/build-module/components/global-styles/typography-panel.js +83 -15
  95. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  96. package/build-module/components/global-styles/typography-utils.js +204 -0
  97. package/build-module/components/global-styles/typography-utils.js.map +1 -0
  98. package/build-module/components/global-styles/ui.js +10 -0
  99. package/build-module/components/global-styles/ui.js.map +1 -1
  100. package/build-module/components/global-styles/use-global-styles-output.js +102 -53
  101. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  102. package/build-module/components/global-styles/utils.js +53 -5
  103. package/build-module/components/global-styles/utils.js.map +1 -1
  104. package/build-module/components/header/document-actions/index.js +1 -0
  105. package/build-module/components/header/document-actions/index.js.map +1 -1
  106. package/build-module/components/header/index.js +22 -8
  107. package/build-module/components/header/index.js.map +1 -1
  108. package/build-module/components/header/mode-switcher/index.js +0 -4
  109. package/build-module/components/header/mode-switcher/index.js.map +1 -1
  110. package/build-module/components/header/more-menu/index.js +13 -3
  111. package/build-module/components/header/more-menu/index.js.map +1 -1
  112. package/build-module/components/header/undo-redo/redo.js +3 -2
  113. package/build-module/components/header/undo-redo/redo.js.map +1 -1
  114. package/build-module/components/list/actions/index.js +1 -1
  115. package/build-module/components/list/actions/index.js.map +1 -1
  116. package/build-module/components/save-button/index.js +3 -4
  117. package/build-module/components/save-button/index.js.map +1 -1
  118. package/build-module/components/sidebar/default-sidebar.js +9 -1
  119. package/build-module/components/sidebar/default-sidebar.js.map +1 -1
  120. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js +3 -3
  121. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -1
  122. package/build-module/components/sidebar/plugin-sidebar/index.js +9 -1
  123. package/build-module/components/sidebar/plugin-sidebar/index.js.map +1 -1
  124. package/build-module/components/sidebar/template-card/template-actions.js +1 -1
  125. package/build-module/components/sidebar/template-card/template-actions.js.map +1 -1
  126. package/build-module/components/template-details/edit-template-title.js +1 -1
  127. package/build-module/components/template-details/edit-template-title.js.map +1 -1
  128. package/build-module/components/template-details/index.js +19 -10
  129. package/build-module/components/template-details/index.js.map +1 -1
  130. package/build-module/components/template-details/template-areas.js +1 -1
  131. package/build-module/components/template-details/template-areas.js.map +1 -1
  132. package/build-module/components/template-details/template-part-area-selector.js +35 -0
  133. package/build-module/components/template-details/template-part-area-selector.js.map +1 -0
  134. package/build-module/components/template-part-converter/convert-to-template-part.js +3 -1
  135. package/build-module/components/template-part-converter/convert-to-template-part.js.map +1 -1
  136. package/build-module/index.js +1 -1
  137. package/build-module/index.js.map +1 -1
  138. package/build-style/style-rtl.css +15 -8
  139. package/build-style/style.css +15 -8
  140. package/package.json +29 -29
  141. package/src/components/add-new-template/add-custom-template-modal.js +12 -3
  142. package/src/components/add-new-template/new-template.js +53 -24
  143. package/src/components/add-new-template/utils.js +145 -16
  144. package/src/components/block-editor/resizable-editor.js +28 -18
  145. package/src/components/editor/style.scss +1 -0
  146. package/src/components/global-styles/border-panel.js +3 -3
  147. package/src/components/global-styles/dimensions-panel.js +139 -33
  148. package/src/components/global-styles/hooks.js +4 -3
  149. package/src/components/global-styles/screen-color-palette.js +1 -1
  150. package/src/components/global-styles/screen-colors.js +46 -4
  151. package/src/components/global-styles/screen-heading-color.js +201 -0
  152. package/src/components/global-styles/screen-typography-element.js +4 -0
  153. package/src/components/global-styles/screen-typography.js +6 -0
  154. package/src/components/global-styles/style.scss +14 -6
  155. package/src/components/global-styles/test/typography-utils.js +130 -0
  156. package/src/components/global-styles/test/use-global-styles-output.js +79 -3
  157. package/src/components/global-styles/test/utils.js +68 -8
  158. package/src/components/global-styles/typography-panel.js +119 -48
  159. package/src/components/global-styles/typography-utils.js +228 -0
  160. package/src/components/global-styles/ui.js +13 -0
  161. package/src/components/global-styles/use-global-styles-output.js +119 -61
  162. package/src/components/global-styles/utils.js +39 -4
  163. package/src/components/header/document-actions/index.js +3 -0
  164. package/src/components/header/index.js +32 -4
  165. package/src/components/header/mode-switcher/index.js +0 -3
  166. package/src/components/header/more-menu/index.js +7 -2
  167. package/src/components/header/undo-redo/redo.js +6 -2
  168. package/src/components/list/actions/index.js +3 -1
  169. package/src/components/save-button/index.js +10 -13
  170. package/src/components/sidebar/default-sidebar.js +12 -0
  171. package/src/components/sidebar/navigation-menu-sidebar/navigation-menu.js +1 -5
  172. package/src/components/sidebar/plugin-sidebar/index.js +12 -0
  173. package/src/components/sidebar/template-card/template-actions.js +3 -1
  174. package/src/components/template-details/edit-template-title.js +7 -3
  175. package/src/components/template-details/index.js +23 -8
  176. package/src/components/template-details/style.scss +0 -5
  177. package/src/components/template-details/template-areas.js +3 -1
  178. package/src/components/template-details/template-part-area-selector.js +38 -0
  179. package/src/components/template-part-converter/convert-to-template-part.js +3 -1
  180. package/src/index.js +1 -1
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
@@ -11,7 +16,10 @@ import {
11
16
  __experimentalUseCustomUnits as useCustomUnits,
12
17
  __experimentalView as View,
13
18
  } from '@wordpress/components';
14
- import { __experimentalUseCustomSides as useCustomSides } from '@wordpress/block-editor';
19
+ import {
20
+ __experimentalUseCustomSides as useCustomSides,
21
+ __experimentalSpacingSizesControl as SpacingSizesControl,
22
+ } from '@wordpress/block-editor';
15
23
  import { Icon, positionCenter, stretchWide } from '@wordpress/icons';
16
24
 
17
25
  /**
@@ -66,6 +74,12 @@ function useHasGap( name ) {
66
74
  return settings && supports.includes( 'blockGap' );
67
75
  }
68
76
 
77
+ function useHasSpacingPresets() {
78
+ const [ settings ] = useSetting( 'spacing.spacingSizes' );
79
+
80
+ return settings && settings.length > 0;
81
+ }
82
+
69
83
  function filterValuesBySides( values, sides ) {
70
84
  if ( ! sides ) {
71
85
  // If no custom side configuration all sides are opted into by default.
@@ -90,7 +104,7 @@ function filterValuesBySides( values, sides ) {
90
104
  }
91
105
 
92
106
  function splitStyleValue( value ) {
93
- // Check for shorthand value ( a string value ).
107
+ // Check for shorthand value (a string value).
94
108
  if ( value && typeof value === 'string' ) {
95
109
  // Convert to value for individual sides for BoxControl.
96
110
  return {
@@ -104,6 +118,25 @@ function splitStyleValue( value ) {
104
118
  return value;
105
119
  }
106
120
 
121
+ function splitGapValue( value ) {
122
+ // Check for shorthand value (a string value).
123
+ if ( value && typeof value === 'string' ) {
124
+ // Convert to value for individual sides for BoxControl.
125
+ return {
126
+ top: value,
127
+ right: value,
128
+ bottom: value,
129
+ left: value,
130
+ };
131
+ }
132
+
133
+ return {
134
+ ...value,
135
+ right: value?.left,
136
+ bottom: value?.top,
137
+ };
138
+ }
139
+
107
140
  // Props for managing `layout.contentSize`.
108
141
  function useContentSizeProps( name ) {
109
142
  const [ contentSizeValue, setContentSizeValue ] = useSetting(
@@ -160,8 +193,9 @@ function usePaddingProps( name ) {
160
193
  setRawPadding( padding );
161
194
  };
162
195
  const resetPaddingValue = () => setPaddingValues( {} );
163
- const hasPaddingValue = () =>
164
- !! paddingValues && Object.keys( paddingValues ).length;
196
+ const [ userSetPaddingValue ] = useStyle( 'spacing.padding', name, 'user' );
197
+ // The `hasPaddingValue` check does not need a parsed value, as `userSetPaddingValue` will be `undefined` if not set.
198
+ const hasPaddingValue = () => !! userSetPaddingValue;
165
199
 
166
200
  return {
167
201
  paddingValues,
@@ -203,11 +237,29 @@ function useMarginProps( name ) {
203
237
  // Props for managing `spacing.blockGap`.
204
238
  function useBlockGapProps( name ) {
205
239
  const [ gapValue, setGapValue ] = useStyle( 'spacing.blockGap', name );
240
+ const gapValues = splitGapValue( gapValue );
241
+ const setGapValues = ( nextBoxGapValue ) => {
242
+ if ( ! nextBoxGapValue ) {
243
+ setGapValue( null );
244
+ }
245
+ setGapValue( {
246
+ top: nextBoxGapValue?.top,
247
+ left: nextBoxGapValue?.left,
248
+ } );
249
+ };
250
+ const gapSides = useCustomSides( name, 'blockGap' );
251
+ const isAxialGap =
252
+ gapSides && gapSides.some( ( side ) => AXIAL_SIDES.includes( side ) );
206
253
  const resetGapValue = () => setGapValue( undefined );
207
- const hasGapValue = () => !! gapValue;
254
+ const [ userSetGapValue ] = useStyle( 'spacing.blockGap', name, 'user' );
255
+ const hasGapValue = () => !! userSetGapValue;
208
256
  return {
209
257
  gapValue,
258
+ gapValues,
259
+ gapSides,
260
+ isAxialGap,
210
261
  setGapValue,
262
+ setGapValues,
211
263
  resetGapValue,
212
264
  hasGapValue,
213
265
  };
@@ -219,6 +271,7 @@ export default function DimensionsPanel( { name } ) {
219
271
  const showPaddingControl = useHasPadding( name );
220
272
  const showMarginControl = useHasMargin( name );
221
273
  const showGapControl = useHasGap( name );
274
+ const showSpacingPresetsControl = useHasSpacingPresets();
222
275
  const units = useCustomUnits( {
223
276
  availableUnits: useSetting( 'spacing.units', name )[ 0 ] || [
224
277
  '%',
@@ -266,8 +319,16 @@ export default function DimensionsPanel( { name } ) {
266
319
  } = useMarginProps( name );
267
320
 
268
321
  // Props for managing `spacing.blockGap`.
269
- const { gapValue, setGapValue, resetGapValue, hasGapValue } =
270
- useBlockGapProps( name );
322
+ const {
323
+ gapValue,
324
+ gapValues,
325
+ gapSides,
326
+ isAxialGap,
327
+ setGapValue,
328
+ setGapValues,
329
+ resetGapValue,
330
+ hasGapValue,
331
+ } = useBlockGapProps( name );
271
332
 
272
333
  const resetAll = () => {
273
334
  resetPaddingValue();
@@ -340,16 +401,32 @@ export default function DimensionsPanel( { name } ) {
340
401
  label={ __( 'Padding' ) }
341
402
  onDeselect={ resetPaddingValue }
342
403
  isShownByDefault={ true }
404
+ className={ classnames( {
405
+ 'tools-panel-item-spacing': showSpacingPresetsControl,
406
+ } ) }
343
407
  >
344
- <BoxControl
345
- values={ paddingValues }
346
- onChange={ setPaddingValues }
347
- label={ __( 'Padding' ) }
348
- sides={ paddingSides }
349
- units={ units }
350
- allowReset={ false }
351
- splitOnAxis={ isAxialPadding }
352
- />
408
+ { ! showSpacingPresetsControl && (
409
+ <BoxControl
410
+ values={ paddingValues }
411
+ onChange={ setPaddingValues }
412
+ label={ __( 'Padding' ) }
413
+ sides={ paddingSides }
414
+ units={ units }
415
+ allowReset={ false }
416
+ splitOnAxis={ isAxialPadding }
417
+ />
418
+ ) }
419
+ { showSpacingPresetsControl && (
420
+ <SpacingSizesControl
421
+ values={ paddingValues }
422
+ onChange={ setPaddingValues }
423
+ label={ __( 'Padding' ) }
424
+ sides={ paddingSides }
425
+ units={ units }
426
+ allowReset={ false }
427
+ splitOnAxis={ isAxialPadding }
428
+ />
429
+ ) }
353
430
  </ToolsPanelItem>
354
431
  ) }
355
432
  { showMarginControl && (
@@ -358,16 +435,32 @@ export default function DimensionsPanel( { name } ) {
358
435
  label={ __( 'Margin' ) }
359
436
  onDeselect={ resetMarginValue }
360
437
  isShownByDefault={ true }
438
+ className={ classnames( {
439
+ 'tools-panel-item-spacing': showSpacingPresetsControl,
440
+ } ) }
361
441
  >
362
- <BoxControl
363
- values={ marginValues }
364
- onChange={ setMarginValues }
365
- label={ __( 'Margin' ) }
366
- sides={ marginSides }
367
- units={ units }
368
- allowReset={ false }
369
- splitOnAxis={ isAxialMargin }
370
- />
442
+ { ! showSpacingPresetsControl && (
443
+ <BoxControl
444
+ values={ marginValues }
445
+ onChange={ setMarginValues }
446
+ label={ __( 'Margin' ) }
447
+ sides={ marginSides }
448
+ units={ units }
449
+ allowReset={ false }
450
+ splitOnAxis={ isAxialMargin }
451
+ />
452
+ ) }
453
+ { showSpacingPresetsControl && (
454
+ <SpacingSizesControl
455
+ values={ marginValues }
456
+ onChange={ setMarginValues }
457
+ label={ __( 'Margin' ) }
458
+ sides={ marginSides }
459
+ units={ units }
460
+ allowReset={ false }
461
+ splitOnAxis={ isAxialMargin }
462
+ />
463
+ ) }
371
464
  </ToolsPanelItem>
372
465
  ) }
373
466
  { showGapControl && (
@@ -377,14 +470,27 @@ export default function DimensionsPanel( { name } ) {
377
470
  onDeselect={ resetGapValue }
378
471
  isShownByDefault={ true }
379
472
  >
380
- <UnitControl
381
- label={ __( 'Block spacing' ) }
382
- __unstableInputWidth="80px"
383
- min={ 0 }
384
- onChange={ setGapValue }
385
- units={ units }
386
- value={ gapValue }
387
- />
473
+ { isAxialGap ? (
474
+ <BoxControl
475
+ label={ __( 'Block spacing' ) }
476
+ min={ 0 }
477
+ onChange={ setGapValues }
478
+ units={ units }
479
+ sides={ gapSides }
480
+ values={ gapValues }
481
+ allowReset={ false }
482
+ splitOnAxis={ isAxialGap }
483
+ />
484
+ ) : (
485
+ <UnitControl
486
+ label={ __( 'Block spacing' ) }
487
+ __unstableInputWidth="80px"
488
+ min={ 0 }
489
+ onChange={ setGapValue }
490
+ units={ units }
491
+ value={ gapValue }
492
+ />
493
+ ) }
388
494
  </ToolsPanelItem>
389
495
  ) }
390
496
  </ToolsPanel>
@@ -128,21 +128,21 @@ export function useStyle( path, blockName, source = 'all' ) {
128
128
  switch ( source ) {
129
129
  case 'all':
130
130
  result = getValueFromVariable(
131
- mergedConfig.settings,
131
+ mergedConfig,
132
132
  blockName,
133
133
  get( userConfig, finalPath ) ?? get( baseConfig, finalPath )
134
134
  );
135
135
  break;
136
136
  case 'user':
137
137
  result = getValueFromVariable(
138
- mergedConfig.settings,
138
+ mergedConfig,
139
139
  blockName,
140
140
  get( userConfig, finalPath )
141
141
  );
142
142
  break;
143
143
  case 'base':
144
144
  result = getValueFromVariable(
145
- baseConfig.settings,
145
+ baseConfig,
146
146
  blockName,
147
147
  get( baseConfig, finalPath )
148
148
  );
@@ -170,6 +170,7 @@ const ROOT_BLOCK_SUPPORTS = [
170
170
  'padding',
171
171
  'contentSize',
172
172
  'wideSize',
173
+ 'blockGap',
173
174
  ];
174
175
 
175
176
  export function getSupportedGlobalStylesPanels( name ) {
@@ -24,7 +24,7 @@ function ScreenColorPalette( { name } ) {
24
24
  tabs={ [
25
25
  {
26
26
  name: 'solid',
27
- title: 'Solid color',
27
+ title: 'Solid',
28
28
  value: 'solid',
29
29
  },
30
30
  {
@@ -45,7 +45,9 @@ function BackgroundColorItem( { name, parentMenu } ) {
45
45
  data-testid="background-color-indicator"
46
46
  />
47
47
  </ColorIndicatorWrapper>
48
- <FlexItem>{ __( 'Background' ) }</FlexItem>
48
+ <FlexItem className="edit-site-global-styles__color-label">
49
+ { __( 'Background' ) }
50
+ </FlexItem>
49
51
  </HStack>
50
52
  </NavigationButtonAsItem>
51
53
  );
@@ -72,7 +74,9 @@ function TextColorItem( { name, parentMenu } ) {
72
74
  data-testid="text-color-indicator"
73
75
  />
74
76
  </ColorIndicatorWrapper>
75
- <FlexItem>{ __( 'Text' ) }</FlexItem>
77
+ <FlexItem className="edit-site-global-styles__color-label">
78
+ { __( 'Text' ) }
79
+ </FlexItem>
76
80
  </HStack>
77
81
  </NavigationButtonAsItem>
78
82
  );
@@ -102,7 +106,39 @@ function LinkColorItem( { name, parentMenu } ) {
102
106
  <ColorIndicator colorValue={ colorHover } />
103
107
  </ColorIndicatorWrapper>
104
108
  </ZStack>
105
- <FlexItem>{ __( 'Links' ) }</FlexItem>
109
+ <FlexItem className="edit-site-global-styles__color-label">
110
+ { __( 'Links' ) }
111
+ </FlexItem>
112
+ </HStack>
113
+ </NavigationButtonAsItem>
114
+ );
115
+ }
116
+
117
+ function HeadingColorItem( { name, parentMenu } ) {
118
+ const supports = getSupportedGlobalStylesPanels( name );
119
+ const hasSupport = supports.includes( 'color' );
120
+ const [ color ] = useStyle( 'elements.heading.color.text', name );
121
+ const [ bgColor ] = useStyle( 'elements.heading.color.background', name );
122
+
123
+ if ( ! hasSupport ) {
124
+ return null;
125
+ }
126
+
127
+ return (
128
+ <NavigationButtonAsItem
129
+ path={ parentMenu + '/colors/heading' }
130
+ aria-label={ __( 'Colors heading styles' ) }
131
+ >
132
+ <HStack justify="flex-start">
133
+ <ZStack isLayered={ false } offset={ -8 }>
134
+ <ColorIndicatorWrapper expanded={ false }>
135
+ <ColorIndicator colorValue={ bgColor } />
136
+ </ColorIndicatorWrapper>
137
+ <ColorIndicatorWrapper expanded={ false }>
138
+ <ColorIndicator colorValue={ color } />
139
+ </ColorIndicatorWrapper>
140
+ </ZStack>
141
+ <FlexItem>{ __( 'Headings' ) }</FlexItem>
106
142
  </HStack>
107
143
  </NavigationButtonAsItem>
108
144
  );
@@ -129,7 +165,9 @@ function ButtonColorItem( { name, parentMenu } ) {
129
165
  <ColorIndicator colorValue={ color } />
130
166
  </ColorIndicatorWrapper>
131
167
  </ZStack>
132
- <FlexItem>{ __( 'Buttons' ) }</FlexItem>
168
+ <FlexItem className="edit-site-global-styles__color-label">
169
+ { __( 'Buttons' ) }
170
+ </FlexItem>
133
171
  </HStack>
134
172
  </NavigationButtonAsItem>
135
173
  );
@@ -166,6 +204,10 @@ function ScreenColors( { name } ) {
166
204
  name={ name }
167
205
  parentMenu={ parentMenu }
168
206
  />
207
+ <HeadingColorItem
208
+ name={ name }
209
+ parentMenu={ parentMenu }
210
+ />
169
211
  <ButtonColorItem
170
212
  name={ name }
171
213
  parentMenu={ parentMenu }
@@ -0,0 +1,201 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { sprintf, __ } from '@wordpress/i18n';
5
+ import {
6
+ __experimentalToggleGroupControl as ToggleGroupControl,
7
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
8
+ } from '@wordpress/components';
9
+ import { __experimentalColorGradientControl as ColorGradientControl } from '@wordpress/block-editor';
10
+ import { useState } from '@wordpress/element';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import ScreenHeader from './header';
16
+ import {
17
+ getSupportedGlobalStylesPanels,
18
+ useSetting,
19
+ useStyle,
20
+ useColorsPerOrigin,
21
+ useGradientsPerOrigin,
22
+ } from './hooks';
23
+
24
+ function ScreenHeadingColor( { name } ) {
25
+ const [ selectedLevel, setCurrentTab ] = useState( 'heading' );
26
+
27
+ const supports = getSupportedGlobalStylesPanels( name );
28
+ const [ solids ] = useSetting( 'color.palette', name );
29
+ const [ gradients ] = useSetting( 'color.gradients', name );
30
+ const [ areCustomSolidsEnabled ] = useSetting( 'color.custom', name );
31
+ const [ areCustomGradientsEnabled ] = useSetting(
32
+ 'color.customGradient',
33
+ name
34
+ );
35
+ const [ isTextEnabled ] = useSetting( 'color.text', name );
36
+ const [ isBackgroundEnabled ] = useSetting( 'color.background', name );
37
+
38
+ const colorsPerOrigin = useColorsPerOrigin( name );
39
+ const gradientsPerOrigin = useGradientsPerOrigin( name );
40
+
41
+ const hasTextColor =
42
+ supports.includes( 'color' ) &&
43
+ isTextEnabled &&
44
+ ( solids.length > 0 || areCustomSolidsEnabled );
45
+
46
+ const hasBackgroundColor =
47
+ supports.includes( 'backgroundColor' ) &&
48
+ isBackgroundEnabled &&
49
+ ( solids.length > 0 || areCustomSolidsEnabled );
50
+ const hasGradientColor =
51
+ supports.includes( 'background' ) &&
52
+ ( gradients.length > 0 || areCustomGradientsEnabled );
53
+
54
+ const [ color, setColor ] = useStyle(
55
+ 'elements.' + selectedLevel + '.color.text',
56
+ name
57
+ );
58
+ const [ userColor ] = useStyle(
59
+ 'elements.' + selectedLevel + '.color.text',
60
+ name,
61
+ 'user'
62
+ );
63
+
64
+ const [ backgroundColor, setBackgroundColor ] = useStyle(
65
+ 'elements.' + selectedLevel + '.color.background',
66
+ name
67
+ );
68
+ const [ userBackgroundColor ] = useStyle(
69
+ 'elements.' + selectedLevel + '.color.background',
70
+ name,
71
+ 'user'
72
+ );
73
+ const [ gradient, setGradient ] = useStyle(
74
+ 'elements.' + selectedLevel + '.color.gradient',
75
+ name
76
+ );
77
+ const [ userGradient ] = useStyle(
78
+ 'elements.' + selectedLevel + '.color.gradient',
79
+ name,
80
+ 'user'
81
+ );
82
+
83
+ if ( ! hasTextColor && ! hasBackgroundColor && ! hasGradientColor ) {
84
+ return null;
85
+ }
86
+
87
+ let backgroundSettings = {};
88
+ if ( hasBackgroundColor ) {
89
+ backgroundSettings = {
90
+ colorValue: backgroundColor,
91
+ onColorChange: setBackgroundColor,
92
+ };
93
+ if ( backgroundColor ) {
94
+ backgroundSettings.clearable =
95
+ backgroundColor === userBackgroundColor;
96
+ }
97
+ }
98
+
99
+ let gradientSettings = {};
100
+ if ( hasGradientColor ) {
101
+ gradientSettings = {
102
+ gradientValue: gradient,
103
+ onGradientChange: setGradient,
104
+ };
105
+ if ( gradient ) {
106
+ gradientSettings.clearable = gradient === userGradient;
107
+ }
108
+ }
109
+
110
+ const controlProps = {
111
+ ...backgroundSettings,
112
+ ...gradientSettings,
113
+ };
114
+
115
+ return (
116
+ <>
117
+ <ScreenHeader
118
+ title={ __( 'Headings' ) }
119
+ description={ __(
120
+ 'Set the default color used for headings across the site.'
121
+ ) }
122
+ />
123
+ <div className="edit-site-global-styles-screen-heading-color">
124
+ <h4>{ __( 'Select heading level' ) }</h4>
125
+
126
+ <ToggleGroupControl
127
+ label={ __( 'Select heading level' ) }
128
+ hideLabelFromVision={ true }
129
+ value={ selectedLevel }
130
+ onChange={ setCurrentTab }
131
+ isBlock
132
+ >
133
+ <ToggleGroupControlOption
134
+ value="heading"
135
+ /* translators: 'All' refers to selecting all heading levels
136
+ and applying the same style to h1-h6. */
137
+ label={ __( 'All' ) }
138
+ />
139
+ <ToggleGroupControlOption value="h1" label={ __( 'H1' ) } />
140
+ <ToggleGroupControlOption value="h2" label={ __( 'H2' ) } />
141
+ <ToggleGroupControlOption value="h3" label={ __( 'H3' ) } />
142
+ <ToggleGroupControlOption value="h4" label={ __( 'H4' ) } />
143
+ <ToggleGroupControlOption value="h5" label={ __( 'H5' ) } />
144
+ <ToggleGroupControlOption value="h6" label={ __( 'H6' ) } />
145
+ </ToggleGroupControl>
146
+ </div>
147
+ { hasTextColor && (
148
+ <div className="edit-site-global-styles-screen-heading-color">
149
+ <h4>
150
+ { selectedLevel === 'heading'
151
+ ? __( 'Text color for all heading levels' )
152
+ : sprintf(
153
+ /* translators: %s: heading level (h1-h6) */
154
+ __( 'Text color for %s' ),
155
+ selectedLevel.toUpperCase()
156
+ ) }
157
+ </h4>
158
+ <ColorGradientControl
159
+ className="edit-site-screen-heading-text-color__control"
160
+ colors={ colorsPerOrigin }
161
+ disableCustomColors={ ! areCustomSolidsEnabled }
162
+ __experimentalHasMultipleOrigins
163
+ showTitle={ false }
164
+ enableAlpha
165
+ __experimentalIsRenderedInSidebar
166
+ colorValue={ color }
167
+ onColorChange={ setColor }
168
+ clearable={ color === userColor }
169
+ />
170
+ </div>
171
+ ) }
172
+ { hasBackgroundColor && (
173
+ <div className="edit-site-global-styles-screen-heading-color">
174
+ <h4>
175
+ { selectedLevel === 'heading'
176
+ ? __( 'Background color for all heading levels' )
177
+ : sprintf(
178
+ /* translators: %s: heading level (h1-h6) */
179
+ __( 'Background color for %s' ),
180
+ selectedLevel.toUpperCase()
181
+ ) }
182
+ </h4>
183
+ <ColorGradientControl
184
+ className="edit-site-screen-heading-background-color__control"
185
+ colors={ colorsPerOrigin }
186
+ gradients={ gradientsPerOrigin }
187
+ disableCustomColors={ ! areCustomSolidsEnabled }
188
+ disableCustomGradients={ ! areCustomGradientsEnabled }
189
+ __experimentalHasMultipleOrigins
190
+ showTitle={ false }
191
+ enableAlpha
192
+ __experimentalIsRenderedInSidebar
193
+ { ...controlProps }
194
+ />
195
+ </div>
196
+ ) }
197
+ </>
198
+ );
199
+ }
200
+
201
+ export default ScreenHeadingColor;
@@ -18,6 +18,10 @@ const elements = {
18
18
  description: __( 'Manage the fonts and typography used on the links.' ),
19
19
  title: __( 'Links' ),
20
20
  },
21
+ heading: {
22
+ description: __( 'Manage the fonts and typography used on headings.' ),
23
+ title: __( 'Headings' ),
24
+ },
21
25
  button: {
22
26
  description: __( 'Manage the fonts and typography used on buttons.' ),
23
27
  title: __( 'Buttons' ),
@@ -104,6 +104,12 @@ function ScreenTypography( { name } ) {
104
104
  element="link"
105
105
  label={ __( 'Links' ) }
106
106
  />
107
+ <Item
108
+ name={ name }
109
+ parentMenu={ parentMenu }
110
+ element="heading"
111
+ label={ __( 'Headings' ) }
112
+ />
107
113
  <Item
108
114
  name={ name }
109
115
  parentMenu={ parentMenu }
@@ -21,6 +21,12 @@
21
21
  border-radius: $radius-block-ui;
22
22
  }
23
23
 
24
+ .edit-site-typography-panel__full-width-control {
25
+ grid-column: 1 / -1;
26
+ max-width: 100%;
27
+ }
28
+
29
+ .edit-site-global-styles-screen-heading-color,
24
30
  .edit-site-global-styles-screen-typography {
25
31
  margin: $grid-unit-20;
26
32
  }
@@ -41,6 +47,7 @@
41
47
  .component-color-indicator {
42
48
  // Show a diagonal line (crossed out) for empty swatches.
43
49
  background: linear-gradient(-45deg, transparent 48%, $gray-300 48%, $gray-300 52%, transparent 52%);
50
+ flex-shrink: 0;
44
51
  }
45
52
  }
46
53
 
@@ -72,12 +79,6 @@
72
79
  padding: $grid-unit-20;
73
80
  }
74
81
 
75
- .edit-site-screen-background-color__control {
76
- .block-editor-color-gradient-control__tab-panel {
77
- padding: $grid-unit-20;
78
- }
79
- }
80
-
81
82
  .edit-site-global-styles-variations_item {
82
83
  box-sizing: border-box;
83
84
 
@@ -107,4 +108,11 @@
107
108
  .edit-site-global-styles__color-indicator-wrapper {
108
109
  // Match the height of the rest of the icons (24px).
109
110
  height: $grid-unit * 3;
111
+ flex-shrink: 0;
112
+ }
113
+
114
+ .edit-site-global-styles__color-label {
115
+ white-space: nowrap;
116
+ overflow: hidden;
117
+ text-overflow: ellipsis;
110
118
  }