@wordpress/edit-site 4.11.0 → 4.12.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 (127) hide show
  1. package/CHANGELOG.md +2 -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 +22 -2
  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/global-styles/dimensions-panel.js +6 -2
  9. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  10. package/build/components/global-styles/hooks.js +1 -1
  11. package/build/components/global-styles/hooks.js.map +1 -1
  12. package/build/components/global-styles/screen-color-palette.js +1 -1
  13. package/build/components/global-styles/screen-color-palette.js.map +1 -1
  14. package/build/components/global-styles/screen-colors.js +51 -7
  15. package/build/components/global-styles/screen-colors.js.map +1 -1
  16. package/build/components/global-styles/screen-heading-color.js +157 -0
  17. package/build/components/global-styles/screen-heading-color.js.map +1 -0
  18. package/build/components/global-styles/screen-typography-element.js +4 -0
  19. package/build/components/global-styles/screen-typography-element.js.map +1 -1
  20. package/build/components/global-styles/screen-typography.js +5 -0
  21. package/build/components/global-styles/screen-typography.js.map +1 -1
  22. package/build/components/global-styles/typography-panel.js +73 -12
  23. package/build/components/global-styles/typography-panel.js.map +1 -1
  24. package/build/components/global-styles/typography-utils.js +217 -0
  25. package/build/components/global-styles/typography-utils.js.map +1 -0
  26. package/build/components/global-styles/ui.js +11 -0
  27. package/build/components/global-styles/ui.js.map +1 -1
  28. package/build/components/global-styles/use-global-styles-output.js +61 -40
  29. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  30. package/build/components/global-styles/utils.js +17 -2
  31. package/build/components/global-styles/utils.js.map +1 -1
  32. package/build/components/header/index.js +15 -4
  33. package/build/components/header/index.js.map +1 -1
  34. package/build/components/header/undo-redo/redo.js +2 -1
  35. package/build/components/header/undo-redo/redo.js.map +1 -1
  36. package/build/components/list/actions/index.js +1 -1
  37. package/build/components/list/actions/index.js.map +1 -1
  38. package/build/components/save-button/index.js +2 -3
  39. package/build/components/save-button/index.js.map +1 -1
  40. package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js +2 -2
  41. package/build/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -1
  42. package/build/components/sidebar/template-card/template-actions.js +1 -1
  43. package/build/components/sidebar/template-card/template-actions.js.map +1 -1
  44. package/build/components/template-details/index.js +1 -1
  45. package/build/components/template-details/index.js.map +1 -1
  46. package/build/components/template-details/template-areas.js +1 -1
  47. package/build/components/template-details/template-areas.js.map +1 -1
  48. package/build/components/template-part-converter/convert-to-template-part.js +4 -1
  49. package/build/components/template-part-converter/convert-to-template-part.js.map +1 -1
  50. package/build-module/components/add-new-template/add-custom-template-modal.js +4 -2
  51. package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -1
  52. package/build-module/components/add-new-template/new-template.js +21 -3
  53. package/build-module/components/add-new-template/new-template.js.map +1 -1
  54. package/build-module/components/add-new-template/utils.js +147 -26
  55. package/build-module/components/add-new-template/utils.js.map +1 -1
  56. package/build-module/components/global-styles/dimensions-panel.js +6 -2
  57. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  58. package/build-module/components/global-styles/hooks.js +1 -1
  59. package/build-module/components/global-styles/hooks.js.map +1 -1
  60. package/build-module/components/global-styles/screen-color-palette.js +1 -1
  61. package/build-module/components/global-styles/screen-color-palette.js.map +1 -1
  62. package/build-module/components/global-styles/screen-colors.js +51 -7
  63. package/build-module/components/global-styles/screen-colors.js.map +1 -1
  64. package/build-module/components/global-styles/screen-heading-color.js +143 -0
  65. package/build-module/components/global-styles/screen-heading-color.js.map +1 -0
  66. package/build-module/components/global-styles/screen-typography-element.js +4 -0
  67. package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
  68. package/build-module/components/global-styles/screen-typography.js +5 -0
  69. package/build-module/components/global-styles/screen-typography.js.map +1 -1
  70. package/build-module/components/global-styles/typography-panel.js +74 -13
  71. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  72. package/build-module/components/global-styles/typography-utils.js +204 -0
  73. package/build-module/components/global-styles/typography-utils.js.map +1 -0
  74. package/build-module/components/global-styles/ui.js +10 -0
  75. package/build-module/components/global-styles/ui.js.map +1 -1
  76. package/build-module/components/global-styles/use-global-styles-output.js +61 -44
  77. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  78. package/build-module/components/global-styles/utils.js +16 -2
  79. package/build-module/components/global-styles/utils.js.map +1 -1
  80. package/build-module/components/header/index.js +17 -6
  81. package/build-module/components/header/index.js.map +1 -1
  82. package/build-module/components/header/undo-redo/redo.js +3 -2
  83. package/build-module/components/header/undo-redo/redo.js.map +1 -1
  84. package/build-module/components/list/actions/index.js +1 -1
  85. package/build-module/components/list/actions/index.js.map +1 -1
  86. package/build-module/components/save-button/index.js +3 -4
  87. package/build-module/components/save-button/index.js.map +1 -1
  88. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js +3 -3
  89. package/build-module/components/sidebar/navigation-menu-sidebar/navigation-menu.js.map +1 -1
  90. package/build-module/components/sidebar/template-card/template-actions.js +1 -1
  91. package/build-module/components/sidebar/template-card/template-actions.js.map +1 -1
  92. package/build-module/components/template-details/index.js +1 -1
  93. package/build-module/components/template-details/index.js.map +1 -1
  94. package/build-module/components/template-details/template-areas.js +1 -1
  95. package/build-module/components/template-details/template-areas.js.map +1 -1
  96. package/build-module/components/template-part-converter/convert-to-template-part.js +3 -1
  97. package/build-module/components/template-part-converter/convert-to-template-part.js.map +1 -1
  98. package/build-style/style-rtl.css +13 -4
  99. package/build-style/style.css +13 -4
  100. package/package.json +29 -29
  101. package/src/components/add-new-template/add-custom-template-modal.js +12 -3
  102. package/src/components/add-new-template/new-template.js +40 -20
  103. package/src/components/add-new-template/utils.js +145 -16
  104. package/src/components/global-styles/dimensions-panel.js +5 -3
  105. package/src/components/global-styles/hooks.js +1 -0
  106. package/src/components/global-styles/screen-color-palette.js +1 -1
  107. package/src/components/global-styles/screen-colors.js +46 -4
  108. package/src/components/global-styles/screen-heading-color.js +201 -0
  109. package/src/components/global-styles/screen-typography-element.js +4 -0
  110. package/src/components/global-styles/screen-typography.js +6 -0
  111. package/src/components/global-styles/style.scss +13 -6
  112. package/src/components/global-styles/test/typography-utils.js +130 -0
  113. package/src/components/global-styles/test/use-global-styles-output.js +66 -3
  114. package/src/components/global-styles/typography-panel.js +85 -16
  115. package/src/components/global-styles/typography-utils.js +228 -0
  116. package/src/components/global-styles/ui.js +13 -0
  117. package/src/components/global-styles/use-global-styles-output.js +79 -48
  118. package/src/components/global-styles/utils.js +10 -0
  119. package/src/components/header/index.js +28 -3
  120. package/src/components/header/undo-redo/redo.js +6 -2
  121. package/src/components/list/actions/index.js +3 -1
  122. package/src/components/save-button/index.js +10 -13
  123. package/src/components/sidebar/navigation-menu-sidebar/navigation-menu.js +1 -5
  124. package/src/components/sidebar/template-card/template-actions.js +3 -1
  125. package/src/components/template-details/index.js +3 -1
  126. package/src/components/template-details/template-areas.js +3 -1
  127. package/src/components/template-part-converter/convert-to-template-part.js +3 -1
