@wordpress/editor 14.0.1 → 14.1.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 (247) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +164 -20
  3. package/build/components/document-tools/index.js +12 -3
  4. package/build/components/document-tools/index.js.map +1 -1
  5. package/build/components/editor/index.js +18 -24
  6. package/build/components/editor/index.js.map +1 -1
  7. package/build/components/entities-saved-states/hooks/use-is-dirty.js +9 -0
  8. package/build/components/entities-saved-states/hooks/use-is-dirty.js.map +1 -1
  9. package/build/components/entities-saved-states/index.js +28 -0
  10. package/build/components/entities-saved-states/index.js.map +1 -1
  11. package/build/components/global-styles-provider/index.js +9 -2
  12. package/build/components/global-styles-provider/index.js.map +1 -1
  13. package/build/components/index.js +7 -0
  14. package/build/components/index.js.map +1 -1
  15. package/build/components/post-actions/actions.js +9 -4
  16. package/build/components/post-actions/actions.js.map +1 -1
  17. package/build/components/post-publish-button/index.js +4 -0
  18. package/build/components/post-publish-button/index.js.map +1 -1
  19. package/build/components/post-publish-button/label.js +5 -0
  20. package/build/components/post-publish-button/label.js.map +1 -1
  21. package/build/components/post-publish-panel/index.js +4 -0
  22. package/build/components/post-publish-panel/index.js.map +1 -1
  23. package/build/components/post-sticky/check.js +8 -0
  24. package/build/components/post-sticky/check.js.map +1 -1
  25. package/build/components/post-sticky/index.js +5 -1
  26. package/build/components/post-sticky/index.js.map +1 -1
  27. package/build/components/post-switch-to-draft-button/index.js +11 -2
  28. package/build/components/post-switch-to-draft-button/index.js.map +1 -1
  29. package/build/components/post-sync-status/index.js +5 -1
  30. package/build/components/post-sync-status/index.js.map +1 -1
  31. package/build/components/post-taxonomies/check.js +8 -0
  32. package/build/components/post-taxonomies/check.js.map +1 -1
  33. package/build/components/post-taxonomies/flat-term-selector.js +14 -2
  34. package/build/components/post-taxonomies/flat-term-selector.js.map +1 -1
  35. package/build/components/post-taxonomies/index.js +9 -0
  36. package/build/components/post-taxonomies/index.js.map +1 -1
  37. package/build/components/post-taxonomies/panel.js +10 -0
  38. package/build/components/post-taxonomies/panel.js.map +1 -1
  39. package/build/components/post-title/index.js +4 -8
  40. package/build/components/post-title/index.js.map +1 -1
  41. package/build/components/post-title/post-title-raw.js +3 -7
  42. package/build/components/post-title/post-title-raw.js.map +1 -1
  43. package/build/components/post-trash/check.js +8 -0
  44. package/build/components/post-trash/check.js.map +1 -1
  45. package/build/components/post-trash/index.js +6 -1
  46. package/build/components/post-trash/index.js.map +1 -1
  47. package/build/components/post-visibility/index.js +1 -0
  48. package/build/components/post-visibility/index.js.map +1 -1
  49. package/build/components/provider/index.js +18 -15
  50. package/build/components/provider/index.js.map +1 -1
  51. package/build/components/sidebar/post-summary.js +1 -1
  52. package/build/components/sidebar/post-summary.js.map +1 -1
  53. package/build/components/table-of-contents/index.js +11 -0
  54. package/build/components/table-of-contents/index.js.map +1 -1
  55. package/build/components/template-part-menu-items/convert-to-regular.js +38 -0
  56. package/build/components/template-part-menu-items/convert-to-regular.js.map +1 -0
  57. package/build/components/template-part-menu-items/convert-to-template-part.js +77 -0
  58. package/build/components/template-part-menu-items/convert-to-template-part.js.map +1 -0
  59. package/build/components/template-part-menu-items/index.js +67 -0
  60. package/build/components/template-part-menu-items/index.js.map +1 -0
  61. package/build/components/template-part-menu-items/index.native.js +10 -0
  62. package/build/components/template-part-menu-items/index.native.js.map +1 -0
  63. package/build/components/template-validation-notice/index.js +1 -0
  64. package/build/components/template-validation-notice/index.js.map +1 -1
  65. package/build/components/theme-support-check/index.js +9 -0
  66. package/build/components/theme-support-check/index.js.map +1 -1
  67. package/build/components/time-to-read/index.js +6 -0
  68. package/build/components/time-to-read/index.js.map +1 -1
  69. package/build/components/visual-editor/edit-template-blocks-notification.js +1 -0
  70. package/build/components/visual-editor/edit-template-blocks-notification.js.map +1 -1
  71. package/build/components/word-count/index.js +5 -1
  72. package/build/components/word-count/index.js.map +1 -1
  73. package/build/dataviews/api.js +61 -0
  74. package/build/dataviews/api.js.map +1 -0
  75. package/build/dataviews/store/private-actions.js +28 -0
  76. package/build/dataviews/store/private-actions.js.map +1 -0
  77. package/build/dataviews/store/private-selectors.js +20 -0
  78. package/build/dataviews/store/private-selectors.js.map +1 -0
  79. package/build/dataviews/store/reducer.js +36 -0
  80. package/build/dataviews/store/reducer.js.map +1 -0
  81. package/build/hooks/pattern-overrides.js +2 -1
  82. package/build/hooks/pattern-overrides.js.map +1 -1
  83. package/build/index.js +12 -0
  84. package/build/index.js.map +1 -1
  85. package/build/private-apis.js +0 -6
  86. package/build/private-apis.js.map +1 -1
  87. package/build/private-apis.native.js +0 -2
  88. package/build/private-apis.native.js.map +1 -1
  89. package/build/store/private-actions.js +21 -0
  90. package/build/store/private-actions.js.map +1 -1
  91. package/build/store/private-selectors.js +5 -0
  92. package/build/store/private-selectors.js.map +1 -1
  93. package/build/store/reducer.js +4 -1
  94. package/build/store/reducer.js.map +1 -1
  95. package/build-module/components/document-tools/index.js +12 -3
  96. package/build-module/components/document-tools/index.js.map +1 -1
  97. package/build-module/components/editor/index.js +19 -24
  98. package/build-module/components/editor/index.js.map +1 -1
  99. package/build-module/components/entities-saved-states/hooks/use-is-dirty.js +10 -0
  100. package/build-module/components/entities-saved-states/hooks/use-is-dirty.js.map +1 -1
  101. package/build-module/components/entities-saved-states/index.js +28 -0
  102. package/build-module/components/entities-saved-states/index.js.map +1 -1
  103. package/build-module/components/global-styles-provider/index.js +9 -2
  104. package/build-module/components/global-styles-provider/index.js.map +1 -1
  105. package/build-module/components/index.js +7 -0
  106. package/build-module/components/index.js.map +1 -1
  107. package/build-module/components/post-actions/actions.js +9 -4
  108. package/build-module/components/post-actions/actions.js.map +1 -1
  109. package/build-module/components/post-publish-button/index.js +4 -0
  110. package/build-module/components/post-publish-button/index.js.map +1 -1
  111. package/build-module/components/post-publish-button/label.js +6 -0
  112. package/build-module/components/post-publish-button/label.js.map +1 -1
  113. package/build-module/components/post-publish-panel/index.js +4 -0
  114. package/build-module/components/post-publish-panel/index.js.map +1 -1
  115. package/build-module/components/post-sticky/check.js +9 -0
  116. package/build-module/components/post-sticky/check.js.map +1 -1
  117. package/build-module/components/post-sticky/index.js +6 -0
  118. package/build-module/components/post-sticky/index.js.map +1 -1
  119. package/build-module/components/post-switch-to-draft-button/index.js +10 -1
  120. package/build-module/components/post-switch-to-draft-button/index.js.map +1 -1
  121. package/build-module/components/post-sync-status/index.js +6 -0
  122. package/build-module/components/post-sync-status/index.js.map +1 -1
  123. package/build-module/components/post-taxonomies/check.js +9 -0
  124. package/build-module/components/post-taxonomies/check.js.map +1 -1
  125. package/build-module/components/post-taxonomies/flat-term-selector.js +14 -2
  126. package/build-module/components/post-taxonomies/flat-term-selector.js.map +1 -1
  127. package/build-module/components/post-taxonomies/index.js +9 -0
  128. package/build-module/components/post-taxonomies/index.js.map +1 -1
  129. package/build-module/components/post-taxonomies/panel.js +10 -0
  130. package/build-module/components/post-taxonomies/panel.js.map +1 -1
  131. package/build-module/components/post-title/index.js +4 -8
  132. package/build-module/components/post-title/index.js.map +1 -1
  133. package/build-module/components/post-title/post-title-raw.js +3 -7
  134. package/build-module/components/post-title/post-title-raw.js.map +1 -1
  135. package/build-module/components/post-trash/check.js +9 -0
  136. package/build-module/components/post-trash/check.js.map +1 -1
  137. package/build-module/components/post-trash/index.js +7 -0
  138. package/build-module/components/post-trash/index.js.map +1 -1
  139. package/build-module/components/post-visibility/index.js +1 -0
  140. package/build-module/components/post-visibility/index.js.map +1 -1
  141. package/build-module/components/provider/index.js +18 -15
  142. package/build-module/components/provider/index.js.map +1 -1
  143. package/build-module/components/sidebar/post-summary.js +1 -1
  144. package/build-module/components/sidebar/post-summary.js.map +1 -1
  145. package/build-module/components/table-of-contents/index.js +11 -0
  146. package/build-module/components/table-of-contents/index.js.map +1 -1
  147. package/build-module/components/template-part-menu-items/convert-to-regular.js +31 -0
  148. package/build-module/components/template-part-menu-items/convert-to-regular.js.map +1 -0
  149. package/build-module/components/template-part-menu-items/convert-to-template-part.js +71 -0
  150. package/build-module/components/template-part-menu-items/convert-to-template-part.js.map +1 -0
  151. package/build-module/components/template-part-menu-items/index.js +59 -0
  152. package/build-module/components/template-part-menu-items/index.js.map +1 -0
  153. package/build-module/components/template-part-menu-items/index.native.js +4 -0
  154. package/build-module/components/template-part-menu-items/index.native.js.map +1 -0
  155. package/build-module/components/template-validation-notice/index.js +1 -0
  156. package/build-module/components/template-validation-notice/index.js.map +1 -1
  157. package/build-module/components/theme-support-check/index.js +10 -0
  158. package/build-module/components/theme-support-check/index.js.map +1 -1
  159. package/build-module/components/time-to-read/index.js +6 -0
  160. package/build-module/components/time-to-read/index.js.map +1 -1
  161. package/build-module/components/visual-editor/edit-template-blocks-notification.js +1 -0
  162. package/build-module/components/visual-editor/edit-template-blocks-notification.js.map +1 -1
  163. package/build-module/components/word-count/index.js +6 -0
  164. package/build-module/components/word-count/index.js.map +1 -1
  165. package/build-module/dataviews/api.js +54 -0
  166. package/build-module/dataviews/api.js.map +1 -0
  167. package/build-module/dataviews/store/private-actions.js +21 -0
  168. package/build-module/dataviews/store/private-actions.js.map +1 -0
  169. package/build-module/dataviews/store/private-selectors.js +14 -0
  170. package/build-module/dataviews/store/private-selectors.js.map +1 -0
  171. package/build-module/dataviews/store/reducer.js +29 -0
  172. package/build-module/dataviews/store/reducer.js.map +1 -0
  173. package/build-module/hooks/pattern-overrides.js +2 -1
  174. package/build-module/hooks/pattern-overrides.js.map +1 -1
  175. package/build-module/index.js +1 -0
  176. package/build-module/index.js.map +1 -1
  177. package/build-module/private-apis.js +0 -6
  178. package/build-module/private-apis.js.map +1 -1
  179. package/build-module/private-apis.native.js +0 -2
  180. package/build-module/private-apis.native.js.map +1 -1
  181. package/build-module/store/private-actions.js +1 -0
  182. package/build-module/store/private-actions.js.map +1 -1
  183. package/build-module/store/private-selectors.js +4 -0
  184. package/build-module/store/private-selectors.js.map +1 -1
  185. package/build-module/store/reducer.js +3 -1
  186. package/build-module/store/reducer.js.map +1 -1
  187. package/build-style/style-rtl.css +7 -2
  188. package/build-style/style.css +7 -2
  189. package/build-types/dataviews/store/private-actions.d.ts +17 -0
  190. package/build-types/dataviews/store/private-actions.d.ts.map +1 -0
  191. package/build-types/dataviews/store/private-selectors.d.ts +10 -0
  192. package/build-types/dataviews/store/private-selectors.d.ts.map +1 -0
  193. package/build-types/dataviews/store/reducer.d.ts +11 -0
  194. package/build-types/dataviews/store/reducer.d.ts.map +1 -0
  195. package/package.json +35 -35
  196. package/src/components/document-tools/index.js +13 -4
  197. package/src/components/editor/index.js +23 -28
  198. package/src/components/entities-saved-states/hooks/use-is-dirty.js +9 -0
  199. package/src/components/entities-saved-states/index.js +26 -0
  200. package/src/components/global-styles-provider/index.js +12 -2
  201. package/src/components/index.js +7 -0
  202. package/src/components/keyboard-shortcut-help-modal/style.scss +0 -3
  203. package/src/components/post-actions/actions.js +6 -2
  204. package/src/components/post-card-panel/style.scss +4 -0
  205. package/src/components/post-panel-row/style.scss +1 -1
  206. package/src/components/post-publish-button/index.js +3 -0
  207. package/src/components/post-publish-button/label.js +5 -0
  208. package/src/components/post-publish-panel/index.js +3 -0
  209. package/src/components/post-status/style.scss +5 -0
  210. package/src/components/post-sticky/check.js +8 -0
  211. package/src/components/post-sticky/index.js +5 -0
  212. package/src/components/post-switch-to-draft-button/index.js +10 -1
  213. package/src/components/post-sync-status/index.js +5 -0
  214. package/src/components/post-taxonomies/check.js +8 -0
  215. package/src/components/post-taxonomies/flat-term-selector.js +13 -2
  216. package/src/components/post-taxonomies/index.js +8 -0
  217. package/src/components/post-taxonomies/panel.js +9 -0
  218. package/src/components/post-title/index.js +2 -5
  219. package/src/components/post-title/post-title-raw.js +2 -5
  220. package/src/components/post-trash/check.js +8 -0
  221. package/src/components/post-trash/index.js +6 -0
  222. package/src/components/post-visibility/index.js +1 -0
  223. package/src/components/provider/index.js +17 -17
  224. package/src/components/sidebar/post-summary.js +1 -1
  225. package/src/components/table-of-contents/index.js +10 -0
  226. package/src/components/template-part-menu-items/convert-to-regular.js +32 -0
  227. package/src/components/template-part-menu-items/convert-to-template-part.js +75 -0
  228. package/src/components/template-part-menu-items/index.js +59 -0
  229. package/src/components/template-part-menu-items/index.native.js +3 -0
  230. package/src/components/template-validation-notice/index.js +1 -0
  231. package/src/components/theme-support-check/index.js +9 -0
  232. package/src/components/time-to-read/index.js +5 -0
  233. package/src/components/visual-editor/edit-template-blocks-notification.js +1 -0
  234. package/src/components/word-count/index.js +5 -0
  235. package/src/dataviews/api.js +55 -0
  236. package/src/dataviews/store/private-actions.ts +30 -0
  237. package/src/dataviews/store/private-selectors.ts +15 -0
  238. package/src/dataviews/store/reducer.ts +44 -0
  239. package/src/hooks/pattern-overrides.js +2 -0
  240. package/src/index.js +1 -0
  241. package/src/private-apis.js +0 -6
  242. package/src/private-apis.native.js +0 -2
  243. package/src/store/private-actions.js +1 -0
  244. package/src/store/private-selectors.js +5 -0
  245. package/src/store/reducer.js +2 -0
  246. package/tsconfig.json +36 -0
  247. package/tsconfig.tsbuildinfo +1 -0
