@wordpress/edit-site 4.8.0 → 4.11.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 (204) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/components/add-new-template/add-custom-generic-template-modal.js +84 -0
  3. package/build/components/add-new-template/add-custom-generic-template-modal.js.map +1 -0
  4. package/build/components/add-new-template/add-custom-template-modal.js +204 -0
  5. package/build/components/add-new-template/add-custom-template-modal.js.map +1 -0
  6. package/build/components/add-new-template/new-template.js +91 -33
  7. package/build/components/add-new-template/new-template.js.map +1 -1
  8. package/build/components/add-new-template/utils.js +532 -0
  9. package/build/components/add-new-template/utils.js.map +1 -0
  10. package/build/components/block-editor/index.js +1 -3
  11. package/build/components/block-editor/index.js.map +1 -1
  12. package/build/components/code-editor/index.js +17 -4
  13. package/build/components/code-editor/index.js.map +1 -1
  14. package/build/components/editor/index.js +16 -0
  15. package/build/components/editor/index.js.map +1 -1
  16. package/build/components/error-boundary/index.js +6 -0
  17. package/build/components/error-boundary/index.js.map +1 -1
  18. package/build/components/global-styles/context-menu.js +6 -3
  19. package/build/components/global-styles/context-menu.js.map +1 -1
  20. package/build/components/global-styles/dimensions-panel.js +185 -19
  21. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  22. package/build/components/global-styles/global-styles-provider.js +4 -2
  23. package/build/components/global-styles/global-styles-provider.js.map +1 -1
  24. package/build/components/global-styles/hooks.js +11 -2
  25. package/build/components/global-styles/hooks.js.map +1 -1
  26. package/build/components/global-styles/palette.js +2 -1
  27. package/build/components/global-styles/palette.js.map +1 -1
  28. package/build/components/global-styles/screen-block-list.js +4 -1
  29. package/build/components/global-styles/screen-block-list.js.map +1 -1
  30. package/build/components/global-styles/screen-button-color.js +80 -0
  31. package/build/components/global-styles/screen-button-color.js.map +1 -0
  32. package/build/components/global-styles/screen-color-palette.js +13 -17
  33. package/build/components/global-styles/screen-color-palette.js.map +1 -1
  34. package/build/components/global-styles/screen-colors.js +56 -8
  35. package/build/components/global-styles/screen-colors.js.map +1 -1
  36. package/build/components/global-styles/screen-link-color.js +48 -14
  37. package/build/components/global-styles/screen-link-color.js.map +1 -1
  38. package/build/components/global-styles/screen-root.js +4 -2
  39. package/build/components/global-styles/screen-root.js.map +1 -1
  40. package/build/components/global-styles/screen-typography-element.js +4 -0
  41. package/build/components/global-styles/screen-typography-element.js.map +1 -1
  42. package/build/components/global-styles/screen-typography.js +9 -1
  43. package/build/components/global-styles/screen-typography.js.map +1 -1
  44. package/build/components/global-styles/ui.js +11 -0
  45. package/build/components/global-styles/ui.js.map +1 -1
  46. package/build/components/global-styles/use-global-styles-output.js +282 -35
  47. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  48. package/build/components/global-styles/utils.js +35 -2
  49. package/build/components/global-styles/utils.js.map +1 -1
  50. package/build/components/header/index.js +29 -10
  51. package/build/components/header/index.js.map +1 -1
  52. package/build/components/header/more-menu/site-export.js +4 -1
  53. package/build/components/header/more-menu/site-export.js.map +1 -1
  54. package/build/components/header/undo-redo/redo.js +13 -4
  55. package/build/components/header/undo-redo/redo.js.map +1 -1
  56. package/build/components/header/undo-redo/undo.js +13 -4
  57. package/build/components/header/undo-redo/undo.js.map +1 -1
  58. package/build/components/keyboard-shortcut-help-modal/config.js +17 -0
  59. package/build/components/keyboard-shortcut-help-modal/config.js.map +1 -1
  60. package/build/components/keyboard-shortcut-help-modal/index.js +1 -3
  61. package/build/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  62. package/build/components/sidebar/template-card/index.js +19 -7
  63. package/build/components/sidebar/template-card/index.js.map +1 -1
  64. package/build/components/sidebar/template-card/template-actions.js +64 -0
  65. package/build/components/sidebar/template-card/template-actions.js.map +1 -0
  66. package/build/components/template-details/edit-template-title.js +11 -3
  67. package/build/components/template-details/edit-template-title.js.map +1 -1
  68. package/build/components/template-details/index.js +1 -20
  69. package/build/components/template-details/index.js.map +1 -1
  70. package/build/hooks/index.js +2 -0
  71. package/build/hooks/index.js.map +1 -1
  72. package/build/hooks/template-part-edit.js +86 -0
  73. package/build/hooks/template-part-edit.js.map +1 -0
  74. package/build/store/selectors.js +4 -1
  75. package/build/store/selectors.js.map +1 -1
  76. package/build-module/components/add-new-template/add-custom-generic-template-modal.js +77 -0
  77. package/build-module/components/add-new-template/add-custom-generic-template-modal.js.map +1 -0
  78. package/build-module/components/add-new-template/add-custom-template-modal.js +189 -0
  79. package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -0
  80. package/build-module/components/add-new-template/new-template.js +90 -34
  81. package/build-module/components/add-new-template/new-template.js.map +1 -1
  82. package/build-module/components/add-new-template/utils.js +503 -0
  83. package/build-module/components/add-new-template/utils.js.map +1 -0
  84. package/build-module/components/block-editor/index.js +1 -2
  85. package/build-module/components/block-editor/index.js.map +1 -1
  86. package/build-module/components/code-editor/index.js +18 -5
  87. package/build-module/components/code-editor/index.js.map +1 -1
  88. package/build-module/components/editor/index.js +16 -0
  89. package/build-module/components/editor/index.js.map +1 -1
  90. package/build-module/components/error-boundary/index.js +5 -0
  91. package/build-module/components/error-boundary/index.js.map +1 -1
  92. package/build-module/components/global-styles/context-menu.js +6 -3
  93. package/build-module/components/global-styles/context-menu.js.map +1 -1
  94. package/build-module/components/global-styles/dimensions-panel.js +185 -20
  95. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  96. package/build-module/components/global-styles/global-styles-provider.js +4 -2
  97. package/build-module/components/global-styles/global-styles-provider.js.map +1 -1
  98. package/build-module/components/global-styles/hooks.js +11 -2
  99. package/build-module/components/global-styles/hooks.js.map +1 -1
  100. package/build-module/components/global-styles/palette.js +2 -1
  101. package/build-module/components/global-styles/palette.js.map +1 -1
  102. package/build-module/components/global-styles/screen-block-list.js +4 -1
  103. package/build-module/components/global-styles/screen-block-list.js.map +1 -1
  104. package/build-module/components/global-styles/screen-button-color.js +67 -0
  105. package/build-module/components/global-styles/screen-button-color.js.map +1 -0
  106. package/build-module/components/global-styles/screen-color-palette.js +14 -19
  107. package/build-module/components/global-styles/screen-color-palette.js.map +1 -1
  108. package/build-module/components/global-styles/screen-colors.js +57 -9
  109. package/build-module/components/global-styles/screen-colors.js.map +1 -1
  110. package/build-module/components/global-styles/screen-link-color.js +47 -14
  111. package/build-module/components/global-styles/screen-link-color.js.map +1 -1
  112. package/build-module/components/global-styles/screen-root.js +4 -2
  113. package/build-module/components/global-styles/screen-root.js.map +1 -1
  114. package/build-module/components/global-styles/screen-typography-element.js +4 -0
  115. package/build-module/components/global-styles/screen-typography-element.js.map +1 -1
  116. package/build-module/components/global-styles/screen-typography.js +10 -2
  117. package/build-module/components/global-styles/screen-typography.js.map +1 -1
  118. package/build-module/components/global-styles/ui.js +10 -0
  119. package/build-module/components/global-styles/ui.js.map +1 -1
  120. package/build-module/components/global-styles/use-global-styles-output.js +280 -42
  121. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  122. package/build-module/components/global-styles/utils.js +34 -3
  123. package/build-module/components/global-styles/utils.js.map +1 -1
  124. package/build-module/components/header/index.js +31 -11
  125. package/build-module/components/header/index.js.map +1 -1
  126. package/build-module/components/header/more-menu/site-export.js +4 -1
  127. package/build-module/components/header/more-menu/site-export.js.map +1 -1
  128. package/build-module/components/header/undo-redo/redo.js +9 -3
  129. package/build-module/components/header/undo-redo/redo.js.map +1 -1
  130. package/build-module/components/header/undo-redo/undo.js +9 -3
  131. package/build-module/components/header/undo-redo/undo.js.map +1 -1
  132. package/build-module/components/keyboard-shortcut-help-modal/config.js +17 -0
  133. package/build-module/components/keyboard-shortcut-help-modal/config.js.map +1 -1
  134. package/build-module/components/keyboard-shortcut-help-modal/index.js +1 -2
  135. package/build-module/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  136. package/build-module/components/sidebar/template-card/index.js +18 -7
  137. package/build-module/components/sidebar/template-card/index.js.map +1 -1
  138. package/build-module/components/sidebar/template-card/template-actions.js +49 -0
  139. package/build-module/components/sidebar/template-card/template-actions.js.map +1 -0
  140. package/build-module/components/template-details/edit-template-title.js +12 -3
  141. package/build-module/components/template-details/edit-template-title.js.map +1 -1
  142. package/build-module/components/template-details/index.js +2 -21
  143. package/build-module/components/template-details/index.js.map +1 -1
  144. package/build-module/hooks/index.js +1 -0
  145. package/build-module/hooks/index.js.map +1 -1
  146. package/build-module/hooks/template-part-edit.js +67 -0
  147. package/build-module/hooks/template-part-edit.js.map +1 -0
  148. package/build-module/store/selectors.js +5 -2
  149. package/build-module/store/selectors.js.map +1 -1
  150. package/build-style/style-rtl.css +198 -49
  151. package/build-style/style.css +198 -49
  152. package/package.json +29 -29
  153. package/src/components/add-new-template/add-custom-generic-template-modal.js +97 -0
  154. package/src/components/add-new-template/add-custom-template-modal.js +247 -0
  155. package/src/components/add-new-template/new-template.js +158 -70
  156. package/src/components/add-new-template/style.scss +149 -0
  157. package/src/components/add-new-template/utils.js +538 -0
  158. package/src/components/block-editor/index.js +0 -2
  159. package/src/components/code-editor/index.js +15 -5
  160. package/src/components/editor/index.js +11 -0
  161. package/src/components/error-boundary/index.js +5 -0
  162. package/src/components/global-styles/context-menu.js +3 -0
  163. package/src/components/global-styles/dimensions-panel.js +209 -21
  164. package/src/components/global-styles/global-styles-provider.js +8 -9
  165. package/src/components/global-styles/hooks.js +18 -0
  166. package/src/components/global-styles/palette.js +4 -1
  167. package/src/components/global-styles/screen-block-list.js +10 -1
  168. package/src/components/global-styles/screen-button-color.js +102 -0
  169. package/src/components/global-styles/screen-color-palette.js +25 -27
  170. package/src/components/global-styles/screen-colors.js +58 -7
  171. package/src/components/global-styles/screen-link-color.js +65 -23
  172. package/src/components/global-styles/screen-root.js +8 -2
  173. package/src/components/global-styles/screen-typography-element.js +4 -0
  174. package/src/components/global-styles/screen-typography.js +17 -2
  175. package/src/components/global-styles/style.scss +14 -8
  176. package/src/components/global-styles/test/use-global-styles-output.js +313 -16
  177. package/src/components/global-styles/ui.js +13 -0
  178. package/src/components/global-styles/use-global-styles-output.js +344 -38
  179. package/src/components/global-styles/utils.js +36 -2
  180. package/src/components/header/index.js +42 -17
  181. package/src/components/header/more-menu/site-export.js +3 -0
  182. package/src/components/header/style.scss +58 -8
  183. package/src/components/header/undo-redo/redo.js +6 -1
  184. package/src/components/header/undo-redo/undo.js +6 -1
  185. package/src/components/keyboard-shortcut-help-modal/config.js +12 -0
  186. package/src/components/keyboard-shortcut-help-modal/index.js +1 -2
  187. package/src/components/keyboard-shortcut-help-modal/style.scss +0 -5
  188. package/src/components/list/style.scss +0 -8
  189. package/src/components/sidebar/style.scss +4 -0
  190. package/src/components/sidebar/template-card/index.js +15 -6
  191. package/src/components/sidebar/template-card/style.scss +49 -35
  192. package/src/components/sidebar/template-card/template-actions.js +43 -0
  193. package/src/components/template-details/edit-template-title.js +10 -2
  194. package/src/components/template-details/index.js +4 -21
  195. package/src/components/test/error-boundary.js +38 -0
  196. package/src/hooks/index.js +1 -0
  197. package/src/hooks/template-part-edit.js +82 -0
  198. package/src/store/selectors.js +11 -5
  199. package/src/style.scss +0 -1
  200. package/build/components/edit-template-part-menu-button/index.js +0 -90
  201. package/build/components/edit-template-part-menu-button/index.js.map +0 -1
  202. package/build-module/components/edit-template-part-menu-button/index.js +0 -72
  203. package/build-module/components/edit-template-part-menu-button/index.js.map +0 -1
  204. package/src/components/edit-template-part-menu-button/index.js +0 -82
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { __experimentalColorGradientControl as ColorGradientControl } from '@wordpress/block-editor';
6
-
6
+ import { TabPanel } from '@wordpress/components';
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
@@ -29,40 +29,82 @@ function ScreenLinkColor( { name } ) {
29
29
  isLinkEnabled &&
30
30
  ( solids.length > 0 || areCustomSolidsEnabled );
31
31
 
32
- const [ linkColor, setLinkColor ] = useStyle(
33
- 'elements.link.color.text',
34
- name
35
- );
36
- const [ userLinkColor ] = useStyle(
37
- 'elements.link.color.text',
38
- name,
39
- 'user'
40
- );
32
+ const pseudoStates = {
33
+ default: {
34
+ label: __( 'Default' ),
35
+ value: useStyle( 'elements.link.color.text', name )[ 0 ],
36
+ handler: useStyle( 'elements.link.color.text', name )[ 1 ],
37
+ userValue: useStyle(
38
+ 'elements.link.color.text',
39
+ name,
40
+ 'user'
41
+ )[ 0 ],
42
+ },
43
+ hover: {
44
+ label: __( 'Hover' ),
45
+ value: useStyle( 'elements.link.:hover.color.text', name )[ 0 ],
46
+ handler: useStyle( 'elements.link.:hover.color.text', name )[ 1 ],
47
+ userValue: useStyle(
48
+ 'elements.link.:hover.color.text',
49
+ name,
50
+ 'user'
51
+ )[ 0 ],
52
+ },
53
+ };
41
54
 
42
55
  if ( ! hasLinkColor ) {
43
56
  return null;
44
57
  }
45
58
 
59
+ const tabs = Object.entries( pseudoStates ).map(
60
+ ( [ selector, config ] ) => {
61
+ return {
62
+ name: selector,
63
+ title: config.label,
64
+ className: `color-text-${ selector }`,
65
+ };
66
+ }
67
+ );
68
+
46
69
  return (
47
70
  <>
48
71
  <ScreenHeader
49
72
  title={ __( 'Links' ) }
50
73
  description={ __(
51
- 'Set the default color used for links across the site.'
74
+ 'Set the colors used for links across the site.'
52
75
  ) }
53
76
  />
54
- <ColorGradientControl
55
- className="edit-site-screen-link-color__control"
56
- colors={ colorsPerOrigin }
57
- disableCustomColors={ ! areCustomSolidsEnabled }
58
- __experimentalHasMultipleOrigins
59
- showTitle={ false }
60
- enableAlpha
61
- __experimentalIsRenderedInSidebar
62
- colorValue={ linkColor }
63
- onColorChange={ setLinkColor }
64
- clearable={ linkColor === userLinkColor }
65
- />
77
+
78
+ <TabPanel tabs={ tabs }>
79
+ { ( tab ) => {
80
+ const pseudoSelectorConfig =
81
+ pseudoStates[ tab.name ] ?? null;
82
+
83
+ if ( ! pseudoSelectorConfig ) {
84
+ return null;
85
+ }
86
+
87
+ return (
88
+ <>
89
+ <ColorGradientControl
90
+ className="edit-site-screen-link-color__control"
91
+ colors={ colorsPerOrigin }
92
+ disableCustomColors={ ! areCustomSolidsEnabled }
93
+ __experimentalHasMultipleOrigins
94
+ showTitle={ false }
95
+ enableAlpha
96
+ __experimentalIsRenderedInSidebar
97
+ colorValue={ pseudoSelectorConfig.value }
98
+ onColorChange={ pseudoSelectorConfig.handler }
99
+ clearable={
100
+ pseudoSelectorConfig.value ===
101
+ pseudoSelectorConfig.userValue
102
+ }
103
+ />
104
+ </>
105
+ );
106
+ } }
107
+ </TabPanel>
66
108
  </>
67
109
  );
68
110
  }