@@ -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,11 @@
21
21
  border-radius: $radius-block-ui;
22
22
  }
23
23
 
24
+ .edit-site-typography-panel__half-width-control {
25
+ width: calc((100% - #{$grid-unit-30}) / 2);
26
+ }
27
+
28
+ .edit-site-global-styles-screen-heading-color,
24
29
  .edit-site-global-styles-screen-typography {
25
30
  margin: $grid-unit-20;
26
31
  }
@@ -41,6 +46,7 @@
41
46
  .component-color-indicator {
42
47
  // Show a diagonal line (crossed out) for empty swatches.
43
48
  background: linear-gradient(-45deg, transparent 48%, $gray-300 48%, $gray-300 52%, transparent 52%);
49
+ flex-shrink: 0;
44
50
  }
45
51
  }
46
52
 
@@ -72,12 +78,6 @@
72
78
  padding: $grid-unit-20;
73
79
  }
74
80
 
75
- .edit-site-screen-background-color__control {
76
- .block-editor-color-gradient-control__tab-panel {
77
- padding: $grid-unit-20;
78
- }
79
- }
80
-
81
81
  .edit-site-global-styles-variations_item {
82
82
  box-sizing: border-box;
83
83
 
@@ -107,4 +107,11 @@
107
107
  .edit-site-global-styles__color-indicator-wrapper {
108
108
  // Match the height of the rest of the icons (24px).
109
109
  height: $grid-unit * 3;
110
+ flex-shrink: 0;
111
+ }
112
+
113
+ .edit-site-global-styles__color-label {
114
+ white-space: nowrap;
115
+ overflow: hidden;
116
+ text-overflow: ellipsis;
110
117
  }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { getTypographyFontSizeValue } from '../typography-utils';
5
+
6
+ describe( 'typography utils', () => {
7
+ describe( 'getTypographyFontSizeValue', () => {
8
+ it( 'should return the expected values', () => {
9
+ [
10
+ // Default return non-fluid value.
11
+ {
12
+ preset: {
13
+ size: '28px',
14
+ },
15
+ typographySettings: undefined,
16
+ expected: '28px',
17
+ },
18
+ // Should return non-fluid value when fluid is `false`.
19
+ {
20
+ preset: {
21
+ size: '28px',
22
+ fluid: false,
23
+ },
24
+ typographySettings: {
25
+ fluid: true,
26
+ },
27
+ expected: '28px',
28
+ },
29
+ // Should return fluid value.
30
+ {
31
+ preset: {
32
+ size: '1.75rem',
33
+ },
34
+ typographySettings: {
35
+ fluid: true,
36
+ },
37
+ expected:
38
+ 'clamp(1.3125rem, 1.3125rem + ((1vw - 0.48rem) * 2.524), 2.625rem)',
39
+ },
40
+ // Should return default fluid values with empty fluid array.
41
+ {
42
+ preset: {
43
+ size: '28px',
44
+ fluid: [],
45
+ },
46
+ typographySettings: {
47
+ fluid: true,
48
+ },
49
+ expected:
50
+ 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 2.524), 42px)',
51
+ },
52
+
53
+ // Should return default fluid values with null values.
54
+ {
55
+ preset: {
56
+ size: '28px',
57
+ fluid: null,
58
+ },
59
+ typographySettings: {
60
+ fluid: true,
61
+ },
62
+ expected:
63
+ 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 2.524), 42px)',
64
+ },
65
+
66
+ // Should return size with invalid fluid units.
67
+ {
68
+ preset: {
69
+ size: '10em',
70
+ fluid: {
71
+ min: '20vw',
72
+ max: '50%',
73
+ },
74
+ },
75
+ typographySettings: {
76
+ fluid: true,
77
+ },
78
+ expected: '10em',
79
+ },
80
+ // Should return fluid clamp value.
81
+ {
82
+ preset: {
83
+ size: '28px',
84
+ fluid: {
85
+ min: '20px',
86
+ max: '50rem',
87
+ },
88
+ },
89
+ typographySettings: {
90
+ fluid: true,
91
+ },
92
+ expected:
93
+ 'clamp(20px, 1.25rem + ((1vw - 7.68px) * 93.75), 50rem)',
94
+ },
95
+ // Should return clamp value with default fluid max value.
96
+ {
97
+ preset: {
98
+ size: '28px',
99
+ fluid: {
100
+ min: '2.6rem',
101
+ },
102
+ },
103
+ typographySettings: {
104
+ fluid: true,
105
+ },
106
+ expected:
107
+ 'clamp(2.6rem, 2.6rem + ((1vw - 0.48rem) * 0.048), 42px)',
108
+ },
109
+ // Should return clamp value with default fluid min value.
110
+ {
111
+ preset: {
112
+ size: '28px',
113
+ fluid: {
114
+ max: '80px',
115
+ },
116
+ },
117
+ typographySettings: {
118
+ fluid: true,
119
+ },
120
+ expected:
121
+ 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 7.091), 80px)',
122
+ },
123
+ ].forEach( ( { preset, typographySettings, expected } ) => {
124
+ expect(
125
+ getTypographyFontSizeValue( preset, typographySettings )
126
+ ).toBe( expected );
127
+ } );
128
+ } );
129
+ } );
130
+ } );
@@ -13,6 +13,7 @@ import {
13
13
  getBlockSelectors,
14
14
  toCustomProperties,
15
15
  toStyles,
16
+ getStylesDeclarations,
16
17
  } from '../use-global-styles-output';
