@wordpress/editor 13.34.0 → 13.35.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 (263) hide show
  1. package/CHANGELOG.md +10 -4
  2. package/build/bindings/pattern-overrides.js +70 -1
  3. package/build/bindings/pattern-overrides.js.map +1 -1
  4. package/build/components/block-settings-menu/content-only-settings-menu.js +126 -0
  5. package/build/components/block-settings-menu/content-only-settings-menu.js.map +1 -0
  6. package/build/components/block-settings-menu/content-only-settings-menu.native.js +11 -0
  7. package/build/components/block-settings-menu/content-only-settings-menu.native.js.map +1 -0
  8. package/build/components/collapsible-block-toolbar/index.js +2 -2
  9. package/build/components/collapsible-block-toolbar/index.js.map +1 -1
  10. package/build/components/document-bar/index.js +2 -2
  11. package/build/components/document-bar/index.js.map +1 -1
  12. package/build/components/document-outline/item.js +2 -2
  13. package/build/components/document-outline/item.js.map +1 -1
  14. package/build/components/document-tools/index.js +15 -18
  15. package/build/components/document-tools/index.js.map +1 -1
  16. package/build/components/editor-canvas/index.js +19 -8
  17. package/build/components/editor-canvas/index.js.map +1 -1
  18. package/build/components/global-keyboard-shortcuts/register-shortcuts.js +1 -1
  19. package/build/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
  20. package/build/components/global-styles-provider/index.js +130 -0
  21. package/build/components/global-styles-provider/index.js.map +1 -0
  22. package/build/components/header/index.js +147 -0
  23. package/build/components/header/index.js.map +1 -0
  24. package/build/components/inserter-sidebar/index.js +56 -31
  25. package/build/components/inserter-sidebar/index.js.map +1 -1
  26. package/build/components/keyboard-shortcut-help-modal/index.js +2 -2
  27. package/build/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  28. package/build/components/post-actions/actions.js +122 -64
  29. package/build/components/post-actions/actions.js.map +1 -1
  30. package/build/components/post-actions/index.js +7 -14
  31. package/build/components/post-actions/index.js.map +1 -1
  32. package/build/components/post-card-panel/index.js +5 -29
  33. package/build/components/post-card-panel/index.js.map +1 -1
  34. package/build/components/post-comments/index.js +28 -8
  35. package/build/components/post-comments/index.js.map +1 -1
  36. package/build/components/post-discussion/panel.js +103 -21
  37. package/build/components/post-discussion/panel.js.map +1 -1
  38. package/build/components/post-excerpt/panel.js +2 -2
  39. package/build/components/post-excerpt/panel.js.map +1 -1
  40. package/build/components/post-format/panel.js +27 -0
  41. package/build/components/post-format/panel.js.map +1 -0
  42. package/build/components/post-panel-row/index.js +2 -2
  43. package/build/components/post-panel-row/index.js.map +1 -1
  44. package/build/components/post-panel-section/index.js +28 -0
  45. package/build/components/post-panel-section/index.js.map +1 -0
  46. package/build/components/post-pingbacks/index.js +5 -2
  47. package/build/components/post-pingbacks/index.js.map +1 -1
  48. package/build/components/post-saved-state/index.js +2 -2
  49. package/build/components/post-saved-state/index.js.map +1 -1
  50. package/build/components/post-slug/panel.js +27 -0
  51. package/build/components/post-slug/panel.js.map +1 -0
  52. package/build/components/post-status/index.js +4 -4
  53. package/build/components/post-status/index.js.map +1 -1
  54. package/build/components/post-sticky/panel.js +21 -0
  55. package/build/components/post-sticky/panel.js.map +1 -0
  56. package/build/components/post-title/index.js +2 -2
  57. package/build/components/post-title/index.js.map +1 -1
  58. package/build/components/post-title/post-title-raw.js +2 -2
  59. package/build/components/post-title/post-title-raw.js.map +1 -1
  60. package/build/components/post-transform-panel/hooks.js +90 -0
  61. package/build/components/post-transform-panel/hooks.js.map +1 -0
  62. package/build/components/post-transform-panel/index.js +101 -0
  63. package/build/components/post-transform-panel/index.js.map +1 -0
  64. package/build/components/post-trash/panel.js +18 -0
  65. package/build/components/post-trash/panel.js.map +1 -0
  66. package/build/components/post-type-support-check/index.js +1 -1
  67. package/build/components/post-type-support-check/index.js.map +1 -1
  68. package/build/components/preferences-modal/index.js +3 -3
  69. package/build/components/preferences-modal/index.js.map +1 -1
  70. package/build/components/provider/index.js +3 -1
  71. package/build/components/provider/index.js.map +1 -1
  72. package/build/components/provider/use-block-editor-settings.js +21 -3
  73. package/build/components/provider/use-block-editor-settings.js.map +1 -1
  74. package/build/components/sidebar/constants.js +11 -0
  75. package/build/components/sidebar/constants.js.map +1 -0
  76. package/build/components/sidebar/header.js +53 -0
  77. package/build/components/sidebar/header.js.map +1 -0
  78. package/build/components/sidebar/index.js +157 -0
  79. package/build/components/sidebar/index.js.map +1 -0
  80. package/build/components/sidebar/post-summary.js +84 -0
  81. package/build/components/sidebar/post-summary.js.map +1 -0
  82. package/build/components/start-page-options/index.js +5 -7
  83. package/build/components/start-page-options/index.js.map +1 -1
  84. package/build/components/start-template-options/index.js +192 -0
  85. package/build/components/start-template-options/index.js.map +1 -0
  86. package/build/components/template-content-panel/index.js +38 -0
  87. package/build/components/template-content-panel/index.js.map +1 -0
  88. package/build/hooks/pattern-overrides.js +10 -5
  89. package/build/hooks/pattern-overrides.js.map +1 -1
  90. package/build/private-apis.js +7 -12
  91. package/build/private-apis.js.map +1 -1
  92. package/build/private-apis.native.js +72 -0
  93. package/build/private-apis.native.js.map +1 -0
  94. package/build/store/private-selectors.js +6 -1
  95. package/build/store/private-selectors.js.map +1 -1
  96. package/build/store/reducer.js +15 -0
  97. package/build/store/reducer.js.map +1 -1
  98. package/build-module/bindings/pattern-overrides.js +69 -1
  99. package/build-module/bindings/pattern-overrides.js.map +1 -1
  100. package/build-module/components/block-settings-menu/content-only-settings-menu.js +119 -0
  101. package/build-module/components/block-settings-menu/content-only-settings-menu.js.map +1 -0
  102. package/build-module/components/block-settings-menu/content-only-settings-menu.native.js +5 -0
  103. package/build-module/components/block-settings-menu/content-only-settings-menu.native.js.map +1 -0
  104. package/build-module/components/collapsible-block-toolbar/index.js +2 -2
  105. package/build-module/components/collapsible-block-toolbar/index.js.map +1 -1
  106. package/build-module/components/document-bar/index.js +2 -2
  107. package/build-module/components/document-bar/index.js.map +1 -1
  108. package/build-module/components/document-outline/item.js +2 -2
  109. package/build-module/components/document-outline/item.js.map +1 -1
  110. package/build-module/components/document-tools/index.js +16 -19
  111. package/build-module/components/document-tools/index.js.map +1 -1
  112. package/build-module/components/editor-canvas/index.js +19 -8
  113. package/build-module/components/editor-canvas/index.js.map +1 -1
  114. package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js +1 -1
  115. package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
  116. package/build-module/components/global-styles-provider/index.js +120 -0
  117. package/build-module/components/global-styles-provider/index.js.map +1 -0
  118. package/build-module/components/header/index.js +139 -0
  119. package/build-module/components/header/index.js.map +1 -0
  120. package/build-module/components/inserter-sidebar/index.js +59 -34
  121. package/build-module/components/inserter-sidebar/index.js.map +1 -1
  122. package/build-module/components/keyboard-shortcut-help-modal/index.js +2 -2
  123. package/build-module/components/keyboard-shortcut-help-modal/index.js.map +1 -1
  124. package/build-module/components/post-actions/actions.js +125 -66
  125. package/build-module/components/post-actions/actions.js.map +1 -1
  126. package/build-module/components/post-actions/index.js +7 -14
  127. package/build-module/components/post-actions/index.js.map +1 -1
  128. package/build-module/components/post-card-panel/index.js +7 -30
  129. package/build-module/components/post-card-panel/index.js.map +1 -1
  130. package/build-module/components/post-comments/index.js +30 -10
  131. package/build-module/components/post-comments/index.js.map +1 -1
  132. package/build-module/components/post-discussion/panel.js +105 -23
  133. package/build-module/components/post-discussion/panel.js.map +1 -1
  134. package/build-module/components/post-excerpt/panel.js +2 -2
  135. package/build-module/components/post-excerpt/panel.js.map +1 -1
  136. package/build-module/components/post-format/panel.js +18 -0
  137. package/build-module/components/post-format/panel.js.map +1 -0
  138. package/build-module/components/post-panel-row/index.js +2 -2
  139. package/build-module/components/post-panel-row/index.js.map +1 -1
  140. package/build-module/components/post-panel-section/index.js +20 -0
  141. package/build-module/components/post-panel-section/index.js.map +1 -0
  142. package/build-module/components/post-pingbacks/index.js +6 -3
  143. package/build-module/components/post-pingbacks/index.js.map +1 -1
  144. package/build-module/components/post-saved-state/index.js +2 -2
  145. package/build-module/components/post-saved-state/index.js.map +1 -1
  146. package/build-module/components/post-slug/panel.js +18 -0
  147. package/build-module/components/post-slug/panel.js.map +1 -0
  148. package/build-module/components/post-status/index.js +4 -4
  149. package/build-module/components/post-status/index.js.map +1 -1
  150. package/build-module/components/post-sticky/panel.js +12 -0
  151. package/build-module/components/post-sticky/panel.js.map +1 -0
  152. package/build-module/components/post-title/index.js +2 -2
  153. package/build-module/components/post-title/index.js.map +1 -1
  154. package/build-module/components/post-title/post-title-raw.js +2 -2
  155. package/build-module/components/post-title/post-title-raw.js.map +1 -1
  156. package/build-module/components/post-transform-panel/hooks.js +83 -0
  157. package/build-module/components/post-transform-panel/hooks.js.map +1 -0
  158. package/build-module/components/post-transform-panel/index.js +94 -0
  159. package/build-module/components/post-transform-panel/index.js.map +1 -0
  160. package/build-module/components/post-trash/panel.js +10 -0
  161. package/build-module/components/post-trash/panel.js.map +1 -0
  162. package/build-module/components/post-type-support-check/index.js +1 -1
  163. package/build-module/components/post-type-support-check/index.js.map +1 -1
  164. package/build-module/components/preferences-modal/index.js +3 -3
  165. package/build-module/components/preferences-modal/index.js.map +1 -1
  166. package/build-module/components/provider/index.js +3 -1
  167. package/build-module/components/provider/index.js.map +1 -1
  168. package/build-module/components/provider/use-block-editor-settings.js +21 -3
  169. package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
  170. package/build-module/components/sidebar/constants.js +5 -0
  171. package/build-module/components/sidebar/constants.js.map +1 -0
  172. package/build-module/components/sidebar/header.js +46 -0
  173. package/build-module/components/sidebar/header.js.map +1 -0
  174. package/build-module/components/sidebar/index.js +149 -0
  175. package/build-module/components/sidebar/index.js.map +1 -0
  176. package/build-module/components/sidebar/post-summary.js +77 -0
  177. package/build-module/components/sidebar/post-summary.js.map +1 -0
  178. package/build-module/components/start-page-options/index.js +5 -7
  179. package/build-module/components/start-page-options/index.js.map +1 -1
  180. package/build-module/components/start-template-options/index.js +185 -0
  181. package/build-module/components/start-template-options/index.js.map +1 -0
  182. package/build-module/components/template-content-panel/index.js +31 -0
  183. package/build-module/components/template-content-panel/index.js.map +1 -0
  184. package/build-module/hooks/pattern-overrides.js +10 -5
  185. package/build-module/hooks/pattern-overrides.js.map +1 -1
  186. package/build-module/private-apis.js +7 -12
  187. package/build-module/private-apis.js.map +1 -1
  188. package/build-module/private-apis.native.js +62 -0
  189. package/build-module/private-apis.native.js.map +1 -0
  190. package/build-module/store/private-selectors.js +3 -0
  191. package/build-module/store/private-selectors.js.map +1 -1
  192. package/build-module/store/reducer.js +14 -0
  193. package/build-module/store/reducer.js.map +1 -1
  194. package/build-style/style-rtl.css +328 -18
  195. package/build-style/style.css +328 -18
  196. package/package.json +38 -36
  197. package/src/bindings/pattern-overrides.js +83 -1
  198. package/src/components/autocompleters/style.scss +1 -2
  199. package/src/components/block-settings-menu/content-only-settings-menu.js +175 -0
  200. package/src/components/block-settings-menu/content-only-settings-menu.native.js +4 -0
  201. package/src/components/block-settings-menu/style.scss +4 -0
  202. package/src/components/collapsible-block-toolbar/index.js +2 -2
  203. package/src/components/document-bar/index.js +2 -2
  204. package/src/components/document-outline/item.js +2 -2
  205. package/src/components/document-tools/index.js +19 -21
  206. package/src/components/editor-canvas/index.js +18 -6
  207. package/src/components/global-keyboard-shortcuts/register-shortcuts.js +1 -1
  208. package/src/components/global-styles-provider/index.js +162 -0
  209. package/src/components/header/index.js +154 -0
  210. package/src/components/header/style.scss +231 -0
  211. package/src/components/inserter-sidebar/index.js +52 -29
  212. package/src/components/inserter-sidebar/style.scss +10 -3
  213. package/src/components/keyboard-shortcut-help-modal/index.js +2 -2
  214. package/src/components/list-view-sidebar/style.scss +1 -0
  215. package/src/components/page-attributes/test/order.js +5 -1
  216. package/src/components/post-actions/actions.js +256 -150
  217. package/src/components/post-actions/index.js +5 -38
  218. package/src/components/post-card-panel/index.js +39 -85
  219. package/src/components/post-comments/index.js +47 -9
  220. package/src/components/post-discussion/panel.js +108 -31
  221. package/src/components/post-discussion/style.scss +26 -0
  222. package/src/components/post-excerpt/panel.js +2 -2
  223. package/src/components/post-format/panel.js +22 -0
  224. package/src/components/post-format/style.scss +6 -0
  225. package/src/components/post-last-revision/test/check.js +5 -1
  226. package/src/components/post-panel-row/index.js +2 -2
  227. package/src/components/post-panel-section/index.js +19 -0
  228. package/src/components/post-panel-section/style.scss +3 -0
  229. package/src/components/post-pingbacks/index.js +11 -2
  230. package/src/components/post-publish-panel/style.scss +5 -0
  231. package/src/components/post-saved-state/index.js +2 -2
  232. package/src/components/post-slug/panel.js +22 -0
  233. package/src/components/post-slug/style.scss +5 -0
  234. package/src/components/post-slug/test/index.js +5 -1
  235. package/src/components/post-status/index.js +4 -4
  236. package/src/components/post-sticky/panel.js +18 -0
  237. package/src/components/post-title/index.js +2 -2
  238. package/src/components/post-title/post-title-raw.js +2 -2
  239. package/src/components/post-transform-panel/hooks.js +114 -0
  240. package/src/components/post-transform-panel/index.js +99 -0
  241. package/src/components/post-trash/panel.js +13 -0
  242. package/src/components/post-type-support-check/index.js +1 -1
  243. package/src/components/post-type-support-check/test/index.js +2 -2
  244. package/src/components/preferences-modal/index.js +3 -3
  245. package/src/components/provider/index.js +4 -0
  246. package/src/components/provider/use-block-editor-settings.js +19 -4
  247. package/src/components/sidebar/constants.js +4 -0
  248. package/src/components/sidebar/header.js +49 -0
  249. package/src/components/sidebar/index.js +200 -0
  250. package/src/components/sidebar/post-summary.js +104 -0
  251. package/src/components/sidebar/style.scss +18 -0
  252. package/src/components/start-page-options/index.js +6 -4
  253. package/src/components/start-template-options/index.js +219 -0
  254. package/src/components/start-template-options/style.scss +55 -0
  255. package/src/components/template-areas/style.scss +0 -1
  256. package/src/components/template-content-panel/index.js +36 -0
  257. package/src/hooks/pattern-overrides.js +12 -6
  258. package/src/private-apis.js +10 -12
  259. package/src/private-apis.native.js +61 -0
  260. package/src/store/private-selectors.js +3 -0
  261. package/src/store/reducer.js +12 -0
  262. package/src/style.scss +7 -0
  263. package/src/components/post-slug/test/check.js +0 -17
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import PostPanelRow from '../post-panel-row';
5
+ import PostStickyForm from './';
6
+ import PostStickyCheck from './check';
7
+
8
+ export function PostStickyPanel() {
9
+ return (
10
+ <PostStickyCheck>
11
+ <PostPanelRow>
12
+ <PostStickyForm />
13
+ </PostPanelRow>
14
+ </PostStickyCheck>
15
+ );
16
+ }
17
+
18
+ export default PostStickyPanel;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import classnames from 'classnames';
4
+ import clsx from 'clsx';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -185,7 +185,7 @@ function PostTitle( _, forwardedRef ) {
185
185
 
186
186
  // The wp-block className is important for editor styles.
187
187
  // This same block is used in both the visual and the code editor.
188
- const className = classnames( DEFAULT_CLASSNAMES, {
188
+ const className = clsx( DEFAULT_CLASSNAMES, {
189
189
  'is-selected': isSelected,
190
190
  'has-fixed-toolbar': hasFixedToolbar,
191
191
  } );
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import classnames from 'classnames';
4
+ import clsx from 'clsx';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -51,7 +51,7 @@ function PostTitleRaw( _, forwardedRef ) {
51
51
 
52
52
  // The wp-block className is important for editor styles.
53
53
  // This same block is used in both the visual and the code editor.
54
- const className = classnames( DEFAULT_CLASSNAMES, {
54
+ const className = clsx( DEFAULT_CLASSNAMES, {
55
55
  'is-selected': isSelected,
56
56
  'has-fixed-toolbar': hasFixedToolbar,
57
57
  'is-raw-text': true,
@@ -0,0 +1,114 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { useMemo } from '@wordpress/element';
6
+ import { store as coreStore } from '@wordpress/core-data';
7
+ import { parse } from '@wordpress/blocks';
8
+ import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { unlock } from '../../lock-unlock';
14
+ import { store as editorStore } from '../../store';
15
+
16
+ const { EXCLUDED_PATTERN_SOURCES, PATTERN_TYPES } =
17
+ unlock( patternsPrivateApis );
18
+
19
+ function injectThemeAttributeInBlockTemplateContent(
20
+ block,
21
+ currentThemeStylesheet
22
+ ) {
23
+ block.innerBlocks = block.innerBlocks.map( ( innerBlock ) => {
24
+ return injectThemeAttributeInBlockTemplateContent(
25
+ innerBlock,
26
+ currentThemeStylesheet
27
+ );
28
+ } );
29
+
30
+ if (
31
+ block.name === 'core/template-part' &&
32
+ block.attributes.theme === undefined
33
+ ) {
34
+ block.attributes.theme = currentThemeStylesheet;
35
+ }
36
+ return block;
37
+ }
38
+
39
+ /**
40
+ * Filter all patterns and return only the ones that are compatible with the current template.
41
+ *
42
+ * @param {Array} patterns An array of patterns.
43
+ * @param {Object} template The current template.
44
+ * @return {Array} Array of patterns that are compatible with the current template.
45
+ */
46
+ function filterPatterns( patterns, template ) {
47
+ // Filter out duplicates.
48
+ const filterOutDuplicatesByName = ( currentItem, index, items ) =>
49
+ index === items.findIndex( ( item ) => currentItem.name === item.name );
50
+
51
+ // Filter out core/directory patterns not included in theme.json.
52
+ const filterOutExcludedPatternSources = ( pattern ) =>
53
+ ! EXCLUDED_PATTERN_SOURCES.includes( pattern.source );
54
+
55
+ // Looks for patterns that have the same template type as the current template,
56
+ // or have a block type that matches the current template area.
57
+ const filterCompatiblePatterns = ( pattern ) =>
58
+ pattern.templateTypes?.includes( template.slug ) ||
59
+ pattern.blockTypes?.includes( 'core/template-part/' + template.area );
60
+
61
+ return patterns.filter( ( pattern, index, items ) => {
62
+ return (
63
+ filterOutDuplicatesByName( pattern, index, items ) &&
64
+ filterOutExcludedPatternSources( pattern ) &&
65
+ filterCompatiblePatterns( pattern )
66
+ );
67
+ } );
68
+ }
69
+
70
+ function preparePatterns( patterns, currentThemeStylesheet ) {
71
+ return patterns.map( ( pattern ) => ( {
72
+ ...pattern,
73
+ keywords: pattern.keywords || [],
74
+ type: PATTERN_TYPES.theme,
75
+ blocks: parse( pattern.content, {
76
+ __unstableSkipMigrationLogs: true,
77
+ } ).map( ( block ) =>
78
+ injectThemeAttributeInBlockTemplateContent(
79
+ block,
80
+ currentThemeStylesheet
81
+ )
82
+ ),
83
+ } ) );
84
+ }
85
+
86
+ export function useAvailablePatterns( template ) {
87
+ const { blockPatterns, restBlockPatterns, currentThemeStylesheet } =
88
+ useSelect( ( select ) => {
89
+ const { getEditorSettings } = select( editorStore );
90
+ const settings = getEditorSettings();
91
+
92
+ return {
93
+ blockPatterns:
94
+ settings.__experimentalAdditionalBlockPatterns ??
95
+ settings.__experimentalBlockPatterns,
96
+ restBlockPatterns: select( coreStore ).getBlockPatterns(),
97
+ currentThemeStylesheet:
98
+ select( coreStore ).getCurrentTheme().stylesheet,
99
+ };
100
+ }, [] );
101
+
102
+ return useMemo( () => {
103
+ const mergedPatterns = [
104
+ ...( blockPatterns || [] ),
105
+ ...( restBlockPatterns || [] ),
106
+ ];
107
+ const filteredPatterns = filterPatterns( mergedPatterns, template );
108
+ return preparePatterns(
109
+ filteredPatterns,
110
+ template,
111
+ currentThemeStylesheet
112
+ );
113
+ }, [ blockPatterns, restBlockPatterns, template, currentThemeStylesheet ] );
114
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+ import { store as coreStore } from '@wordpress/core-data';
6
+ import { PanelBody, PanelRow } from '@wordpress/components';
7
+ import { __ } from '@wordpress/i18n';
8
+ import { useAsyncList } from '@wordpress/compose';
9
+ import { __experimentalBlockPatternsList as BlockPatternsList } from '@wordpress/block-editor';
10
+ import { serialize } from '@wordpress/blocks';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import { store as editorStore } from '../../store';
16
+ import { useAvailablePatterns } from './hooks';
17
+ import {
18
+ TEMPLATE_POST_TYPE,
19
+ TEMPLATE_PART_POST_TYPE,
20
+ } from '../../store/constants';
21
+
22
+ function TemplatesList( { availableTemplates, onSelect } ) {
23
+ const shownTemplates = useAsyncList( availableTemplates );
24
+ if ( ! availableTemplates || availableTemplates?.length === 0 ) {
25
+ return null;
26
+ }
27
+
28
+ return (
29
+ <BlockPatternsList
30
+ label={ __( 'Templates' ) }
31
+ blockPatterns={ availableTemplates }
32
+ shownPatterns={ shownTemplates }
33
+ onClickPattern={ onSelect }
34
+ showTitlesAsTooltip
35
+ />
36
+ );
37
+ }
38
+
39
+ function PostTransform() {
40
+ const { record, postType, postId } = useSelect( ( select ) => {
41
+ const { getCurrentPostType, getCurrentPostId } = select( editorStore );
42
+ const { getEditedEntityRecord } = select( coreStore );
43
+ const type = getCurrentPostType();
44
+ const id = getCurrentPostId();
45
+ return {
46
+ postType: type,
47
+ postId: id,
48
+ record: getEditedEntityRecord( 'postType', type, id ),
49
+ };
50
+ }, [] );
51
+ const { editEntityRecord } = useDispatch( coreStore );
52
+ const availablePatterns = useAvailablePatterns( record );
53
+ const onTemplateSelect = async ( selectedTemplate ) => {
54
+ await editEntityRecord( 'postType', postType, postId, {
55
+ blocks: selectedTemplate.blocks,
56
+ content: serialize( selectedTemplate.blocks ),
57
+ } );
58
+ };
59
+ if ( ! availablePatterns?.length ) {
60
+ return null;
61
+ }
62
+
63
+ return (
64
+ <PanelBody
65
+ title={ __( 'Transform into:' ) }
66
+ initialOpen={ record.type === TEMPLATE_PART_POST_TYPE }
67
+ >
68
+ <PanelRow>
69
+ <p>
70
+ { __(
71
+ 'Choose a predefined pattern to switch up the look of your template.' // TODO - make this dynamic?
72
+ ) }
73
+ </p>
74
+ </PanelRow>
75
+
76
+ <TemplatesList
77
+ availableTemplates={ availablePatterns }
78
+ onSelect={ onTemplateSelect }
79
+ />
80
+ </PanelBody>
81
+ );
82
+ }
83
+
84
+ export default function PostTransformPanel() {
85
+ const { postType } = useSelect( ( select ) => {
86
+ const { getCurrentPostType } = select( editorStore );
87
+ return {
88
+ postType: getCurrentPostType(),
89
+ };
90
+ }, [] );
91
+
92
+ if (
93
+ ! [ TEMPLATE_PART_POST_TYPE, TEMPLATE_POST_TYPE ].includes( postType )
94
+ ) {
95
+ return null;
96
+ }
97
+
98
+ return <PostTransform />;
99
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import PostTrashCheck from './check';
5
+ import PostTrashLink from './';
6
+
7
+ export default function PostTrashPanel() {
8
+ return (
9
+ <PostTrashCheck>
10
+ <PostTrashLink />
11
+ </PostTrashCheck>
12
+ );
13
+ }
@@ -27,7 +27,7 @@ function PostTypeSupportCheck( { children, supportKeys } ) {
27
27
  const { getPostType } = select( coreStore );
28
28
  return getPostType( getEditedPostAttribute( 'type' ) );
29
29
  }, [] );
30
- let isSupported = true;
30
+ let isSupported = !! postType;
31
31
  if ( postType ) {
32
32
  isSupported = (
33
33
  Array.isArray( supportKeys ) ? supportKeys : [ supportKeys ]
@@ -29,7 +29,7 @@ function setupUseSelectMock( postType ) {
29
29
  }
30
30
 
31
31
  describe( 'PostTypeSupportCheck', () => {
32
- it( 'renders its children when post type is not known', () => {
32
+ it( 'does not render its children when post type is not known', () => {
33
33
  setupUseSelectMock( undefined );
34
34
 
35
35
  const { container } = render(
@@ -38,7 +38,7 @@ describe( 'PostTypeSupportCheck', () => {
38
38
  </PostTypeSupportCheck>
39
39
  );
40
40
 
41
- expect( container ).toHaveTextContent( 'Supported' );
41
+ expect( container ).not.toHaveTextContent( 'Supported' );
42
42
  } );
43
43
 
44
44
  it( 'does not render its children when post type is known and not supports', () => {
@@ -70,9 +70,9 @@ export default function EditorPreferencesModal( { extraSections = {} } ) {
70
70
  scope="core"
71
71
  featureName="showListViewByDefault"
72
72
  help={ __(
73
- 'Opens the block list view sidebar by default.'
73
+ 'Opens the List View sidebar by default.'
74
74
  ) }
75
- label={ __( 'Always open list view' ) }
75
+ label={ __( 'Always open List View' ) }
76
76
  />
77
77
  { showBlockBreadcrumbsOption && (
78
78
  <PreferenceToggleControl
@@ -88,7 +88,7 @@ export default function EditorPreferencesModal( { extraSections = {} } ) {
88
88
  scope="core"
89
89
  featureName="allowRightClickOverrides"
90
90
  help={ __(
91
- 'Allows contextual list view menus via right-click, overriding browser defaults.'
91
+ 'Allows contextual List View menus via right-click, overriding browser defaults.'
92
92
  ) }
93
93
  label={ __(
94
94
  'Allow right-click contextual menus'
@@ -28,6 +28,8 @@ import useCommands from '../commands';
28
28
  import BlockRemovalWarnings from '../block-removal-warnings';
29
29
  import StartPageOptions from '../start-page-options';
30
30
  import KeyboardShortcutHelpModal from '../keyboard-shortcut-help-modal';
31
+ import ContentOnlySettingsMenu from '../block-settings-menu/content-only-settings-menu';
32
+ import StartTemplateOptions from '../start-template-options';
31
33
 
32
34
  const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis );
33
35
  const { PatternsMenuItems } = unlock( editPatternsPrivateApis );
@@ -264,6 +266,7 @@ export const ExperimentalEditorProvider = withRegistryProvider(
264
266
  { ! settings.__unstableIsPreviewMode && (
265
267
  <>
266
268
  <PatternsMenuItems />
269
+ <ContentOnlySettingsMenu />
267
270
  { mode === 'template-locked' && (
268
271
  <DisableNonPageContentBlocks />
269
272
  ) }
@@ -273,6 +276,7 @@ export const ExperimentalEditorProvider = withRegistryProvider(
273
276
  <KeyboardShortcutHelpModal />
274
277
  <BlockRemovalWarnings />
275
278
  <StartPageOptions />
279
+ <StartTemplateOptions />
276
280
  </>
277
281
  ) }
278
282
  </BlockEditorProviderComponent>
@@ -24,8 +24,10 @@ import inserterMediaCategories from '../media-categories';
24
24
  import { mediaUpload } from '../../utils';
25
25
  import { store as editorStore } from '../../store';
26
26
  import { lock, unlock } from '../../lock-unlock';
27
+ import { useGlobalStylesContext } from '../global-styles-provider';
27
28
 
28
29
  const EMPTY_BLOCKS_LIST = [];
30
+ const DEFAULT_STYLES = {};
29
31
 
30
32
  function __experimentalReusableBlocksSelect( select ) {
31
33
  return (
@@ -173,6 +175,9 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
173
175
  [ postType, postId, isLargeViewport, renderingMode ]
174
176
  );
175
177
 
178
+ const { merged: mergedGlobalStyles } = useGlobalStylesContext();
179
+ const globalStylesData = mergedGlobalStyles.styles ?? DEFAULT_STYLES;
180
+
176
181
  const settingsBlockPatterns =
177
182
  settings.__experimentalAdditionalBlockPatterns ?? // WP 6.0
178
183
  settings.__experimentalBlockPatterns; // WP 5.9
@@ -251,6 +256,8 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
251
256
  }, [ settings.allowedBlockTypes, hiddenBlockTypes, blockTypes ] );
252
257
 
253
258
  const forceDisableFocusMode = settings.focusMode === false;
259
+ const { globalStylesDataKey, selectBlockPatternsKey } =
260
+ unlock( privateApis );
254
261
 
255
262
  return useMemo( () => {
256
263
  const blockEditorSettings = {
@@ -259,6 +266,7 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
259
266
  BLOCK_EDITOR_SETTINGS.includes( key )
260
267
  )
261
268
  ),
269
+ [ globalStylesDataKey ]: globalStylesData,
262
270
  allowedBlockTypes,
263
271
  allowRightClickOverrides,
264
272
  focusMode: focusMode && ! forceDisableFocusMode,
@@ -267,10 +275,14 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
267
275
  keepCaretInsideBlock,
268
276
  mediaUpload: hasUploadPermissions ? mediaUpload : undefined,
269
277
  __experimentalBlockPatterns: blockPatterns,
270
- [ unlock( privateApis ).selectBlockPatternsKey ]: ( select ) =>
271
- unlock( select( coreStore ) ).getBlockPatternsForPostType(
272
- postType
273
- ),
278
+ [ selectBlockPatternsKey ]: ( select ) => {
279
+ const { hasFinishedResolution, getBlockPatternsForPostType } =
280
+ unlock( select( coreStore ) );
281
+ const patterns = getBlockPatternsForPostType( postType );
282
+ return hasFinishedResolution( 'getBlockPatterns' )
283
+ ? patterns
284
+ : undefined;
285
+ },
274
286
  [ unlock( privateApis ).reusableBlocksSelectKey ]:
275
287
  __experimentalReusableBlocksSelect,
276
288
  __experimentalBlockPatternCategories: blockPatternCategories,
@@ -327,6 +339,9 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
327
339
  postType,
328
340
  setIsInserterOpened,
329
341
  sectionRootClientId,
342
+ globalStylesData,
343
+ globalStylesDataKey,
344
+ selectBlockPatternsKey,
330
345
  ] );
331
346
  }
332
347
 
@@ -0,0 +1,4 @@
1
+ export const sidebars = {
2
+ document: 'edit-post/document',
3
+ block: 'edit-post/block',
4
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { privateApis as componentsPrivateApis } from '@wordpress/components';
5
+ import { __, _x } from '@wordpress/i18n';
6
+ import { useSelect } from '@wordpress/data';
7
+ import { forwardRef } from '@wordpress/element';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { store as editorStore } from '../../store';
13
+ import { unlock } from '../../lock-unlock';
14
+ import { sidebars } from './constants';
15
+
16
+ const { Tabs } = unlock( componentsPrivateApis );
17
+
18
+ const SidebarHeader = ( _, ref ) => {
19
+ const { documentLabel } = useSelect( ( select ) => {
20
+ const { getPostTypeLabel } = select( editorStore );
21
+
22
+ return {
23
+ // translators: Default label for the Document sidebar tab, not selected.
24
+ documentLabel: getPostTypeLabel() || _x( 'Document', 'noun' ),
25
+ };
26
+ }, [] );
27
+
28
+ return (
29
+ <Tabs.TabList ref={ ref }>
30
+ <Tabs.Tab
31
+ tabId={ sidebars.document }
32
+ // Used for focus management in the SettingsSidebar component.
33
+ data-tab-id={ sidebars.document }
34
+ >
35
+ { documentLabel }
36
+ </Tabs.Tab>
37
+ <Tabs.Tab
38
+ tabId={ sidebars.block }
39
+ // Used for focus management in the SettingsSidebar component.
40
+ data-tab-id={ sidebars.block }
41
+ >
42
+ { /* translators: Text label for the Block Settings Sidebar tab. */ }
43
+ { __( 'Block' ) }
44
+ </Tabs.Tab>
45
+ </Tabs.TabList>
46
+ );
47
+ };
48
+
49
+ export default forwardRef( SidebarHeader );
@@ -0,0 +1,200 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ BlockInspector,
6
+ store as blockEditorStore,
7
+ } from '@wordpress/block-editor';
8
+ import { useSelect, useDispatch } from '@wordpress/data';
9
+ import {
10
+ Platform,
11
+ useCallback,
12
+ useContext,
13
+ useEffect,
14
+ useRef,
15
+ } from '@wordpress/element';
16
+ import { isRTL, __ } from '@wordpress/i18n';
17
+ import { drawerLeft, drawerRight } from '@wordpress/icons';
18
+ import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts';
19
+ import { privateApis as componentsPrivateApis } from '@wordpress/components';
20
+ import { store as interfaceStore } from '@wordpress/interface';
21
+
22
+ /**
23
+ * Internal dependencies
24
+ */
25
+ import PageAttributesPanel from '../page-attributes/panel';
26
+ import PatternOverridesPanel from '../pattern-overrides-panel';
27
+ import PluginDocumentSettingPanel from '../plugin-document-setting-panel';
28
+ import PluginSidebar from '../plugin-sidebar';
29
+ import PostLastRevisionPanel from '../post-last-revision/panel';
30
+ import PostSummary from './post-summary';
31
+ import PostTaxonomiesPanel from '../post-taxonomies/panel';
32
+ import PostTransformPanel from '../post-transform-panel';
33
+ import SidebarHeader from './header';
34
+ import TemplateContentPanel from '../template-content-panel';
35
+ import useAutoSwitchEditorSidebars from '../provider/use-auto-switch-editor-sidebars';
36
+ import { sidebars } from './constants';
37
+ import { unlock } from '../../lock-unlock';
38
+ import { store as editorStore } from '../../store';
39
+ import {
40
+ NAVIGATION_POST_TYPE,
41
+ TEMPLATE_PART_POST_TYPE,
42
+ TEMPLATE_POST_TYPE,
43
+ } from '../../store/constants';
44
+
45
+ const { Tabs } = unlock( componentsPrivateApis );
46
+
47
+ const SIDEBAR_ACTIVE_BY_DEFAULT = Platform.select( {
48
+ web: true,
49
+ native: false,
50
+ } );
51
+
52
+ const SidebarContent = ( {
53
+ tabName,
54
+ keyboardShortcut,
55
+ renderingMode,
56
+ onActionPerformed,
57
+ extraPanels,
58
+ } ) => {
59
+ const tabListRef = useRef( null );
60
+ // Because `PluginSidebar` renders a `ComplementaryArea`, we
61
+ // need to forward the `Tabs` context so it can be passed through the
62
+ // underlying slot/fill.
63
+ const tabsContextValue = useContext( Tabs.Context );
64
+
65
+ // This effect addresses a race condition caused by tabbing from the last
66
+ // block in the editor into the settings sidebar. Without this effect, the
67
+ // selected tab and browser focus can become separated in an unexpected way
68
+ // (e.g the "block" tab is focused, but the "post" tab is selected).
69
+ useEffect( () => {
70
+ const tabsElements = Array.from(
71
+ tabListRef.current?.querySelectorAll( '[role="tab"]' ) || []
72
+ );
73
+ const selectedTabElement = tabsElements.find(
74
+ // We are purposefully using a custom `data-tab-id` attribute here
75
+ // because we don't want rely on any assumptions about `Tabs`
76
+ // component internals.
77
+ ( element ) => element.getAttribute( 'data-tab-id' ) === tabName
78
+ );
79
+ const activeElement = selectedTabElement?.ownerDocument.activeElement;
80
+ const tabsHasFocus = tabsElements.some( ( element ) => {
81
+ return activeElement && activeElement.id === element.id;
82
+ } );
83
+ if (
84
+ tabsHasFocus &&
85
+ selectedTabElement &&
86
+ selectedTabElement.id !== activeElement?.id
87
+ ) {
88
+ selectedTabElement?.focus();
89
+ }
90
+ }, [ tabName ] );
91
+
92
+ return (
93
+ <PluginSidebar
94
+ identifier={ tabName }
95
+ header={
96
+ <Tabs.Context.Provider value={ tabsContextValue }>
97
+ <SidebarHeader ref={ tabListRef } />
98
+ </Tabs.Context.Provider>
99
+ }
100
+ closeLabel={ __( 'Close Settings' ) }
101
+ // This classname is added so we can apply a corrective negative
102
+ // margin to the panel.
103
+ // see https://github.com/WordPress/gutenberg/pull/55360#pullrequestreview-1737671049
104
+ className="editor-sidebar__panel"
105
+ headerClassName="editor-sidebar__panel-tabs"
106
+ /* translators: button label text should, if possible, be under 16 characters. */
107
+ title={ __( 'Settings' ) }
108
+ toggleShortcut={ keyboardShortcut }
109
+ icon={ isRTL() ? drawerLeft : drawerRight }
110
+ isActiveByDefault={ SIDEBAR_ACTIVE_BY_DEFAULT }
111
+ >
112
+ <Tabs.Context.Provider value={ tabsContextValue }>
113
+ <Tabs.TabPanel tabId={ sidebars.document } focusable={ false }>
114
+ <PostSummary onActionPerformed={ onActionPerformed } />
115
+ <PluginDocumentSettingPanel.Slot />
116
+ { renderingMode !== 'post-only' && (
117
+ <TemplateContentPanel />
118
+ ) }
119
+ <PostTransformPanel />
120
+ <PostLastRevisionPanel />
121
+ <PostTaxonomiesPanel />
122
+ <PageAttributesPanel />
123
+ <PatternOverridesPanel />
124
+ { extraPanels }
125
+ </Tabs.TabPanel>
126
+ <Tabs.TabPanel tabId={ sidebars.block } focusable={ false }>
127
+ <BlockInspector />
128
+ </Tabs.TabPanel>
129
+ </Tabs.Context.Provider>
130
+ </PluginSidebar>
131
+ );
132
+ };
133
+
134
+ const Sidebar = ( { extraPanels, onActionPerformed } ) => {
135
+ useAutoSwitchEditorSidebars();
136
+ const { tabName, keyboardShortcut, showSummary, renderingMode } = useSelect(
137
+ ( select ) => {
138
+ const shortcut = select(
139
+ keyboardShortcutsStore
140
+ ).getShortcutRepresentation( 'core/editor/toggle-sidebar' );
141
+
142
+ const sidebar =
143
+ select( interfaceStore ).getActiveComplementaryArea( 'core' );
144
+ const _isEditorSidebarOpened = [
145
+ sidebars.block,
146
+ sidebars.document,
147
+ ].includes( sidebar );
148
+ let _tabName = sidebar;
149
+ if ( ! _isEditorSidebarOpened ) {
150
+ _tabName = !! select(
151
+ blockEditorStore
152
+ ).getBlockSelectionStart()
153
+ ? sidebars.block
154
+ : sidebars.document;
155
+ }
156
+
157
+ return {
158
+ tabName: _tabName,
159
+ keyboardShortcut: shortcut,
160
+ showSummary: ! [
161
+ TEMPLATE_POST_TYPE,
162
+ TEMPLATE_PART_POST_TYPE,
163
+ NAVIGATION_POST_TYPE,
164
+ ].includes( select( editorStore ).getCurrentPostType() ),
165
+ renderingMode: select( editorStore ).getRenderingMode(),
166
+ };
167
+ },
168
+ []
169
+ );
170
+
171
+ const { enableComplementaryArea } = useDispatch( interfaceStore );
172
+
173
+ const onTabSelect = useCallback(
174
+ ( newSelectedTabId ) => {
175
+ if ( !! newSelectedTabId ) {
176
+ enableComplementaryArea( 'core', newSelectedTabId );
177
+ }
178
+ },
179
+ [ enableComplementaryArea ]
180
+ );
181
+
182
+ return (
183
+ <Tabs
184
+ selectedTabId={ tabName }
185
+ onSelect={ onTabSelect }
186
+ selectOnMove={ false }
187
+ >
188
+ <SidebarContent
189
+ tabName={ tabName }
190
+ keyboardShortcut={ keyboardShortcut }
191
+ showSummary={ showSummary }
192
+ renderingMode={ renderingMode }
193
+ onActionPerformed={ onActionPerformed }
194
+ extraPanels={ extraPanels }
195
+ />
196
+ </Tabs>
197
+ );
198
+ };
199
+
200
+ export default Sidebar;