@@ -46,7 +46,10 @@ function ScreenRoot() {
46
46
  </Card>
47
47
  { !! variations?.length && (
48
48
  <ItemGroup>
49
- <NavigationButtonAsItem path="/variations">
49
+ <NavigationButtonAsItem
50
+ path="/variations"
51
+ aria-label={ __( 'Browse styles' ) }
52
+ >
50
53
  <HStack justify="space-between">
51
54
  <FlexItem>
52
55
  { __( 'Browse styles' ) }
@@ -82,7 +85,10 @@ function ScreenRoot() {
82
85
  ) }
83
86
  </Spacer>
84
87
  <ItemGroup>
85
- <NavigationButtonAsItem path="/blocks">
88
+ <NavigationButtonAsItem
89
+ path="/blocks"
90
+ aria-label={ __( 'Blocks styles' ) }
91
+ >
86
92
  <HStack justify="space-between">
87
93
  <FlexItem>{ __( 'Blocks' ) }</FlexItem>
88
94
  <IconWithCurrentColor
@@ -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
+ button: {
22
+ description: __( 'Manage the fonts and typography used on buttons.' ),
23
+ title: __( 'Buttons' ),
24
+ },
21
25
  };
22
26
 
23
27
  function ScreenTypographyElement( { name, element } ) {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { __ } from '@wordpress/i18n';
4
+ import { __, sprintf } from '@wordpress/i18n';
5
5
  import {
6
6
  __experimentalItemGroup as ItemGroup,
7
7
  __experimentalVStack as VStack,
@@ -43,8 +43,17 @@ function Item( { name, parentMenu, element, label } ) {
43
43
  return null;
44
44
  }
45
45
 
46
+ const navigationButtonLabel = sprintf(
47
+ // translators: %s: is a subset of Typography, e.g., 'text' or 'links'.
48
+ __( 'Typography %s styles' ),
49
+ label
50
+ );
51
+
46
52
  return (
47
- <NavigationButtonAsItem path={ parentMenu + '/typography/' + element }>
53
+ <NavigationButtonAsItem
54
+ path={ parentMenu + '/typography/' + element }
55
+ aria-label={ navigationButtonLabel }
56
+ >
48
57
  <HStack justify="flex-start">
49
58
  <FlexItem
50
59
  className="edit-site-global-styles-screen-typography__indicator"
@@ -95,6 +104,12 @@ function ScreenTypography( { name } ) {
95
104
  element="link"
96
105
  label={ __( 'Links' ) }
97
106
  />
107
+ <Item
108
+ name={ name }
109
+ parentMenu={ parentMenu }
110
+ element="button"
111
+ label={ __( 'Buttons' ) }
112
+ />
98
113
  </ItemGroup>
99
114
  </VStack>
100
115
  </div>
@@ -57,21 +57,27 @@
57
57
  font-size: 11px !important;
58
58
  }
59
59
 
60
- .edit-site-screen-color-palette-toggle.edit-site-screen-color-palette-toggle {
61
- margin-right: $grid-unit-20;
62
- margin-left: $grid-unit-20;
63
- width: unset;
64
- .components-toggle-group-control {
65
- min-height: $grid-unit-40;
66
- }
60
+ .edit-site-global-styles-section-title {
61
+ color: $gray-800;
62
+ font-weight: 600;
63
+ line-height: 1.2;
64
+ padding: $grid-unit-20;
65
+ padding-bottom: 0;
66
+ margin: 0;
67
67
  }
68
68
 
69
69
  .edit-site-screen-text-color__control,
70
70
  .edit-site-screen-link-color__control,
71
- .edit-site-screen-background-color__control {
71
+ .edit-site-screen-button-color__control {
72
72
  padding: $grid-unit-20;
73
73
  }
74
74
 
75
+ .edit-site-screen-background-color__control {
76
+ .block-editor-color-gradient-control__tab-panel {
77
+ padding: $grid-unit-20;
78
+ }
79
+ }
80
+
75
81
  .edit-site-global-styles-variations_item {
76
82
  box-sizing: border-box;
77
83
 
@@ -7,8 +7,10 @@ import { __EXPERIMENTAL_ELEMENTS as ELEMENTS } from '@wordpress/blocks';
7
7
  * Internal dependencies
8
8
  */
9
9
  import {
10
+ getLayoutStyles,
10
11
  getNodesWithSettings,
11
12
  getNodesWithStyles,
13
+ getBlockSelectors,
12
14
  toCustomProperties,
13
15
  toStyles,
14
16
  } from '../use-global-styles-output';
@@ -40,6 +42,25 @@ describe( 'global styles renderer', () => {
40
42
  fontSize: '23px',
41
43
  },
42
44
  },
45
+ link: {
46
+ ':hover': {
47
+ color: {
48
+ background: 'green',
49
+ text: 'yellow',
50
+ },
51
+ },
52
+ ':focus': {
53
+ color: {
54
+ background: 'green',
55
+ text: 'yellow',
56
+ },
57
+ },
58
+ },
59
+ },
60
+ },
61
+ 'core/image': {
62
+ border: {
63
+ radius: '9999px',
43
64
  },
44
65
  },
45
66
  },
@@ -49,6 +70,18 @@ describe( 'global styles renderer', () => {
49
70
  background: 'yellow',
50
71
  text: 'yellow',
51
72
  },
73
+ ':hover': {
74
+ color: {
75
+ background: 'hotpink',
76
+ text: 'black',
77
+ },
78
+ },
79
+ ':focus': {
80
+ color: {
81
+ background: 'hotpink',
82
+ text: 'black',
83
+ },
84
+ },
52
85
  },
53
86
  },
54
87
  },
@@ -57,7 +90,12 @@ describe( 'global styles renderer', () => {
57
90
  'core/heading': {
58
91
  selector: '.my-heading1, .my-heading2',
59
92
  },
93
+ 'core/image': {
94
+ selector: '.my-image',
95
+ featureSelectors: '.my-image img, .my-image .crop-area',
96
+ },
60
97
  };
98
+
61
99
  expect( getNodesWithStyles( tree, blockSelectors ) ).toEqual( [
62
100
  {
63
101
  styles: {
@@ -74,6 +112,18 @@ describe( 'global styles renderer', () => {
74
112
  background: 'yellow',
75
113
  text: 'yellow',
76
114
  },
115
+ ':hover': {
116
+ color: {
117
+ background: 'hotpink',
118
+ text: 'black',
119
+ },
120
+ },
121
+ ':focus': {
122
+ color: {
123
+ background: 'hotpink',
124
+ text: 'black',
125
+ },
126
+ },
77
127
  },
78
128
  selector: ELEMENTS.link,
79
129
  },
@@ -102,6 +152,32 @@ describe( 'global styles renderer', () => {
102
152
  },
103
153
  selector: '.my-heading1 h2, .my-heading2 h2',
104
154
  },
155
+ {
156
+ styles: {
157
+ ':hover': {
158
+ color: {
159
+ background: 'green',
160
+ text: 'yellow',
161
+ },
162
+ },
163
+ ':focus': {
164
+ color: {
165
+ background: 'green',
166
+ text: 'yellow',
167
+ },
168
+ },
169
+ },
170
+ selector: '.my-heading1 a, .my-heading2 a',
171
+ },
172
+ {
173
+ styles: {
174
+ border: {
175
+ radius: '9999px',
176
+ },
177
+ },
178
+ selector: '.my-image',
179
+ featureSelectors: '.my-image img, .my-image .crop-area',
180
+ },
105
181
  ] );
106
182
  } );
107
183
  } );