17
18
  import { ROOT_BLOCK_SELECTOR } from '../utils';
18
19
 
@@ -478,7 +479,7 @@ describe( 'global styles renderer', () => {
478
479
 
479
480
  expect( toStyles( tree, blockSelectors ) ).toEqual(
480
481
  'body {margin: 0;}' +
481
- 'body{background-color: red;margin: 10px;padding: 10px;}h1{font-size: 42px;}a{color: blue;}a:hover{color: orange;}a:focus{color: orange;}.wp-block-group{margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}h1,h2,h3,h4,h5,h6{color: orange;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color: hotpink;}h1 a:hover,h2 a:hover,h3 a:hover,h4 a:hover,h5 a:hover,h6 a:hover{color: red;}h1 a:focus,h2 a:focus,h3 a:focus,h4 a:focus,h5 a:focus,h6 a:focus{color: red;}' +
482
+ 'body{background-color: red;margin: 10px;padding: 10px;}a{color: blue;}a:hover{color: orange;}a:focus{color: orange;}h1{font-size: 42px;}.wp-block-group{margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}h1,h2,h3,h4,h5,h6{color: orange;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color: hotpink;}h1 a:hover,h2 a:hover,h3 a:hover,h4 a:hover,h5 a:hover,h6 a:hover{color: red;}h1 a:focus,h2 a:focus,h3 a:focus,h4 a:focus,h5 a:focus,h6 a:focus{color: red;}' +
482
483
  '.wp-block-image img, .wp-block-image .wp-crop-area{border-radius: 9999px }.wp-block-image{color: red;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }' +
483
484
  '.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}'
484
485
  );
@@ -582,7 +583,7 @@ describe( 'global styles renderer', () => {
582
583
  } );
583
584
 
584
585
  expect( layoutStyles ).toEqual(
585
- 'body .is-layout-flex { gap: 0.5em; }body .is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }body .is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }body .is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }body .is-layout-flex { display:flex; }body .is-layout-flex { flex-wrap: wrap; align-items: center; }body .is-layout-flex > * { margin: 0; }'
586
+ ':where(.is-layout-flex) { gap: 0.5em; }body .is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }body .is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }body .is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }body .is-layout-flex { display:flex; }body .is-layout-flex { flex-wrap: wrap; align-items: center; }body .is-layout-flex > * { margin: 0; }'
586
587
  );
587
588
  } );