@@ -35,6 +35,10 @@
35
35
 
36
36
  .editor-post-card-panel__icon.is-sync {
37
37
  fill: var(--wp-block-synced-color);
38
+
39
+ & + .editor-post-card-panel__title {
40
+ color: var(--wp-block-synced-color);
41
+ }
38
42
  }
39
43
 
40
44
  .editor-post-card-panel__title-badge {
@@ -6,7 +6,7 @@
6
6
  }
7
7
 
8
8
  .editor-post-panel__row-label {
9
- width: 30%;
9
+ width: 38%;
10
10
  flex-shrink: 0;
11
11
  min-height: $grid-unit-40;
12
12
  display: flex;
@@ -205,6 +205,9 @@ export class PostPublishButton extends Component {
205
205
  }
206
206
  }
207
207
 
208
+ /**
209
+ * Renders the publish button.
210
+ */
208
211
  export default compose( [
209
212
  withSelect( ( select ) => {
210
213
  const {
@@ -10,6 +10,11 @@ import { useViewportMatch } from '@wordpress/compose';
10
10
  */
11
11
  import { store as editorStore } from '../../store';
12
12
 
13
+ /**
14
+ * Renders the label for the publish button.
15
+ *
16
+ * @return {string} The label for the publish button.
17
+ */
13
18
  export default function PublishButtonLabel() {
14
19
  const isSmallerThanMediumViewport = useViewportMatch( 'medium', '<' );
15
20
  const {
@@ -131,6 +131,9 @@ export class PostPublishPanel extends Component {
131
131
  }
132
132
  }
133
133
 
134
+ /**
135
+ * Renders a panel for publishing a post.
136
+ */
134
137
  export default compose( [
135
138
  withSelect( ( select ) => {
136
139
  const { getPostType } = select( coreStore );
@@ -41,4 +41,9 @@
41
41
  padding: 0;
42
42
  margin-bottom: $grid-unit-10;
43
43
  }
44
+
45
+ p.components-base-control__help:has(.components-checkbox-control__help) {
46
+ margin-top: $grid-unit-05;
47
+ }
48
+
44
49
  }
@@ -8,6 +8,14 @@ import { useSelect } from '@wordpress/data';
8
8
  */
9
9
  import { store as editorStore } from '../../store';
10
10
 
11
+ /**
12
+ * Wrapper component that renders its children only if post has a sticky action.
13
+ *
14
+ * @param {Object} props Props.
15
+ * @param {Element} props.children Children to be rendered.
16
+ *
17
+ * @return {Component} The component to be rendered or null if post type is not 'post' or hasStickyAction is false.
18
+ */
11
19
  export default function PostStickyCheck( { children } ) {
12
20
  const { hasStickyAction, postType } = useSelect( ( select ) => {
13
21
  const post = select( editorStore ).getCurrentPost();
@@ -12,6 +12,11 @@ import PostStickyCheck from './check';
12
12
  import { store as editorStore } from '../../store';
13
13
  import PostPanelRow from '../post-panel-row';
14
14
 
15
+ /**
16
+ * Renders the PostSticky component. It provide toggle control for the sticky post feature.
17
+ *
18
+ * @return {Component} The component to be rendered.
19
+ */
15
20
  export default function PostSticky() {
16
21
  const postSticky = useSelect( ( select ) => {
17
22
  return (
@@ -8,14 +8,23 @@ import {
8
8
  import { __ } from '@wordpress/i18n';
9
9
  import { useDispatch, useSelect } from '@wordpress/data';
10
10
  import { useState } from '@wordpress/element';
11
+ import deprecated from '@wordpress/deprecated';
11
12
 
12
13
  /**
13
14
  * Internal dependencies
14
15
  */
15
16
  import { store as editorStore } from '../../store';
16
17
 
17
- // TODO: deprecate..
18
+ /**
19
+ * Renders a button component that allows the user to switch a post to draft status.
20
+ *
21
+ * @return {JSX.Element} The rendered component.
22
+ */
18
23
  export default function PostSwitchToDraftButton() {
24
+ deprecated( 'wp.editor.PostSwitchToDraftButton', {
25
+ since: '6.7',
26
+ version: '6.9',
27
+ } );
19
28
  const [ showConfirmDialog, setShowConfirmDialog ] = useState( false );
20
29
 
21
30
  const { editPost, savePost } = useDispatch( editorStore );
@@ -10,6 +10,11 @@ import { __, _x } from '@wordpress/i18n';
10
10
  import PostPanelRow from '../post-panel-row';
11
11
  import { store as editorStore } from '../../store';
12
12
 
13
+ /**
14
+ * Renders the sync status of a post.
15
+ *
16
+ * @return {JSX.Element|null} The rendered sync status component.
17
+ */
13
18
  export default function PostSyncStatus() {
14
19
  const { syncStatus, postType } = useSelect( ( select ) => {
15
20
  const { getEditedPostAttribute } = select( editorStore );
@@ -9,6 +9,14 @@ import { store as coreStore } from '@wordpress/core-data';
9
9
  */
10
10
  import { store as editorStore } from '../../store';
11
11
 
12
+ /**
13
+ * Renders the children components only if the current post type has taxonomies.
14
+ *
15
+ * @param {Object} props The component props.
16
+ * @param {Element} props.children The children components to render.
17
+ *
18
+ * @return {Component|null} The rendered children components or null if the current post type has no taxonomies.
19
+ */
12
20
  export default function PostTaxonomiesCheck( { children } ) {
13
21
  const hasTaxonomies = useSelect( ( select ) => {
14
22
  const postType = select( editorStore ).getCurrentPostType();
@@ -26,9 +26,12 @@ import MostUsedTerms from './most-used-terms';
26
26
  const EMPTY_ARRAY = [];
27
27
 
28
28
  /**
29
- * Module constants
29
+ * How the max suggestions limit was chosen:
30
+ * - Matches the `per_page` range set by the REST API.
31
+ * - Can't use "unbound" query. The `FormTokenField` needs a fixed number.
32
+ * - Matches default for `FormTokenField`.
30
33
  */
31
- const MAX_TERMS_SUGGESTIONS = 20;
34
+ const MAX_TERMS_SUGGESTIONS = 100;
32
35
  const DEFAULT_QUERY = {
33
36
  per_page: MAX_TERMS_SUGGESTIONS,
34
37
  _fields: 'id,name',
@@ -49,6 +52,14 @@ const termNamesToIds = ( names, terms ) => {
49
52
  .filter( ( id ) => id !== undefined );
50
53
  };
51
54
 
55
+ /**
56
+ * Renders a flat term selector component.
57
+ *
58
+ * @param {Object} props The component props.
59
+ * @param {string} props.slug The slug of the taxonomy.
60
+ *
61
+ * @return {JSX.Element} The rendered flat term selector component.
62
+ */
52
63
  export function FlatTermSelector( { slug } ) {
53
64
  const [ values, setValues ] = useState( [] );
54
65
  const [ search, setSearch ] = useState( '' );
@@ -43,4 +43,12 @@ export function PostTaxonomies( { taxonomyWrapper = identity } ) {
43
43
  } );
44
44
  }
45
45
 
46
+ /**
47
+ * Renders the taxonomies associated with a post.
48
+ *
49
+ * @param {Object} props The component props.
50
+ * @param {Function} props.taxonomyWrapper The wrapper function for each taxonomy component.
51
+ *
52
+ * @return {Array} An array of JSX elements representing the visible taxonomies.
53
+ */
46
54
  export default PostTaxonomies;
@@ -63,4 +63,13 @@ function PostTaxonomies() {
63
63
  );
64
64
  }
65
65
 
66
+ /**
67
+ * Renders a panel for a specific taxonomy.
68
+ *
69
+ * @param {Object} props The component props.
70
+ * @param {Object} props.taxonomy The taxonomy object.
71
+ * @param {Element} props.children The child components.
72
+ *
73
+ * @return {Component} The rendered taxonomy panel.
74
+ */
66
75
  export default PostTaxonomies;
@@ -30,14 +30,12 @@ import usePostTitle from './use-post-title';
30
30
  import PostTypeSupportCheck from '../post-type-support-check';
31
31
 
32
32
  function PostTitle( _, forwardedRef ) {
33
- const { placeholder, hasFixedToolbar } = useSelect( ( select ) => {
33
+ const { placeholder } = useSelect( ( select ) => {
34
34
  const { getSettings } = select( blockEditorStore );
35
- const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } =
36
- getSettings();
35
+ const { titlePlaceholder } = getSettings();
37
36
 
38
37
  return {
39
38
  placeholder: titlePlaceholder,
40
- hasFixedToolbar: _hasFixedToolbar,
41
39
  };
42
40
  }, [] );
43
41
 
@@ -186,7 +184,6 @@ function PostTitle( _, forwardedRef ) {
186
184
  // This same block is used in both the visual and the code editor.
187
185
  const className = clsx( DEFAULT_CLASSNAMES, {
188
186
  'is-selected': isSelected,
189
- 'has-fixed-toolbar': hasFixedToolbar,
190
187
  } );
191
188
 
192
189
  return (
@@ -29,14 +29,12 @@ import usePostTitle from './use-post-title';
29
29
  * @return {Component} The rendered component.
30
30
  */
31
31
  function PostTitleRaw( _, forwardedRef ) {
32
- const { placeholder, hasFixedToolbar } = useSelect( ( select ) => {
32
+ const { placeholder } = useSelect( ( select ) => {
33
33
  const { getSettings } = select( blockEditorStore );
34
- const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } =
35
- getSettings();
34
+ const { titlePlaceholder } = getSettings();
36
35
 
37
36
  return {
38
37
  placeholder: titlePlaceholder,
39
- hasFixedToolbar: _hasFixedToolbar,
40
38
  };
41
39
  }, [] );
42
40
 
@@ -61,7 +59,6 @@ function PostTitleRaw( _, forwardedRef ) {
61
59
  // This same block is used in both the visual and the code editor.
62
60
  const className = clsx( DEFAULT_CLASSNAMES, {
63
61
  'is-selected': isSelected,
64
- 'has-fixed-toolbar': hasFixedToolbar,
65
62
  'is-raw-text': true,
66
63
  } );
67
64
 
@@ -9,6 +9,14 @@ import { store as coreStore } from '@wordpress/core-data';
9
9
  */
10
10
  import { store as editorStore } from '../../store';
11
11
 
12
+ /**
13
+ * Wrapper component that renders its children only if the post can trashed.
14
+ *
15
+ * @param {Object} props - The component props.
16
+ * @param {Element} props.children - The child components to render.
17
+ *
18
+ * @return {Component|null} The rendered child components or null if the post can not trashed.
19
+ */
12
20
  export default function PostTrashCheck( { children } ) {
13
21
  const { canTrashPost } = useSelect( ( select ) => {
14
22
  const { isEditedPostNew, getCurrentPostId, getCurrentPostType } =
@@ -14,6 +14,11 @@ import { useState } from '@wordpress/element';
14
14
  */
15
15
  import { store as editorStore } from '../../store';
16
16
 
17
+ /**
18
+ * Displays the Post Trash Button and Confirm Dialog in the Editor.
19
+ *
20
+ * @return {JSX.Element|null} The rendered PostTrash component.
21
+ */
17
22
  export default function PostTrash() {
18
23
  const { isNew, isDeleting, postId } = useSelect( ( select ) => {
19
24
  const store = select( editorStore );
@@ -55,6 +60,7 @@ export default function PostTrash() {
55
60
  onConfirm={ handleConfirm }
56
61
  onCancel={ () => setShowConfirmDialog( false ) }
57
62
  confirmButtonText={ __( 'Move to trash' ) }
63
+ size="medium"
58
64
  >
59
65
  { __(
60
66
  'Are you sure you want to move this post to the trash?'
@@ -133,6 +133,7 @@ export default function PostVisibility( { onClose } ) {
133
133
  onConfirm={ confirmPrivate }
134
134
  onCancel={ handleDialogCancel }
135
135
  confirmButtonText={ __( 'Publish' ) }
136
+ size="medium"
136
137
  >
137
138
  { __( 'Would you like to privately publish this post now?' ) }
138
139
  </ConfirmDialog>
@@ -33,6 +33,7 @@ import StartTemplateOptions from '../start-template-options';
33
33
  import EditorKeyboardShortcuts from '../global-keyboard-shortcuts';
34
34
  import PatternRenameModal from '../pattern-rename-modal';
35
35
  import PatternDuplicateModal from '../pattern-duplicate-modal';
36
+ import TemplatePartMenuItems from '../template-part-menu-items';
36
37
 
37
38
  const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis );
38
39
  const { PatternsMenuItems } = unlock( editPatternsPrivateApis );
@@ -160,8 +161,21 @@ export const ExperimentalEditorProvider = withRegistryProvider(
160
161
  BlockEditorProviderComponent = ExperimentalBlockEditorProvider,
161
162
  __unstableTemplate: template,
162
163
  } ) => {
163
- const mode = useSelect(
164
- ( select ) => select( editorStore ).getRenderingMode(),
164
+ const { editorSettings, selection, isReady, mode } = useSelect(
165
+ ( select ) => {
166
+ const {
167
+ getEditorSettings,
168
+ getEditorSelection,
169
+ getRenderingMode,
170
+ __unstableIsEditorReady,
171
+ } = select( editorStore );
172
+ return {
173
+ editorSettings: getEditorSettings(),
174
+ isReady: __unstableIsEditorReady(),
175
+ mode: getRenderingMode(),
176
+ selection: getEditorSelection(),
177
+ };
178
+ },
165
179
  []
166
180
  );
167
181
  const shouldRenderTemplate = !! template && mode !== 'post-only';
@@ -187,21 +201,6 @@ export const ExperimentalEditorProvider = withRegistryProvider(
187
201
  rootLevelPost.type,
188
202
  rootLevelPost.slug,
189
203
  ] );
190
- const { editorSettings, selection, isReady } = useSelect(
191
- ( select ) => {
192
- const {
193
- getEditorSettings,
194
- getEditorSelection,
195
- __unstableIsEditorReady,
196
- } = select( editorStore );
197
- return {
198
- editorSettings: getEditorSettings(),
199
- isReady: __unstableIsEditorReady(),
200
- selection: getEditorSelection(),
201
- };
202
- },
203
- []
204
- );
205
204
  const { id, type } = rootLevelPost;
206
205
  const blockEditorSettings = useBlockEditorSettings(
207
206
  editorSettings,
@@ -301,6 +300,7 @@ export const ExperimentalEditorProvider = withRegistryProvider(
301
300
  { ! settings.__unstableIsPreviewMode && (
302
301
  <>
303
302
  <PatternsMenuItems />
303
+ <TemplatePartMenuItems />
304
304
  <ContentOnlySettingsMenu />
305
305
  { mode === 'template-locked' && (
306
306
  <DisableNonPageContentBlocks />
@@ -69,7 +69,7 @@ export default function PostSummary( { onActionPerformed } ) {
69
69
  <PostLastEditedPanel />
70
70
  </VStack>
71
71
  { ! isRemovedPostStatusPanel && (
72
- <VStack spacing={ 2 }>
72
+ <VStack spacing={ 4 }>
73
73
  <VStack spacing={ 1 }>
74
74
  <PostStatusPanel />
75
75
  <PostSchedulePanel />
@@ -52,4 +52,14 @@ function TableOfContents(
52
52
  );
53
53
  }
54
54
 
55
+ /**
56
+ * Renders a table of contents component.
57
+ *
58
+ * @param {Object} props The component props.
59
+ * @param {boolean} props.hasOutlineItemsDisabled Whether outline items are disabled.
60
+ * @param {boolean} props.repositionDropdown Whether to reposition the dropdown.
61
+ * @param {Element.ref} ref The component's ref.
62
+ *
63
+ * @return {JSX.Element} The rendered table of contents component.
64
+ */
55
65
  export default forwardRef( TableOfContents );
@@ -0,0 +1,32 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+ import { store as blockEditorStore } from '@wordpress/block-editor';
6
+ import { MenuItem } from '@wordpress/components';
7
+ import { __ } from '@wordpress/i18n';
8
+
9
+ export default function ConvertToRegularBlocks( { clientId, onClose } ) {
10
+ const { getBlocks } = useSelect( blockEditorStore );
11
+ const { replaceBlocks } = useDispatch( blockEditorStore );
12
+
13
+ const canRemove = useSelect(
14
+ ( select ) => select( blockEditorStore ).canRemoveBlock( clientId ),
15
+ [ clientId ]
16
+ );
17
+
18
+ if ( ! canRemove ) {
19
+ return null;
20
+ }
21
+
22
+ return (
23
+ <MenuItem
24
+ onClick={ () => {
25
+ replaceBlocks( clientId, getBlocks( clientId ) );
26
+ onClose();
27
+ } }
28
+ >
29
+ { __( 'Detach' ) }
30
+ </MenuItem>
31
+ );
32
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useDispatch, useSelect } from '@wordpress/data';
5
+ import { store as blockEditorStore } from '@wordpress/block-editor';
6
+ import { MenuItem } from '@wordpress/components';
7
+ import { createBlock } from '@wordpress/blocks';
8
+ import { __ } from '@wordpress/i18n';
9
+ import { useState } from '@wordpress/element';
10
+ import { store as noticesStore } from '@wordpress/notices';
11
+ import { symbolFilled } from '@wordpress/icons';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import CreateTemplatePartModal from '../create-template-part-modal';
17
+
18
+ export default function ConvertToTemplatePart( { clientIds, blocks } ) {
19
+ const [ isModalOpen, setIsModalOpen ] = useState( false );
20
+ const { replaceBlocks } = useDispatch( blockEditorStore );
21
+ const { createSuccessNotice } = useDispatch( noticesStore );
22
+
23
+ const { canCreate } = useSelect( ( select ) => {
24
+ return {
25
+ canCreate:
26
+ select( blockEditorStore ).canInsertBlockType(
27
+ 'core/template-part'
28
+ ),
29
+ };
30
+ }, [] );
31
+
32
+ if ( ! canCreate ) {
33
+ return null;
34
+ }
35
+
36
+ const onConvert = async ( templatePart ) => {
37
+ replaceBlocks(
38
+ clientIds,
39
+ createBlock( 'core/template-part', {
40
+ slug: templatePart.slug,
41
+ theme: templatePart.theme,
42
+ } )
43
+ );
44
+ createSuccessNotice( __( 'Template part created.' ), {
45
+ type: 'snackbar',
46
+ } );
47
+
48
+ // The modal and this component will be unmounted because of `replaceBlocks` above,
49
+ // so no need to call `closeModal` or `onClose`.
50
+ };
51
+
52
+ return (
53
+ <>
54
+ <MenuItem
55
+ icon={ symbolFilled }
56
+ onClick={ () => {
57
+ setIsModalOpen( true );
58
+ } }
59
+ aria-expanded={ isModalOpen }
60
+ aria-haspopup="dialog"
61
+ >
62
+ { __( 'Create template part' ) }
63
+ </MenuItem>
64
+ { isModalOpen && (
65
+ <CreateTemplatePartModal
66
+ closeModal={ () => {
67
+ setIsModalOpen( false );
68
+ } }
69
+ blocks={ blocks }
70
+ onCreate={ onConvert }
71
+ />
72
+ ) }
73
+ </>
74
+ );
75
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import {
6
+ BlockSettingsMenuControls,
7
+ store as blockEditorStore,
8
+ } from '@wordpress/block-editor';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import ConvertToRegularBlocks from './convert-to-regular';
14
+ import ConvertToTemplatePart from './convert-to-template-part';
15
+
16
+ export default function TemplatePartMenuItems() {
17
+ return (
18
+ <BlockSettingsMenuControls>
19
+ { ( { selectedClientIds, onClose } ) => (
20
+ <TemplatePartConverterMenuItem
21
+ clientIds={ selectedClientIds }
22
+ onClose={ onClose }
23
+ />
24
+ ) }
25
+ </BlockSettingsMenuControls>
26
+ );
27
+ }
28
+
29
+ function TemplatePartConverterMenuItem( { clientIds, onClose } ) {
30
+ const { isContentOnly, blocks } = useSelect(
31
+ ( select ) => {
32
+ const { getBlocksByClientId, getBlockEditingMode } =
33
+ select( blockEditorStore );
34
+ return {
35
+ blocks: getBlocksByClientId( clientIds ),
36
+ isContentOnly:
37
+ clientIds.length === 1 &&
38
+ getBlockEditingMode( clientIds[ 0 ] ) === 'contentOnly',
39
+ };
40
+ },
41
+ [ clientIds ]
42
+ );
43
+
44
+ // Do not show the convert button if the block is in content-only mode.
45
+ if ( isContentOnly ) {
46
+ return null;
47
+ }
48
+
49
+ // Allow converting a single template part to standard blocks.
50
+ if ( blocks.length === 1 && blocks[ 0 ]?.name === 'core/template-part' ) {
51
+ return (
52
+ <ConvertToRegularBlocks
53
+ clientId={ clientIds[ 0 ] }
54
+ onClose={ onClose }
55
+ />
56
+ );
57
+ }
58
+ return <ConvertToTemplatePart clientIds={ clientIds } blocks={ blocks } />;
59
+ }
@@ -0,0 +1,3 @@
1
+ export default function TemplatePartMenuItems() {
2
+ return null;
3
+ }
@@ -51,6 +51,7 @@ export default function TemplateValidationNotice() {
51
51
  synchronizeTemplate();
52
52
  } }
53
53
  onCancel={ () => setShowConfirmDialog( false ) }
54
+ size="medium"
54
55
  >
55
56
  { __(
56
57
  'Resetting the template may result in loss of content, do you want to continue?'
@@ -9,6 +9,15 @@ import { store as coreStore } from '@wordpress/core-data';
9
9
  */
10
10
  import { store as editorStore } from '../../store';
11
11
 
12
+ /**
13
+ * Checks if the current theme supports specific features and renders the children if supported.
14
+ *
15
+ * @param {Object} props The component props.
16
+ * @param {Element} props.children The children to render if the theme supports the specified features.
17
+ * @param {string|string[]} props.supportKeys The key(s) of the theme support(s) to check.
18
+ *
19
+ * @return {JSX.Element|null} The rendered children if the theme supports the specified features, otherwise null.
20
+ */
12
21
  export default function ThemeSupportCheck( { children, supportKeys } ) {
13
22
  const { postType, themeSupports } = useSelect( ( select ) => {
14
23
  return {
@@ -20,6 +20,11 @@ import { store as editorStore } from '../../store';
20
20
  */
21
21
  const AVERAGE_READING_RATE = 189;
22
22
 
23
+ /**
24
+ * Component for showing Time To Read in Content.
25
+ *
26
+ * @return {JSX.Element} The rendered TimeToRead component.
27
+ */
23
28
  export default function TimeToRead() {
24
29
  const content = useSelect(
25
30
  ( select ) => select( editorStore ).getEditedPostAttribute( 'content' ),
@@ -80,6 +80,7 @@ export default function EditTemplateBlocksNotification( { contentRef } ) {
80
80
  } );
81
81
  } }
82
82
  onCancel={ () => setIsDialogOpen( false ) }
83
+ size="medium"
83
84
  >
84
85
  { __(
85
86
  'You’ve tried to select a block that is part of a template, which may be used on other posts and pages. Would you like to edit the template?'
@@ -10,6 +10,11 @@ import { count as wordCount } from '@wordpress/wordcount';
10
10
  */
11
11
  import { store as editorStore } from '../../store';
12
12
 
13
+ /**
14
+ * Renders the word count of the post content.
15
+ *
16
+ * @return {JSX.Element|null} The rendered WordCount component.
17
+ */
13
18
  export default function WordCount() {
14
19
  const content = useSelect(
15
20
  ( select ) => select( editorStore ).getEditedPostAttribute( 'content' ),