@@ -318,6 +394,21 @@ describe( 'global styles renderer', () => {
318
394
  fontSize: '42px',
319
395
  },
320
396
  },
397
+ link: {
398
+ color: {
399
+ text: 'blue',
400
+ },
401
+ ':hover': {
402
+ color: {
403
+ text: 'orange',
404
+ },
405
+ },
406
+ ':focus': {
407
+ color: {
408
+ text: 'orange',
409
+ },
410
+ },
411
+ },
321
412
  },
322
413
  blocks: {
323
414
  'core/group': {
@@ -345,9 +436,27 @@ describe( 'global styles renderer', () => {
345
436
  color: {
346
437
  text: 'hotpink',
347
438
  },
439
+ ':hover': {
440
+ color: {
441
+ text: 'red',
442
+ },
443
+ },
444
+ ':focus': {
445
+ color: {
446
+ text: 'red',
447
+ },
448
+ },
348
449
  },
349
450
  },
350
451
  },
452
+ 'core/image': {
453
+ color: {
454
+ text: 'red',
455
+ },
456
+ border: {
457
+ radius: '9999px',
458
+ },
459
+ },
351
460
  },
352
461
  },
353
462
  };
@@ -358,30 +467,218 @@ describe( 'global styles renderer', () => {
358
467
  },
359
468
  'core/heading': {
360
469
  selector: 'h1,h2,h3,h4,h5,h6',
361
- elements: {
362
- link:
363
- 'h1 ' +
364
- ELEMENTS.link +
365
- ',h2 ' +
366
- ELEMENTS.link +
367
- ',h3 ' +
368
- ELEMENTS.link +
369
- ',h4 ' +
370
- ELEMENTS.link +
371
- ',h5 ' +
372
- ELEMENTS.link +
373
- ',h6 ' +
374
- ELEMENTS.link,
470
+ },
471
+ 'core/image': {
472
+ selector: '.wp-block-image',
473
+ featureSelectors: {
474
+ border: '.wp-block-image img, .wp-block-image .wp-crop-area',
375
475
  },
376
476
  },
377
477
  };
378
478
 
379
479
  expect( toStyles( tree, blockSelectors ) ).toEqual(
380
480
  'body {margin: 0;}' +
381
- 'body{background-color: red;margin: 10px;padding: 10px;}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;}' +
382
- '.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; }' +
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
+ '.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; }' +
383
483
  '.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;}'
384
484
  );
385
485
  } );