588
589
 
@@ -647,7 +648,7 @@ describe( 'global styles renderer', () => {
647
648
  } );
648
649
 
649
650
  expect( layoutStyles ).toEqual(
650
- '.wp-block-group.is-layout-flex { gap: 2em; }'
651
+ ':where(.wp-block-group.is-layout-flex) { gap: 2em; }'
651
652
  );
652
653
  } );
653
654
  } );
@@ -681,4 +682,66 @@ describe( 'global styles renderer', () => {
681
682
  } );
682
683
  } );
683
684
  } );
685
+
686
+ describe( 'getStylesDeclarations', () => {
687
+ const blockStyles = {
688
+ spacing: {
689
+ padding: {
690
+ top: '33px',
691
+ right: '33px',
692
+ bottom: '33px',
693
+ left: '33px',
694
+ },
695
+ },
696
+ color: {
697
+ background: 'var:preset|color|light-green-cyan',
698
+ },
699
+ typography: {
700
+ fontFamily: 'sans-serif',
701
+ },
702
+ };
703
+
704
+ it( 'Should output padding variables and other properties if useRootPaddingAwareAlignments is enabled', () => {
705
+ expect(
706
+ getStylesDeclarations( blockStyles, 'body', true )
707
+ ).toEqual( [
708
+ 'font-family: sans-serif',
709
+ '--wp--style--root--padding-top: 33px',
710
+ '--wp--style--root--padding-right: 33px',
711
+ '--wp--style--root--padding-bottom: 33px',
712
+ '--wp--style--root--padding-left: 33px',
713
+ 'background-color: var(--wp--preset--color--light-green-cyan)',
714
+ ] );
715
+ } );
716
+
717
+ it( 'Should output padding and other properties if useRootPaddingAwareAlignments is disabled', () => {
718
+ expect(
719
+ getStylesDeclarations( blockStyles, 'body', false )
720
+ ).toEqual( [
721
+ 'font-family: sans-serif',
722
+ 'background-color: var(--wp--preset--color--light-green-cyan)',
723
+ 'padding-top: 33px',
724
+ 'padding-right: 33px',
725
+ 'padding-bottom: 33px',
726
+ 'padding-left: 33px',
727
+ ] );
728
+ } );
729
+
730
+ it( 'Should not output padding variables if selector is not root', () => {
731
+ expect(
732
+ getStylesDeclarations(
733
+ blockStyles,
734
+ '.wp-block-button__link',
735
+ true
736
+ )
737
+ ).toEqual( [
738
+ 'font-family: sans-serif',
739
+ 'background-color: var(--wp--preset--color--light-green-cyan)',
740
+ 'padding-top: 33px',
741
+ 'padding-right: 33px',
742
+ 'padding-bottom: 33px',
743
+ 'padding-left: 33px',
744
+ ] );
745
+ } );
746
+ } );
684
747
  } );
