@wordpress/edit-site 6.14.0 → 6.15.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 (126) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/LICENSE.md +1 -1
  3. package/build/components/add-new-pattern/index.js +6 -10
  4. package/build/components/add-new-pattern/index.js.map +1 -1
  5. package/build/components/editor/index.js +1 -9
  6. package/build/components/editor/index.js.map +1 -1
  7. package/build/components/global-styles/confirm-reset-shadow-dialog.js +39 -0
  8. package/build/components/global-styles/confirm-reset-shadow-dialog.js.map +1 -0
  9. package/build/components/global-styles/font-library-modal/index.js +1 -1
  10. package/build/components/global-styles/font-library-modal/index.js.map +1 -1
  11. package/build/components/global-styles/font-sizes/font-size.js +17 -14
  12. package/build/components/global-styles/font-sizes/font-size.js.map +1 -1
  13. package/build/components/global-styles/font-sizes/font-sizes.js +17 -20
  14. package/build/components/global-styles/font-sizes/font-sizes.js.map +1 -1
  15. package/build/components/global-styles/screen-block.js +1 -1
  16. package/build/components/global-styles/screen-block.js.map +1 -1
  17. package/build/components/global-styles/shadows-edit-panel.js +21 -13
  18. package/build/components/global-styles/shadows-edit-panel.js.map +1 -1
  19. package/build/components/global-styles/shadows-panel.js +43 -5
  20. package/build/components/global-styles/shadows-panel.js.map +1 -1
  21. package/build/components/layout/index.js +10 -1
  22. package/build/components/layout/index.js.map +1 -1
  23. package/build/components/page-patterns/fields.js +6 -35
  24. package/build/components/page-patterns/fields.js.map +1 -1
  25. package/build/components/page-templates/fields.js +6 -19
  26. package/build/components/page-templates/fields.js.map +1 -1
  27. package/build/components/post-list/index.js +13 -5
  28. package/build/components/post-list/index.js.map +1 -1
  29. package/build/components/sidebar-dataviews/custom-dataviews-list.js +5 -7
  30. package/build/components/sidebar-dataviews/custom-dataviews-list.js.map +1 -1
  31. package/build/components/sidebar-dataviews/default-views.js +3 -2
  32. package/build/components/sidebar-dataviews/default-views.js.map +1 -1
  33. package/build/components/sidebar-global-styles-wrapper/index.js +40 -72
  34. package/build/components/sidebar-global-styles-wrapper/index.js.map +1 -1
  35. package/build/components/sidebar-navigation-screen-main/index.js +1 -0
  36. package/build/components/sidebar-navigation-screen-main/index.js.map +1 -1
  37. package/build/components/site-editor-routes/stylebook.js +6 -2
  38. package/build/components/site-editor-routes/stylebook.js.map +1 -1
  39. package/build/components/site-editor-routes/styles.js +7 -1
  40. package/build/components/site-editor-routes/styles.js.map +1 -1
  41. package/build/components/style-book/constants.js +36 -2
  42. package/build/components/style-book/constants.js.map +1 -1
  43. package/build/components/style-book/index.js +106 -61
  44. package/build/components/style-book/index.js.map +1 -1
  45. package/build-module/components/add-new-pattern/index.js +6 -10
  46. package/build-module/components/add-new-pattern/index.js.map +1 -1
  47. package/build-module/components/editor/index.js +1 -9
  48. package/build-module/components/editor/index.js.map +1 -1
  49. package/build-module/components/global-styles/confirm-reset-shadow-dialog.js +32 -0
  50. package/build-module/components/global-styles/confirm-reset-shadow-dialog.js.map +1 -0
  51. package/build-module/components/global-styles/font-library-modal/index.js +1 -1
  52. package/build-module/components/global-styles/font-library-modal/index.js.map +1 -1
  53. package/build-module/components/global-styles/font-sizes/font-size.js +17 -14
  54. package/build-module/components/global-styles/font-sizes/font-size.js.map +1 -1
  55. package/build-module/components/global-styles/font-sizes/font-sizes.js +24 -27
  56. package/build-module/components/global-styles/font-sizes/font-sizes.js.map +1 -1
  57. package/build-module/components/global-styles/screen-block.js +1 -1
  58. package/build-module/components/global-styles/screen-block.js.map +1 -1
  59. package/build-module/components/global-styles/shadows-edit-panel.js +21 -13
  60. package/build-module/components/global-styles/shadows-edit-panel.js.map +1 -1
  61. package/build-module/components/global-styles/shadows-panel.js +46 -8
  62. package/build-module/components/global-styles/shadows-panel.js.map +1 -1
  63. package/build-module/components/layout/index.js +11 -2
  64. package/build-module/components/layout/index.js.map +1 -1
  65. package/build-module/components/page-patterns/fields.js +7 -36
  66. package/build-module/components/page-patterns/fields.js.map +1 -1
  67. package/build-module/components/page-templates/fields.js +6 -19
  68. package/build-module/components/page-templates/fields.js.map +1 -1
  69. package/build-module/components/post-list/index.js +13 -5
  70. package/build-module/components/post-list/index.js.map +1 -1
  71. package/build-module/components/sidebar-dataviews/custom-dataviews-list.js +5 -7
  72. package/build-module/components/sidebar-dataviews/custom-dataviews-list.js.map +1 -1
  73. package/build-module/components/sidebar-dataviews/default-views.js +3 -2
  74. package/build-module/components/sidebar-dataviews/default-views.js.map +1 -1
  75. package/build-module/components/sidebar-global-styles-wrapper/index.js +41 -75
  76. package/build-module/components/sidebar-global-styles-wrapper/index.js.map +1 -1
  77. package/build-module/components/sidebar-navigation-screen-main/index.js +1 -0
  78. package/build-module/components/sidebar-navigation-screen-main/index.js.map +1 -1
  79. package/build-module/components/site-editor-routes/stylebook.js +6 -2
  80. package/build-module/components/site-editor-routes/stylebook.js.map +1 -1
  81. package/build-module/components/site-editor-routes/styles.js +7 -1
  82. package/build-module/components/site-editor-routes/styles.js.map +1 -1
  83. package/build-module/components/style-book/constants.js +35 -1
  84. package/build-module/components/style-book/constants.js.map +1 -1
  85. package/build-module/components/style-book/index.js +107 -62
  86. package/build-module/components/style-book/index.js.map +1 -1
  87. package/build-style/posts-rtl.css +72 -78
  88. package/build-style/posts.css +72 -78
  89. package/build-style/style-rtl.css +163 -184
  90. package/build-style/style.css +163 -184
  91. package/package.json +42 -41
  92. package/src/components/add-new-pattern/index.js +10 -7
  93. package/src/components/canvas-loader/style.scss +4 -3
  94. package/src/components/editor/index.js +1 -7
  95. package/src/components/editor/style.scss +4 -2
  96. package/src/components/editor-canvas-container/style.scss +7 -1
  97. package/src/components/global-styles/confirm-reset-shadow-dialog.js +37 -0
  98. package/src/components/global-styles/font-library-modal/index.js +1 -1
  99. package/src/components/global-styles/font-library-modal/style.scss +4 -2
  100. package/src/components/global-styles/font-sizes/font-size.js +28 -19
  101. package/src/components/global-styles/font-sizes/font-sizes.js +37 -35
  102. package/src/components/global-styles/screen-block.js +3 -2
  103. package/src/components/global-styles/shadows-edit-panel.js +38 -28
  104. package/src/components/global-styles/shadows-panel.js +64 -5
  105. package/src/components/global-styles/style.scss +9 -1
  106. package/src/components/global-styles/variations/style.scss +4 -3
  107. package/src/components/layout/index.js +12 -1
  108. package/src/components/layout/style.scss +8 -3
  109. package/src/components/page/style.scss +8 -5
  110. package/src/components/page-patterns/fields.js +11 -41
  111. package/src/components/page-patterns/style.scss +4 -25
  112. package/src/components/page-templates/fields.js +6 -16
  113. package/src/components/page-templates/style.scss +4 -20
  114. package/src/components/post-list/index.js +13 -4
  115. package/src/components/sidebar-dataviews/custom-dataviews-list.js +7 -6
  116. package/src/components/sidebar-dataviews/default-views.js +3 -2
  117. package/src/components/sidebar-dataviews/style.scss +4 -1
  118. package/src/components/sidebar-global-styles-wrapper/index.js +37 -83
  119. package/src/components/sidebar-global-styles-wrapper/style.scss +22 -0
  120. package/src/components/sidebar-navigation-item/style.scss +6 -0
  121. package/src/components/sidebar-navigation-screen-main/index.js +1 -1
  122. package/src/components/site-editor-routes/stylebook.js +2 -2
  123. package/src/components/site-editor-routes/styles.js +5 -1
  124. package/src/components/site-hub/style.scss +4 -2
  125. package/src/components/style-book/constants.ts +49 -1
  126. package/src/components/style-book/index.js +151 -77