386
486
  } );
487
+
488
+ describe( 'getLayoutStyles', () => {
489
+ const layoutDefinitionsTree = {
490
+ settings: {
491
+ layout: {
492
+ definitions: {
493
+ default: {
494
+ name: 'default',
495
+ slug: 'flow',
496
+ className: 'is-layout-flow',
497
+ baseStyles: [
498
+ {
499
+ selector: ' > .alignleft',
500
+ rules: {
501
+ float: 'left',
502
+ 'margin-inline-start': '0',
503
+ 'margin-inline-end': '2em',
504
+ },
505
+ },
506
+ {
507
+ selector: ' > .alignright',
508
+ rules: {
509
+ float: 'right',
510
+ 'margin-inline-start': '2em',
511
+ 'margin-inline-end': '0',
512
+ },
513
+ },
514
+ {
515
+ selector: ' > .aligncenter',
516
+ rules: {
517
+ 'margin-left': 'auto !important',
518
+ 'margin-right': 'auto !important',
519
+ },
520
+ },
521
+ ],
522
+ spacingStyles: [
523
+ {
524
+ selector: ' > *',
525
+ rules: {
526
+ 'margin-block-start': '0',
527
+ 'margin-block-end': '0',
528
+ },
529
+ },
530
+ {
531
+ selector: ' > * + *',
532
+ rules: {
533
+ 'margin-block-start': null,
534
+ 'margin-block-end': '0',
535
+ },
536
+ },
537
+ ],
538
+ },
539
+ flex: {
540
+ name: 'flex',
541
+ slug: 'flex',
542
+ className: 'is-layout-flex',
543
+ displayMode: 'flex',
544
+ baseStyles: [
545
+ {
546
+ selector: '',
547
+ rules: {
548
+ 'flex-wrap': 'wrap',
549
+ 'align-items': 'center',
550
+ },
551
+ },
552
+ {
553
+ selector: ' > *',
554
+ rules: {
555
+ margin: '0',
556
+ },
557
+ },
558
+ ],
559
+ spacingStyles: [
560
+ {
561
+ selector: '',
562
+ rules: {
563
+ gap: null,
564
+ },
565
+ },
566
+ ],
567
+ },
568
+ },
569
+ },
570
+ },
571
+ };
572
+
573
+ it( 'should return fallback gap flex layout style, and all base styles, if block styles are enabled and blockGap is disabled', () => {
574
+ const style = { spacing: { blockGap: '12px' } };
575
+
576
+ const layoutStyles = getLayoutStyles( {
577
+ tree: layoutDefinitionsTree,
578
+ style,
579
+ selector: 'body',
580
+ hasBlockGapSupport: false,
581
+ hasFallbackGapSupport: true,
582
+ } );
583
+
584
+ 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
+ );
587
+ } );
588
+
589
+ it( 'should return fallback gap layout styles, and base styles, if blockGap is enabled, but there is no blockGap value', () => {
590
+ const style = {};
591
+
592
+ const layoutStyles = getLayoutStyles( {
593
+ tree: layoutDefinitionsTree,
594
+ style,
595
+ selector: 'body',
596
+ hasBlockGapSupport: true,
597
+ hasFallbackGapSupport: true,
598
+ } );
599
+
600
+ expect( layoutStyles ).toEqual(
601
+ 'body .is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }body .is-layout-flow > * + * { margin-block-start: 0.5em; margin-block-end: 0; }body .is-layout-flex { gap: 0.5em; }body { --wp--style--block-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; }'
602
+ );
603
+ } );
604
+
605
+ it( 'should return real gap layout style if blockGap is enabled, and base styles', () => {
606
+ const style = { spacing: { blockGap: '12px' } };
607
+
608
+ const layoutStyles = getLayoutStyles( {
609
+ tree: layoutDefinitionsTree,
610
+ style,
611
+ selector: 'body',
612
+ hasBlockGapSupport: true,
613
+ hasFallbackGapSupport: true,
614
+ } );
615
+
616
+ expect( layoutStyles ).toEqual(
617
+ 'body .is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }body .is-layout-flow > * + * { margin-block-start: 12px; margin-block-end: 0; }body .is-layout-flex { gap: 12px; }body { --wp--style--block-gap: 12px; }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; }'
618
+ );
619
+ } );
620
+
621
+ it( 'should return real gap layout style if blockGap is enabled', () => {
622
+ const style = { spacing: { blockGap: '12px' } };
623
+
624
+ const layoutStyles = getLayoutStyles( {
625
+ tree: layoutDefinitionsTree,
626
+ style,
627
+ selector: '.wp-block-group',
628
+ hasBlockGapSupport: true,
629
+ hasFallbackGapSupport: true,
630
+ } );
631
+
632
+ expect( layoutStyles ).toEqual(
633
+ '.wp-block-group.is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }.wp-block-group.is-layout-flow > * + * { margin-block-start: 12px; margin-block-end: 0; }.wp-block-group.is-layout-flex { gap: 12px; }'
634
+ );
635
+ } );
636
+
637
+ it( 'should return fallback gap flex layout style for a block if blockGap is disabled, and a fallback value is provided', () => {
638
+ const style = { spacing: { blockGap: '12px' } };
639
+
640
+ const layoutStyles = getLayoutStyles( {
641
+ tree: layoutDefinitionsTree,
642
+ style,
643
+ selector: '.wp-block-group',
644
+ hasBlockGapSupport: false, // This means that the fallback value will be used instead of the "real" one.
645
+ hasFallbackGapSupport: true,
646
+ fallbackGapValue: '2em',
647
+ } );
648
+
649
+ expect( layoutStyles ).toEqual(
650
+ '.wp-block-group.is-layout-flex { gap: 2em; }'
651
+ );
652
+ } );
653
+ } );
654
+
655
+ describe( 'getBlockSelectors', () => {
656
+ it( 'should return block selectors data', () => {
657
+ const imageSupports = {
658
+ __experimentalBorder: {
659
+ radius: true,
660
+ __experimentalSelector: 'img, .crop-area',
661
+ },
662
+ color: {
663
+ __experimentalDuotone: 'img',
664
+ },
665
+ __experimentalSelector: '.my-image',
666
+ };
667
+ const imageBlock = { name: 'core/image', supports: imageSupports };
668
+ const blockTypes = [ imageBlock ];
669
+
670
+ expect( getBlockSelectors( blockTypes ) ).toEqual( {
671
+ 'core/image': {
672
+ name: imageBlock.name,
673
+ selector: imageSupports.__experimentalSelector,
674
+ duotoneSelector: imageSupports.color.__experimentalDuotone,
675
+ fallbackGapValue: undefined,
676
+ featureSelectors: {
677
+ border: '.my-image img, .my-image .crop-area',
678
+ },
679
+ hasLayoutSupport: false,
680
+ },
681
+ } );
682
+ } );
683
+ } );
387
684
  } );