@@ -11,8 +11,11 @@ import {
11
11
  PanelBody,
12
12
  FontSizePicker,
13
13
  __experimentalSpacer as Spacer,
14
+ __experimentalToggleGroupControl as ToggleGroupControl,
15
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
14
16
  } from '@wordpress/components';
15
-
17
+ import { __ } from '@wordpress/i18n';
18
+ import { useState } from '@wordpress/element';
16
19
  /**
17
20
  * Internal dependencies
18
21
  */
@@ -59,9 +62,14 @@ function useHasLetterSpacingControl( name ) {
59
62
  }
60
63
 
61
64
  export default function TypographyPanel( { name, element } ) {
65
+ const [ selectedLevel, setCurrentTab ] = useState( 'heading' );
62
66
  const supports = getSupportedGlobalStylesPanels( name );
63
- const prefix =
64
- element === 'text' || ! element ? '' : `elements.${ element }.`;
67
+ let prefix = '';
68
+ if ( element === 'heading' ) {
69
+ prefix = `elements.${ selectedLevel }.`;
70
+ } else if ( element && element !== 'text' ) {
71
+ prefix = `elements.${ element }.`;
72
+ }
65
73
  const [ fontSizes ] = useSetting( 'typography.fontSizes', name );
66
74
  const disableCustomFontSizes = ! useSetting(
67
75
  'typography.customFontSize',
@@ -78,6 +86,12 @@ export default function TypographyPanel( { name, element } ) {
78
86
  const hasAppearanceControl = useHasAppearanceControl( name );
79
87
  const hasLetterSpacingControl = useHasLetterSpacingControl( name );
80
88
 
89
+ /* Disable font size controls when the option to style all headings is selected. */
90
+ let hasFontSizeEnabled = supports.includes( 'fontSize' );
91
+ if ( element === 'heading' && selectedLevel === 'heading' ) {
92
+ hasFontSizeEnabled = false;
93
+ }
94
+
81
95
  const [ fontFamily, setFontFamily ] = useStyle(
82
96
  prefix + 'typography.fontFamily',
83
97
  name
@@ -130,30 +144,79 @@ export default function TypographyPanel( { name, element } ) {
130
144
  >
131
145
  Aa
132
146
  </div>
133
-
147
+ { element === 'heading' && (
148
+ <div>
149
+ <h4>{ __( 'Select heading level' ) }</h4>
150
+ <ToggleGroupControl
151
+ label={ __( 'Select heading level' ) }
152
+ hideLabelFromVision={ true }
153
+ value={ selectedLevel }
154
+ onChange={ setCurrentTab }
155
+ isBlock
156
+ size="__unstable-large"
157
+ >
158
+ <ToggleGroupControlOption
159
+ value="heading"
160
+ /* translators: 'All' refers to selecting all heading levels
161
+ and applying the same style to h1-h6. */
162
+ label={ __( 'All' ) }
163
+ />
164
+ <ToggleGroupControlOption
165
+ value="h1"
166
+ label={ __( 'H1' ) }
167
+ />
168
+ <ToggleGroupControlOption
169
+ value="h2"
170
+ label={ __( 'H2' ) }
171
+ />
172
+ <ToggleGroupControlOption
173
+ value="h3"
174
+ label={ __( 'H3' ) }
175
+ />
176
+ <ToggleGroupControlOption
177
+ value="h4"
178
+ label={ __( 'H4' ) }
179
+ />
180
+ <ToggleGroupControlOption
181
+ value="h5"
182
+ label={ __( 'H5' ) }
183
+ />
184
+ <ToggleGroupControlOption
185
+ value="h6"
186
+ label={ __( 'H6' ) }
187
+ />
188
+ </ToggleGroupControl>
189
+ </div>
190
+ ) }
134
191
  { supports.includes( 'fontFamily' ) && (
135
192
  <FontFamilyControl
136
193
  fontFamilies={ fontFamilies }
137
194
  value={ fontFamily }
138
195
  onChange={ setFontFamily }
196
+ size="__unstable-large"
139
197
  />
140
198
  ) }
141
- { supports.includes( 'fontSize' ) && (
199
+ { hasFontSizeEnabled && (
142
200
  <FontSizePicker
143
201
  value={ fontSize }
144
202
  onChange={ setFontSize }
145
203
  fontSizes={ fontSizes }
146
204
  disableCustomFontSizes={ disableCustomFontSizes }
205
+ size="__unstable-large"
147
206
  />
148
207
  ) }
149
208
  { hasLineHeightEnabled && (
150
- <Spacer marginBottom={ 6 }>
151
- <LineHeightControl
152
- __nextHasNoMarginBottom={ true }
153
- value={ lineHeight }
154
- onChange={ setLineHeight }
155
- />
156
- </Spacer>
209
+ <div className="edit-site-typography-panel__half-width-control">
210
+ <Spacer marginBottom={ 6 }>
211
+ <LineHeightControl
212
+ __nextHasNoMarginBottom={ true }
213
+ __unstableInputWidth="auto"
214
+ value={ lineHeight }
215
+ onChange={ setLineHeight }
216
+ size="__unstable-large"
217
+ />
218
+ </Spacer>
219
+ </div>
157
220
  ) }
158
221
  { hasAppearanceControl && (
159
222
  <FontAppearanceControl
@@ -170,13 +233,19 @@ export default function TypographyPanel( { name, element } ) {
170
233
  } }
171
234
  hasFontStyles={ hasFontStyles }
172
235
  hasFontWeights={ hasFontWeights }
236
+ size="__unstable-large"
237
+ __nextUnconstrainedWidth
173
238
  />
174
239
  ) }
175
240
  { hasLetterSpacingControl && (
176
- <LetterSpacingControl
177
- value={ letterSpacing }
178
- onChange={ setLetterSpacing }
179
- />
241
+ <div className="edit-site-typography-panel__half-width-control">
242
+ <LetterSpacingControl
243
+ value={ letterSpacing }
244
+ onChange={ setLetterSpacing }
245
+ size="__unstable-large"
246
+ __unstableInputWidth="auto"
247
+ />
248
+ </div>
180
249
  ) }
181
250
  </PanelBody>
182
251
  );