@@ -5,11 +5,9 @@ import { __ } from '@wordpress/i18n';
5
5
  import { useMemo, useState } from '@wordpress/element';
6
6
  import { privateApis as routerPrivateApis } from '@wordpress/router';
7
7
  import { useViewportMatch } from '@wordpress/compose';
8
- import {
9
- Button,
10
- privateApis as componentsPrivateApis,
11
- } from '@wordpress/components';
12
- import { addQueryArgs } from '@wordpress/url';
8
+ import { Button } from '@wordpress/components';
9
+ import { addQueryArgs, removeQueryArgs } from '@wordpress/url';
10
+ import { seen } from '@wordpress/icons';
13
11
 
14
12
  /**
15
13
  * Internal dependencies
@@ -17,58 +15,42 @@ import { addQueryArgs } from '@wordpress/url';
17
15
  import GlobalStylesUI from '../global-styles/ui';
18
16
  import Page from '../page';
19
17
  import { unlock } from '../../lock-unlock';
20
- import StyleBook from '../style-book';
21
- import { STYLE_BOOK_COLOR_GROUPS } from '../style-book/constants';
22
18
 
23
19
  const { useLocation, useHistory } = unlock( routerPrivateApis );
24
- const { Menu } = unlock( componentsPrivateApis );
25
20
 
26
21
  const GlobalStylesPageActions = ( {
27
22
  isStyleBookOpened,
28
23
  setIsStyleBookOpened,
24
+ path,
29
25
  } ) => {
26
+ const history = useHistory();
30
27
  return (
31
- <Menu
32
- trigger={
33
- <Button __next40pxDefaultSize variant="tertiary" size="compact">
34
- { __( 'Preview' ) }
35
- </Button>
36
- }
37
- >
38
- <Menu.RadioItem
39
- value
40
- checked={ isStyleBookOpened }
41
- name="styles-preview-actions"
42
- onChange={ () => setIsStyleBookOpened( true ) }
43
- defaultChecked
44
- >
45
- <Menu.ItemLabel>{ __( 'Style book' ) }</Menu.ItemLabel>
46
- <Menu.ItemHelpText>
47
- { __( 'Preview blocks and styles.' ) }
48
- </Menu.ItemHelpText>
49
- </Menu.RadioItem>
50
- <Menu.RadioItem
51
- value={ false }
52
- checked={ ! isStyleBookOpened }
53
- name="styles-preview-actions"
54
- onChange={ () => setIsStyleBookOpened( false ) }
55
- >
56
- <Menu.ItemLabel>{ __( 'Site' ) }</Menu.ItemLabel>
57
- <Menu.ItemHelpText>
58
- { __( 'Preview your site.' ) }
59
- </Menu.ItemHelpText>
60
- </Menu.RadioItem>
61
- </Menu>
28
+ <Button
29
+ isPressed={ isStyleBookOpened }
30
+ icon={ seen }
31
+ label={ __( 'Style Book' ) }
32
+ onClick={ () => {
33
+ setIsStyleBookOpened( ! isStyleBookOpened );
34
+ const updatedPath = ! isStyleBookOpened
35
+ ? addQueryArgs( path, { preview: 'stylebook' } )
36
+ : removeQueryArgs( path, 'preview' );
37
+ // Navigate to the updated path.
38
+ history.navigate( updatedPath );
39
+ } }
40
+ size="compact"
41
+ />
62
42
  );
63
43
  };
64
44
 
65
- export default function GlobalStylesUIWrapper() {
45
+ /**
46
+ * Hook to deal with navigation and location state.
47
+ *
48
+ * @return {Array} The current section and a function to update it.
49
+ */
50
+ export const useSection = () => {
66
51
  const { path, query } = useLocation();
67
52
  const history = useHistory();
68
- const { canvas = 'view' } = query;
69
- const [ isStyleBookOpened, setIsStyleBookOpened ] = useState( false );
70
- const isMobileViewport = useViewportMatch( 'medium', '<' );
71
- const [ section, onChangeSection ] = useMemo( () => {
53
+ return useMemo( () => {
72
54
  return [
73
55
  query.section ?? '/',
74
56
  ( updatedSection ) => {
@@ -80,6 +62,16 @@ export default function GlobalStylesUIWrapper() {
80
62
  },
81
63
  ];
82
64
  }, [ path, query.section, history ] );
65
+ };
66
+
67
+ export default function GlobalStylesUIWrapper() {
68
+ const { path } = useLocation();
69
+
70
+ const [ isStyleBookOpened, setIsStyleBookOpened ] = useState(
71
+ path.includes( 'preview=stylebook' )
72
+ );
73
+ const isMobileViewport = useViewportMatch( 'medium', '<' );
74
+ const [ section, onChangeSection ] = useSection();
83
75
 
84
76
  return (
85
77
  <>
@@ -89,6 +81,7 @@ export default function GlobalStylesUIWrapper() {
89
81
  <GlobalStylesPageActions
90
82
  isStyleBookOpened={ isStyleBookOpened }
91
83
  setIsStyleBookOpened={ setIsStyleBookOpened }
84
+ path={ path }
92
85
  />
93
86
  ) : null
94
87
  }
@@ -100,45 +93,6 @@ export default function GlobalStylesUIWrapper() {
100
93
  onPathChange={ onChangeSection }
101
94
  />
102
95
  </Page>
103
- { canvas === 'view' && isStyleBookOpened && (
104
- <StyleBook
105
- enableResizing={ false }
106
- showCloseButton={ false }
107
- showTabs={ false }
108
- isSelected={ ( blockName ) =>
109
- // Match '/blocks/core%2Fbutton' and
110
- // '/blocks/core%2Fbutton/typography', but not
111
- // '/blocks/core%2Fbuttons'.
112
- section ===
113
- `/blocks/${ encodeURIComponent( blockName ) }` ||
114
- section.startsWith(
115
- `/blocks/${ encodeURIComponent( blockName ) }/`
116
- )
117
- }
118
- path={ section }
119
- onSelect={ ( blockName ) => {
120
- if (
121
- STYLE_BOOK_COLOR_GROUPS.find(
122
- ( group ) => group.slug === blockName
123
- )
124
- ) {
125
- // Go to color palettes Global Styles.
126
- onChangeSection( '/colors/palette' );
127
- return;
128
- }
129
- if ( blockName === 'typography' ) {
130
- // Go to typography Global Styles.
131
- onChangeSection( '/typography' );
132
- return;
133
- }
134
-
135
- // Now go to the selected block.
136
- onChangeSection(
137
- `/blocks/${ encodeURIComponent( blockName ) }`
138
- );
139
- } }
140
- />
141
- ) }
142
96
  </>
143
97
  );
144
98
  }
@@ -33,3 +33,25 @@
33
33
  color: $gray-900;
34
34
  }
35
35
  }
36
+
37
+ .show-icon-labels {
38
+ .edit-site-styles .edit-site-page-content {
39
+ .edit-site-page-header__actions {
40
+ .components-button.has-icon {
41
+ width: auto;
42
+ padding: 0 $grid-unit-10;
43
+
44
+ // Hide the button icons when labels are set to display...
45
+ svg {
46
+ display: none;
47
+ }
48
+ // ... and display labels.
49
+ &::after {
50
+ content: attr(aria-label);
51
+ font-size: $helptext-font-size;
52
+ }
53
+ }
54
+
55
+ }
56
+ }
57
+ }
@@ -18,6 +18,12 @@
18
18
  &[aria-current="true"] {
19
19
  background: $gray-800;
20
20
  color: $white;
21
+ font-weight: $font-weight-medium;
22
+ }
23
+
24
+ // Make sure the focus style is drawn on top of the current item background.
25
+ &:focus-visible {
26
+ transform: translateZ(0);
21
27
  }
22
28
 
23
29
  .edit-site-sidebar-navigation-item__drilldown-indicator {
@@ -19,7 +19,7 @@ import { store as editSiteStore } from '../../store';
19
19
 
20
20
  export function MainSidebarNavigationContent( { isBlockBasedTheme = true } ) {
21
21
  return (
22
- <ItemGroup>
22
+ <ItemGroup className="edit-site-sidebar-navigation-screen-main">
23
23
  { isBlockBasedTheme && (
24
24
  <>
25
25
  <SidebarNavigationItem
@@ -22,7 +22,7 @@ export const stylebookRoute = {
22
22
  ) }
23
23
  />
24
24
  ),
25
- preview: <StyleBookPreview />,
26
- mobile: <StyleBookPreview />,
25
+ preview: <StyleBookPreview isStatic />,
26
+ mobile: <StyleBookPreview isStatic />,
27
27
  },
28
28
  };
@@ -10,6 +10,7 @@ import Editor from '../editor';
10
10
  import { unlock } from '../../lock-unlock';
11
11
  import SidebarNavigationScreenGlobalStyles from '../sidebar-navigation-screen-global-styles';
12
12
  import GlobalStylesUIWrapper from '../sidebar-global-styles-wrapper';
13
+ import { StyleBookPreview } from '../style-book';
13
14
 
14
15
  const { useLocation } = unlock( routerPrivateApis );
15
16
 
@@ -30,7 +31,10 @@ export const stylesRoute = {
30
31
  areas: {
31
32
  content: <GlobalStylesUIWrapper />,
32
33
  sidebar: <SidebarNavigationScreenGlobalStyles backPath="/" />,
33
- preview: <Editor />,
34
+ preview( { query } ) {
35
+ const isStylebook = query.preview === 'stylebook';
36
+ return isStylebook ? <StyleBookPreview /> : <Editor />;
37
+ },
34
38
  mobile: <MobileGlobalStylesUI />,
35
39
  },
36
40
  widths: {
@@ -65,8 +65,10 @@
65
65
  opacity: 0;
66
66
  position: absolute;
67
67
  right: 0;
68
- transition: opacity 0.1s linear;
69
- @include reduce-motion("transition");
68
+
69
+ @media not (prefers-reduced-motion) {
70
+ transition: opacity 0.1s linear;
71
+ }
70
72
  }
71
73
 
72
74
  &:hover::after,
@@ -148,6 +148,55 @@ export const STYLE_BOOK_CATEGORIES: StyleBookCategory[] = [
148
148
  },
149
149
  ];
150
150
 
151
+ // Style book preview subcategories for all blocks section.
152
+ export const STYLE_BOOK_ALL_BLOCKS_SUBCATEGORIES: StyleBookCategory[] = [
153
+ ...STYLE_BOOK_THEME_SUBCATEGORIES,
154
+ {
155
+ slug: 'media',
156
+ title: __( 'Media' ),
157
+ blocks: [ 'core/post-featured-image' ],
158
+ },
159
+ {
160
+ slug: 'widgets',
161
+ title: __( 'Widgets' ),
162
+ blocks: [],
163
+ },
164
+ {
165
+ slug: 'embed',
166
+ title: __( 'Embeds' ),
167
+ include: [],
168
+ },
169
+ ];
170
+
171
+ // Style book preview categories are organised slightly differently to the editor ones.
172
+ export const STYLE_BOOK_PREVIEW_CATEGORIES: StyleBookCategory[] = [
173
+ {
174
+ slug: 'overview',
175
+ title: __( 'Overview' ),
176
+ blocks: [],
177
+ },
178
+ {
179
+ slug: 'text',
180
+ title: __( 'Text' ),
181
+ blocks: [
182
+ 'core/post-content',
183
+ 'core/home-link',
184
+ 'core/navigation-link',
185
+ ],
186
+ },
187
+ {
188
+ slug: 'colors',
189
+ title: __( 'Colors' ),
190
+ blocks: [],
191
+ },
192
+ {
193
+ slug: 'blocks',
194
+ title: __( 'All Blocks' ),
195
+ blocks: [],
196
+ subcategories: STYLE_BOOK_ALL_BLOCKS_SUBCATEGORIES,
197
+ },
198
+ ];
199
+
151
200
  // Forming a "block formatting context" to prevent margin collapsing.
152
201
  // @see https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context
153
202
  const ROOT_CONTAINER = `
@@ -239,7 +288,6 @@ export const STYLE_BOOK_IFRAME_STYLES = `
239
288
  .edit-site-style-book__subcategory-title {
240
289
  font-size: 16px;
241
290
  margin-bottom: 40px;
242
- border-bottom: 1px solid #ddd;
243
291
  padding-bottom: 8px;
244
292
  }
245
293
 
@@ -32,8 +32,11 @@ import {
32
32
  useContext,
33
33
  useRef,
34
34
  useLayoutEffect,
35
+ useEffect,
35
36
  } from '@wordpress/element';
36
37
  import { ENTER, SPACE } from '@wordpress/keycodes';
38
+ import { uploadMedia } from '@wordpress/media-utils';
39
+ import { store as coreStore } from '@wordpress/core-data';
37
40
 
38
41
  /**
39
42
  * Internal dependencies
@@ -47,6 +50,12 @@ import {
47
50
  } from './categories';
48
51
  import { getExamples } from './examples';
49
52
  import { store as siteEditorStore } from '../../store';
53
+ import { useSection } from '../sidebar-global-styles-wrapper';
54
+ import { GlobalStylesRenderer } from '../global-styles-renderer';
55
+ import {
56
+ STYLE_BOOK_COLOR_GROUPS,
57
+ STYLE_BOOK_PREVIEW_CATEGORIES,
58
+ } from '../style-book/constants';
50
59
 
51
60
  const {
52
61
  ExperimentalBlockEditorProvider,
@@ -85,35 +94,24 @@ const scrollToSection = ( anchorId, iframe ) => {
85
94
  };
86
95
 
87
96
  /**
88
- * Parses a Block Editor navigation path to extract the block name and
89
- * build a style book navigation path. The object can be extended to include a category,
90
- * representing a style book tab/section.
97
+ * Parses a Block Editor navigation path to build a style book navigation path.
98
+ * The object can be extended to include a category, representing a style book tab/section.
91
99
  *
92
100
  * @param {string} path An internal Block Editor navigation path.
93
101
  * @return {null|{block: string}} An object containing the example to navigate to.
94
102
  */
95
103
  const getStyleBookNavigationFromPath = ( path ) => {
96
104
  if ( path && typeof path === 'string' ) {
97
- if ( path === '/' ) {
105
+ if (
106
+ path === '/' ||
107
+ path.startsWith( '/typography' ) ||
108
+ path.startsWith( '/colors' ) ||
109
+ path.startsWith( '/blocks' )
110
+ ) {
98
111
  return {
99
112
  top: true,
100
113
  };
101
114
  }
102
-
103
- if ( path.startsWith( '/typography' ) ) {
104
- return {
105
- block: 'typography',
106
- };
107
- }
108
- let block = path.includes( '/blocks/' )
109
- ? decodeURIComponent( path.split( '/blocks/' )[ 1 ] )
110
- : null;
111
- // Default to theme-colors if the path ends with /colors.
112
- block = path.endsWith( '/colors' ) ? 'theme-colors' : block;
113
-
114
- return {
115
- block,
116
- };
117
115
  }
118
116
  return null;
119
117
  };
@@ -307,29 +305,43 @@ function StyleBook( {
307
305
  ) ) }
308
306
  </Tabs.TabList>
309
307
  </div>
310
- { tabs.map( ( tab ) => (
311
- <Tabs.TabPanel
312
- key={ tab.slug }
313
- tabId={ tab.slug }
314
- focusable={ false }
315
- className="edit-site-style-book__tabpanel"
316
- >
317
- <StyleBookBody
318
- category={ tab.slug }
319
- examples={ examples }
320
- isSelected={ isSelected }
321
- onSelect={ onSelect }
322
- settings={ settings }
323
- sizes={ sizes }
324
- title={ tab.title }
325
- goTo={ goTo }
326
- />
327
- </Tabs.TabPanel>
328
- ) ) }
308
+ { tabs.map( ( tab ) => {
309
+ const categoryDefinition = tab.slug
310
+ ? getTopLevelStyleBookCategories().find(
311
+ ( _category ) =>
312
+ _category.slug === tab.slug
313
+ )
314
+ : null;
315
+ const filteredExamples = categoryDefinition
316
+ ? getExamplesByCategory(
317
+ categoryDefinition,
318
+ examples
319
+ )
320
+ : { examples };
321
+ return (
322
+ <Tabs.TabPanel
323
+ key={ tab.slug }
324
+ tabId={ tab.slug }
325
+ focusable={ false }
326
+ className="edit-site-style-book__tabpanel"
327
+ >
328
+ <StyleBookBody
329
+ category={ tab.slug }
330
+ examples={ filteredExamples }
331
+ isSelected={ isSelected }
332
+ onSelect={ onSelect }
333
+ settings={ settings }
334
+ sizes={ sizes }
335
+ title={ tab.title }
336
+ goTo={ goTo }
337
+ />
338
+ </Tabs.TabPanel>
339
+ );
340
+ } ) }
329
341
  </Tabs>
330
342
  ) : (
331
343
  <StyleBookBody
332
- examples={ examplesForSinglePageUse }
344
+ examples={ { examples: examplesForSinglePageUse } }
333
345
  isSelected={ isSelected }
334
346
  onClick={ onClick }
335
347
  onSelect={ onSelect }
@@ -346,33 +358,113 @@ function StyleBook( {
346
358
  /**
347
359
  * Style Book Preview component renders the stylebook without the Editor dependency.
348
360
  *
349
- * @param {Object} props Component props.
350
- * @param {string} props.path Path to the selected block.
351
- * @param {Object} props.userConfig User configuration.
352
- * @param {Function} props.isSelected Function to check if a block is selected.
353
- * @param {Function} props.onSelect Function to select a block.
361
+ * @param {Object} props Component props.
362
+ * @param {Object} props.userConfig User configuration.
363
+ * @param {boolean} props.isStatic Whether the stylebook is static or clickable.
354
364
  * @return {Object} Style Book Preview component.
355
365
  */
356
- export const StyleBookPreview = ( {
357
- path = '',
358
- userConfig = {},
359
- isSelected,
360
- onSelect,
361
- } ) => {
366
+ export const StyleBookPreview = ( { userConfig = {}, isStatic = false } ) => {
362
367
  const siteEditorSettings = useSelect(
363
368
  ( select ) => select( siteEditorStore ).getSettings(),
364
369
  []
365
370
  );
371
+
372
+ const canUserUploadMedia = useSelect(
373
+ ( select ) =>
374
+ select( coreStore ).canUser( 'create', {
375
+ kind: 'root',
376
+ name: 'media',
377
+ } ),
378
+ []
379
+ );
380
+
366
381
  // Update block editor settings because useMultipleOriginColorsAndGradients fetch colours from there.
367
- dispatch( blockEditorStore ).updateSettings( siteEditorSettings );
382
+ useEffect( () => {
383
+ dispatch( blockEditorStore ).updateSettings( {
384
+ ...siteEditorSettings,
385
+ mediaUpload: canUserUploadMedia ? uploadMedia : undefined,
386
+ } );
387
+ }, [ siteEditorSettings, canUserUploadMedia ] );
388
+
389
+ const [ section, onChangeSection ] = useSection();
390
+
391
+ const isSelected = ( blockName ) => {
392
+ // Match '/blocks/core%2Fbutton' and
393
+ // '/blocks/core%2Fbutton/typography', but not
394
+ // '/blocks/core%2Fbuttons'.
395
+ return (
396
+ section === `/blocks/${ encodeURIComponent( blockName ) }` ||
397
+ section.startsWith(
398
+ `/blocks/${ encodeURIComponent( blockName ) }/`
399
+ )
400
+ );
401
+ };
402
+
403
+ const onSelect = ( blockName ) => {
404
+ if (
405
+ STYLE_BOOK_COLOR_GROUPS.find(
406
+ ( group ) => group.slug === blockName
407
+ )
408
+ ) {
409
+ // Go to color palettes Global Styles.
410
+ onChangeSection( '/colors/palette' );
411
+ return;
412
+ }
413
+ if ( blockName === 'typography' ) {
414
+ // Go to typography Global Styles.
415
+ onChangeSection( '/typography' );
416
+ return;
417
+ }
418
+
419
+ // Now go to the selected block.
420
+ onChangeSection( `/blocks/${ encodeURIComponent( blockName ) }` );
421
+ };
368
422
 
369
423
  const [ resizeObserver, sizes ] = useResizeObserver();
370
424
  const colors = useMultiOriginPalettes();
371
425
  const examples = getExamples( colors );
372
426
  const examplesForSinglePageUse = getExamplesForSinglePageUse( examples );
373
427
 
428
+ let previewCategory = null;
429
+ if ( section.includes( '/colors' ) ) {
430
+ previewCategory = 'colors';
431
+ } else if ( section.includes( '/typography' ) ) {
432
+ previewCategory = 'text';
433
+ } else if ( section.includes( '/blocks' ) ) {
434
+ previewCategory = 'blocks';
435
+ const blockName =
436
+ decodeURIComponent( section ).split( '/blocks/' )[ 1 ];
437
+ if (
438
+ blockName &&
439
+ examples.find( ( example ) => example.name === blockName )
440
+ ) {
441
+ previewCategory = blockName;
442
+ }
443
+ } else if ( ! isStatic ) {
444
+ previewCategory = 'overview';
445
+ }
446
+ const categoryDefinition = STYLE_BOOK_PREVIEW_CATEGORIES.find(
447
+ ( category ) => category.slug === previewCategory
448
+ );
449
+
450
+ // If there's no category definition there may be a single block.
451
+ const filteredExamples = categoryDefinition
452
+ ? getExamplesByCategory( categoryDefinition, examples )
453
+ : {
454
+ examples: [
455
+ examples.find(
456
+ ( example ) => example.name === previewCategory
457
+ ),
458
+ ],
459
+ };
460
+
461
+ // If there's no preview category, show all examples.
462
+ const displayedExamples = previewCategory
463
+ ? filteredExamples
464
+ : { examples: examplesForSinglePageUse };
465
+
374
466
  const { base: baseConfig } = useContext( GlobalStylesContext );
375
- const goTo = getStyleBookNavigationFromPath( path );
467
+ const goTo = getStyleBookNavigationFromPath( section );
376
468
 
377
469
  const mergedConfig = useMemo( () => {
378
470
  if ( ! isObjectEmpty( userConfig ) && ! isObjectEmpty( baseConfig ) ) {
@@ -399,13 +491,14 @@ export const StyleBookPreview = ( {
399
491
  <div className="edit-site-style-book">
400
492
  { resizeObserver }
401
493
  <BlockEditorProvider settings={ settings }>
494
+ <GlobalStylesRenderer disableRootPadding />
402
495
  <StyleBookBody
403
- examples={ examplesForSinglePageUse }
496
+ examples={ displayedExamples }
404
497
  settings={ settings }
405
498
  goTo={ goTo }
406
499
  sizes={ sizes }
407
- isSelected={ isSelected }
408
- onSelect={ onSelect }
500
+ isSelected={ ! isStatic ? isSelected : null }
501
+ onSelect={ ! isStatic ? onSelect : null }
409
502
  />
410
503
  </BlockEditorProvider>
411
504
  </div>
@@ -413,7 +506,6 @@ export const StyleBookPreview = ( {
413
506
  };
414
507
 
415
508
  export const StyleBookBody = ( {
416
- category,
417
509
  examples,
418
510
  isSelected,
419
511
  onClick,
@@ -459,13 +551,6 @@ export const StyleBookBody = ( {
459
551
  if ( hasIframeLoaded && iframeRef?.current ) {
460
552
  if ( goTo?.top ) {
461
553
  scrollToSection( 'top', iframeRef?.current );
462
- return;
463
- }
464
- if ( goTo?.block ) {
465
- scrollToSection(
466
- `example-${ goTo?.block }`,
467
- iframeRef?.current
468
- );
469
554
  }
470
555
  }
471
556
  }, [ iframeRef?.current, goTo, scrollToSection, hasIframeLoaded ] );
@@ -492,8 +577,7 @@ export const StyleBookBody = ( {
492
577
  className={ clsx( 'edit-site-style-book__examples', {
493
578
  'is-wide': sizes.width > 600,
494
579
  } ) }
495
- examples={ examples }
496
- category={ category }
580
+ filteredExamples={ examples }
497
581
  label={
498
582
  title
499
583
  ? sprintf(
@@ -505,24 +589,14 @@ export const StyleBookBody = ( {
505
589
  }
506
590
  isSelected={ isSelected }
507
591
  onSelect={ onSelect }
508
- key={ category }
592
+ key={ title }
509
593
  />
510
594
  </Iframe>
511
595
  );
512
596
  };
513
597
 
514
598
  const Examples = memo(
515
- ( { className, examples, category, label, isSelected, onSelect } ) => {
516
- const categoryDefinition = category
517
- ? getTopLevelStyleBookCategories().find(
518
- ( _category ) => _category.slug === category
519
- )
520
- : null;
521
-
522
- const filteredExamples = categoryDefinition
523
- ? getExamplesByCategory( categoryDefinition, examples )
524
- : { examples };
525
-
599
+ ( { className, filteredExamples, label, isSelected, onSelect } ) => {
526
600
  return (
527
601
  <Composite
528
602
  orientation="vertical"