@@ -20,6 +20,7 @@ import ScreenColorPalette from './screen-color-palette';
20
20
  import ScreenBackgroundColor from './screen-background-color';
21
21
  import ScreenTextColor from './screen-text-color';
22
22
  import ScreenLinkColor from './screen-link-color';
23
+ import ScreenButtonColor from './screen-button-color';
23
24
  import ScreenLayout from './screen-layout';
24
25
  import ScreenStyleVariations from './screen-style-variations';
25
26
 
@@ -58,6 +59,12 @@ function ContextScreens( { name } ) {
58
59
  <ScreenTypographyElement name={ name } element="link" />
59
60
  </GlobalStylesNavigationScreen>
60
61
 
62
+ <GlobalStylesNavigationScreen
63
+ path={ parentMenu + '/typography/button' }
64
+ >
65
+ <ScreenTypographyElement name={ name } element="button" />
66
+ </GlobalStylesNavigationScreen>
67
+
61
68
  <GlobalStylesNavigationScreen path={ parentMenu + '/colors' }>
62
69
  <ScreenColors name={ name } />
63
70
  </GlobalStylesNavigationScreen>
@@ -82,6 +89,12 @@ function ContextScreens( { name } ) {
82
89
  <ScreenLinkColor name={ name } />
83
90
  </GlobalStylesNavigationScreen>
84
91
 
92
+ <GlobalStylesNavigationScreen
93
+ path={ parentMenu + '/colors/button' }
94
+ >
95
+ <ScreenButtonColor name={ name } />
96
+ </GlobalStylesNavigationScreen>
97
+
85
98
  <GlobalStylesNavigationScreen path={ parentMenu + '/layout' }>
86
99
  <ScreenLayout name={ name } />
87
100
  </GlobalStylesNavigationScreen>