@wordpress/editor 14.4.0 → 14.5.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 (222) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/bindings/post-meta.js +12 -0
  3. package/build/bindings/post-meta.js.map +1 -1
  4. package/build/components/blog-title/index.js +1 -1
  5. package/build/components/blog-title/index.js.map +1 -1
  6. package/build/components/commands/index.js +8 -2
  7. package/build/components/commands/index.js.map +1 -1
  8. package/build/components/document-bar/index.js +1 -1
  9. package/build/components/document-bar/index.js.map +1 -1
  10. package/build/components/header/index.js +2 -3
  11. package/build/components/header/index.js.map +1 -1
  12. package/build/components/page-attributes/parent.js +6 -2
  13. package/build/components/page-attributes/parent.js.map +1 -1
  14. package/build/components/post-actions/actions.js +38 -344
  15. package/build/components/post-actions/actions.js.map +1 -1
  16. package/build/components/post-actions/index.js +16 -6
  17. package/build/components/post-actions/index.js.map +1 -1
  18. package/build/components/post-author/hook.js +10 -3
  19. package/build/components/post-author/hook.js.map +1 -1
  20. package/build/components/post-author/panel.js +2 -1
  21. package/build/components/post-author/panel.js.map +1 -1
  22. package/build/components/post-card-panel/index.js +1 -1
  23. package/build/components/post-card-panel/index.js.map +1 -1
  24. package/build/components/post-comments/index.js +6 -20
  25. package/build/components/post-comments/index.js.map +1 -1
  26. package/build/components/post-status/index.js +17 -41
  27. package/build/components/post-status/index.js.map +1 -1
  28. package/build/components/post-template/create-new-template-modal.js +3 -0
  29. package/build/components/post-template/create-new-template-modal.js.map +1 -1
  30. package/build/components/post-url/panel.js +3 -2
  31. package/build/components/post-url/panel.js.map +1 -1
  32. package/build/components/preview-dropdown/index.js +82 -17
  33. package/build/components/preview-dropdown/index.js.map +1 -1
  34. package/build/components/provider/disable-non-page-content-blocks.js +14 -18
  35. package/build/components/provider/disable-non-page-content-blocks.js.map +1 -1
  36. package/build/components/site-discussion/index.js +6 -20
  37. package/build/components/site-discussion/index.js.map +1 -1
  38. package/build/components/template-content-panel/index.js +14 -12
  39. package/build/components/template-content-panel/index.js.map +1 -1
  40. package/build/components/visual-editor/index.js +2 -1
  41. package/build/components/visual-editor/index.js.map +1 -1
  42. package/build/dataviews/actions/export-pattern.native.js +9 -0
  43. package/build/dataviews/actions/export-pattern.native.js.map +1 -0
  44. package/build/dataviews/actions/permanently-delete-post.js +107 -0
  45. package/build/dataviews/actions/permanently-delete-post.js.map +1 -0
  46. package/build/dataviews/actions/restore-post.js +112 -0
  47. package/build/dataviews/actions/restore-post.js.map +1 -0
  48. package/build/dataviews/actions/trash-post.js +142 -0
  49. package/build/dataviews/actions/trash-post.js.map +1 -0
  50. package/build/dataviews/store/private-actions.js +45 -0
  51. package/build/dataviews/store/private-actions.js.map +1 -1
  52. package/build/dataviews/store/private-selectors.js +10 -10
  53. package/build/dataviews/store/private-selectors.js.map +1 -1
  54. package/build/dataviews/store/reducer.js +15 -1
  55. package/build/dataviews/store/reducer.js.map +1 -1
  56. package/build/dataviews/types.js.map +1 -1
  57. package/build/private-apis.js +0 -2
  58. package/build/private-apis.js.map +1 -1
  59. package/build/store/actions.js +16 -2
  60. package/build/store/actions.js.map +1 -1
  61. package/build/store/private-actions.js +8 -1
  62. package/build/store/private-actions.js.map +1 -1
  63. package/build/store/private-selectors.js +33 -2
  64. package/build/store/private-selectors.js.map +1 -1
  65. package/build-module/bindings/post-meta.js +12 -0
  66. package/build-module/bindings/post-meta.js.map +1 -1
  67. package/build-module/components/blog-title/index.js +1 -1
  68. package/build-module/components/blog-title/index.js.map +1 -1
  69. package/build-module/components/commands/index.js +8 -2
  70. package/build-module/components/commands/index.js.map +1 -1
  71. package/build-module/components/document-bar/index.js +1 -1
  72. package/build-module/components/document-bar/index.js.map +1 -1
  73. package/build-module/components/header/index.js +2 -3
  74. package/build-module/components/header/index.js.map +1 -1
  75. package/build-module/components/page-attributes/parent.js +7 -3
  76. package/build-module/components/page-attributes/parent.js.map +1 -1
  77. package/build-module/components/post-actions/actions.js +44 -350
  78. package/build-module/components/post-actions/actions.js.map +1 -1
  79. package/build-module/components/post-actions/index.js +16 -6
  80. package/build-module/components/post-actions/index.js.map +1 -1
  81. package/build-module/components/post-author/hook.js +10 -3
  82. package/build-module/components/post-author/hook.js.map +1 -1
  83. package/build-module/components/post-author/panel.js +2 -1
  84. package/build-module/components/post-author/panel.js.map +1 -1
  85. package/build-module/components/post-card-panel/index.js +1 -1
  86. package/build-module/components/post-card-panel/index.js.map +1 -1
  87. package/build-module/components/post-comments/index.js +7 -23
  88. package/build-module/components/post-comments/index.js.map +1 -1
  89. package/build-module/components/post-status/index.js +19 -43
  90. package/build-module/components/post-status/index.js.map +1 -1
  91. package/build-module/components/post-template/create-new-template-modal.js +3 -0
  92. package/build-module/components/post-template/create-new-template-modal.js.map +1 -1
  93. package/build-module/components/post-url/panel.js +4 -5
  94. package/build-module/components/post-url/panel.js.map +1 -1
  95. package/build-module/components/preview-dropdown/index.js +84 -19
  96. package/build-module/components/preview-dropdown/index.js.map +1 -1
  97. package/build-module/components/provider/disable-non-page-content-blocks.js +15 -19
  98. package/build-module/components/provider/disable-non-page-content-blocks.js.map +1 -1
  99. package/build-module/components/site-discussion/index.js +7 -21
  100. package/build-module/components/site-discussion/index.js.map +1 -1
  101. package/build-module/components/template-content-panel/index.js +15 -13
  102. package/build-module/components/template-content-panel/index.js.map +1 -1
  103. package/build-module/components/visual-editor/index.js +2 -1
  104. package/build-module/components/visual-editor/index.js.map +1 -1
  105. package/build-module/dataviews/actions/export-pattern.native.js +3 -0
  106. package/build-module/dataviews/actions/export-pattern.native.js.map +1 -0
  107. package/build-module/dataviews/actions/permanently-delete-post.js +99 -0
  108. package/build-module/dataviews/actions/permanently-delete-post.js.map +1 -0
  109. package/build-module/dataviews/actions/restore-post.js +104 -0
  110. package/build-module/dataviews/actions/restore-post.js.map +1 -0
  111. package/build-module/dataviews/actions/trash-post.js +135 -0
  112. package/build-module/dataviews/actions/trash-post.js.map +1 -0
  113. package/build-module/dataviews/store/private-actions.js +40 -0
  114. package/build-module/dataviews/store/private-actions.js.map +1 -1
  115. package/build-module/dataviews/store/private-selectors.js +8 -9
  116. package/build-module/dataviews/store/private-selectors.js.map +1 -1
  117. package/build-module/dataviews/store/reducer.js +15 -1
  118. package/build-module/dataviews/store/reducer.js.map +1 -1
  119. package/build-module/dataviews/types.js.map +1 -1
  120. package/build-module/private-apis.js +0 -2
  121. package/build-module/private-apis.js.map +1 -1
  122. package/build-module/store/actions.js +16 -2
  123. package/build-module/store/actions.js.map +1 -1
  124. package/build-module/store/private-actions.js +8 -1
  125. package/build-module/store/private-actions.js.map +1 -1
  126. package/build-module/store/private-selectors.js +32 -2
  127. package/build-module/store/private-selectors.js.map +1 -1
  128. package/build-style/style-rtl.css +19 -3
  129. package/build-style/style.css +19 -3
  130. package/build-types/bindings/post-meta.d.ts +6 -0
  131. package/build-types/bindings/post-meta.d.ts.map +1 -1
  132. package/build-types/components/commands/index.d.ts.map +1 -1
  133. package/build-types/components/header/index.d.ts.map +1 -1
  134. package/build-types/components/page-attributes/parent.d.ts.map +1 -1
  135. package/build-types/components/post-actions/actions.d.ts.map +1 -1
  136. package/build-types/components/post-actions/index.d.ts.map +1 -1
  137. package/build-types/components/post-author/hook.d.ts +1 -1
  138. package/build-types/components/post-author/hook.d.ts.map +1 -1
  139. package/build-types/components/post-author/panel.d.ts.map +1 -1
  140. package/build-types/components/post-comments/index.d.ts.map +1 -1
  141. package/build-types/components/post-status/index.d.ts +2 -1
  142. package/build-types/components/post-status/index.d.ts.map +1 -1
  143. package/build-types/components/post-template/create-new-template-modal.d.ts.map +1 -1
  144. package/build-types/components/post-url/panel.d.ts.map +1 -1
  145. package/build-types/components/preview-dropdown/index.d.ts.map +1 -1
  146. package/build-types/components/provider/disable-non-page-content-blocks.d.ts.map +1 -1
  147. package/build-types/components/site-discussion/index.d.ts.map +1 -1
  148. package/build-types/components/template-content-panel/index.d.ts.map +1 -1
  149. package/build-types/components/visual-editor/index.d.ts.map +1 -1
  150. package/build-types/dataviews/actions/export-pattern.native.d.ts +3 -0
  151. package/build-types/dataviews/actions/export-pattern.native.d.ts.map +1 -0
  152. package/build-types/dataviews/actions/permanently-delete-post.d.ts +5 -0
  153. package/build-types/dataviews/actions/permanently-delete-post.d.ts.map +1 -0
  154. package/build-types/dataviews/actions/restore-post.d.ts +5 -0
  155. package/build-types/dataviews/actions/restore-post.d.ts.map +1 -0
  156. package/build-types/dataviews/actions/trash-post.d.ts +5 -0
  157. package/build-types/dataviews/actions/trash-post.d.ts.map +1 -0
  158. package/build-types/dataviews/store/private-actions.d.ts +8 -3
  159. package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
  160. package/build-types/dataviews/store/private-selectors.d.ts +2 -1
  161. package/build-types/dataviews/store/private-selectors.d.ts.map +1 -1
  162. package/build-types/dataviews/store/reducer.d.ts +4 -1
  163. package/build-types/dataviews/store/reducer.d.ts.map +1 -1
  164. package/build-types/dataviews/types.d.ts +9 -0
  165. package/build-types/dataviews/types.d.ts.map +1 -1
  166. package/build-types/private-apis.d.ts.map +1 -1
  167. package/build-types/store/actions.d.ts.map +1 -1
  168. package/build-types/store/private-actions.d.ts.map +1 -1
  169. package/build-types/store/private-selectors.d.ts +11 -0
  170. package/build-types/store/private-selectors.d.ts.map +1 -1
  171. package/build-types/store/reducer.d.ts +1 -0
  172. package/build-types/store/reducer.d.ts.map +1 -1
  173. package/package.json +36 -36
  174. package/src/bindings/post-meta.js +20 -0
  175. package/src/components/blog-title/index.js +1 -1
  176. package/src/components/commands/index.js +4 -2
  177. package/src/components/document-bar/index.js +1 -1
  178. package/src/components/document-bar/style.scss +1 -1
  179. package/src/components/editor-interface/style.scss +5 -0
  180. package/src/components/header/index.js +1 -2
  181. package/src/components/list-view-sidebar/style.scss +4 -0
  182. package/src/components/page-attributes/parent.js +25 -7
  183. package/src/components/post-actions/actions.js +47 -470
  184. package/src/components/post-actions/index.js +19 -7
  185. package/src/components/post-author/hook.js +11 -3
  186. package/src/components/post-author/panel.js +3 -1
  187. package/src/components/post-card-panel/index.js +1 -1
  188. package/src/components/post-comments/index.js +7 -20
  189. package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +2 -2
  190. package/src/components/post-status/index.js +11 -41
  191. package/src/components/post-template/create-new-template-modal.js +7 -1
  192. package/src/components/post-url/panel.js +8 -2
  193. package/src/components/preview-dropdown/index.js +113 -35
  194. package/src/components/preview-dropdown/style.scss +5 -0
  195. package/src/components/provider/disable-non-page-content-blocks.js +27 -24
  196. package/src/components/site-discussion/index.js +7 -19
  197. package/src/components/template-content-panel/index.js +36 -21
  198. package/src/components/visual-editor/index.js +8 -6
  199. package/src/components/visual-editor/style.scss +1 -3
  200. package/src/dataviews/actions/export-pattern.native.tsx +3 -0
  201. package/src/dataviews/actions/permanently-delete-post.tsx +116 -0
  202. package/src/dataviews/actions/restore-post.tsx +134 -0
  203. package/src/dataviews/actions/trash-post.tsx +196 -0
  204. package/src/dataviews/store/private-actions.ts +68 -0
  205. package/src/dataviews/store/private-selectors.ts +9 -17
  206. package/src/dataviews/store/reducer.ts +20 -1
  207. package/src/dataviews/types.ts +11 -0
  208. package/src/private-apis.js +0 -2
  209. package/src/store/actions.js +36 -13
  210. package/src/store/private-actions.js +8 -4
  211. package/src/store/private-selectors.js +45 -2
  212. package/src/store/test/private-selectors.js +78 -0
  213. package/tsconfig.tsbuildinfo +1 -1
  214. package/build/dataviews/actions/index.js +0 -32
  215. package/build/dataviews/actions/index.js.map +0 -1
  216. package/build-module/dataviews/actions/index.js +0 -24
  217. package/build-module/dataviews/actions/index.js.map +0 -1
  218. package/build-types/dataviews/actions/index.d.ts +0 -2
  219. package/build-types/dataviews/actions/index.d.ts.map +0 -1
  220. package/src/components/document-outline/test/__snapshots__/index.js.snap +0 -111
  221. package/src/components/document-outline/test/index.js +0 -185
  222. package/src/dataviews/actions/index.ts +0 -25
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
+ import { __ } from '@wordpress/i18n';
4
5
  import { useMemo } from '@wordpress/element';
5
6
  import { useSelect } from '@wordpress/data';
6
7
  import { decodeEntities } from '@wordpress/html-entities';
@@ -46,17 +47,24 @@ export function useAuthorsQuery( search ) {
46
47
  ( { value } ) => postAuthor?.id === value
47
48
  );
48
49
 
50
+ let currentAuthor = [];
49
51
  if ( foundAuthor < 0 && postAuthor ) {
50
- return [
52
+ currentAuthor = [
51
53
  {
52
54
  value: postAuthor.id,
53
55
  label: decodeEntities( postAuthor.name ),
54
56
  },
55
- ...fetchedAuthors,
57
+ ];
58
+ } else if ( foundAuthor < 0 && ! postAuthor ) {
59
+ currentAuthor = [
60
+ {
61
+ value: 0,
62
+ label: __( '(No author)' ),
63
+ },
56
64
  ];
57
65
  }
58
66
 
59
- return fetchedAuthors;
67
+ return [ ...currentAuthor, ...fetchedAuthors ];
60
68
  }, [ authors, postAuthor ] );
61
69
 
62
70
  return { authorId, authorOptions, postAuthor };
@@ -4,6 +4,7 @@
4
4
  import { __, sprintf } from '@wordpress/i18n';
5
5
  import { Button, Dropdown } from '@wordpress/components';
6
6
  import { useState, useMemo } from '@wordpress/element';
7
+ import { decodeEntities } from '@wordpress/html-entities';
7
8
  import { __experimentalInspectorPopoverHeader as InspectorPopoverHeader } from '@wordpress/block-editor';
8
9
 
9
10
  /**
@@ -16,7 +17,8 @@ import { useAuthorsQuery } from './hook';
16
17
 
17
18
  function PostAuthorToggle( { isOpen, onClick } ) {
18
19
  const { postAuthor } = useAuthorsQuery();
19
- const authorName = postAuthor?.name || '';
20
+ const authorName =
21
+ decodeEntities( postAuthor?.name ) || __( '(No author)' );
20
22
  return (
21
23
  <Button
22
24
  size="compact"
@@ -101,7 +101,7 @@ export default function PostCardPanel( { actions } ) {
101
101
  as="h2"
102
102
  lineHeight="20px"
103
103
  >
104
- { title ? decodeEntities( title ) : __( 'No Title' ) }
104
+ { title ? decodeEntities( title ) : __( 'No title' ) }
105
105
  { isFrontPage && (
106
106
  <span className="editor-post-card-panel__title-badge">
107
107
  { __( 'Homepage' ) }
@@ -4,7 +4,6 @@
4
4
  import { __, _x } from '@wordpress/i18n';
5
5
  import {
6
6
  RadioControl,
7
- __experimentalText as Text,
8
7
  __experimentalVStack as VStack,
9
8
  } from '@wordpress/components';
10
9
  import { useDispatch, useSelect } from '@wordpress/data';
@@ -16,29 +15,17 @@ import { store as editorStore } from '../../store';
16
15
 
17
16
  const COMMENT_OPTIONS = [
18
17
  {
19
- label: (
20
- <>
21
- { _x( 'Open', 'Adjective: e.g. "Comments are open"' ) }
22
- <Text variant="muted" size={ 12 }>
23
- { __( 'Visitors can add new comments and replies.' ) }
24
- </Text>
25
- </>
26
- ),
18
+ label: _x( 'Open', 'Adjective: e.g. "Comments are open"' ),
27
19
  value: 'open',
20
+ description: __( 'Visitors can add new comments and replies.' ),
28
21
  },
29
22
  {
30
- label: (
31
- <>
32
- { __( 'Closed' ) }
33
- <Text variant="muted" size={ 12 }>
34
- { __( 'Visitors cannot add new comments or replies.' ) }
35
- </Text>
36
- <Text variant="muted" size={ 12 }>
37
- { __( 'Existing comments remain visible.' ) }
38
- </Text>
39
- </>
40
- ),
23
+ label: __( 'Closed' ),
41
24
  value: 'closed',
25
+ description: [
26
+ __( 'Visitors cannot add new comments or replies.' ),
27
+ __( 'Existing comments remain visible.' ),
28
+ ].join( ' ' ),
42
29
  },
43
30
  ];
44
31
 
@@ -22,7 +22,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
22
22
  font-weight: 500;
23
23
  line-height: 1.4;
24
24
  text-transform: uppercase;
25
- display: inline-block;
25
+ display: block;
26
26
  margin-bottom: calc(4px * 2);
27
27
  padding: 0;
28
28
  }
@@ -214,7 +214,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
214
214
  font-weight: 500;
215
215
  line-height: 1.4;
216
216
  text-transform: uppercase;
217
- display: inline-block;
217
+ display: block;
218
218
  margin-bottom: calc(4px * 2);
219
219
  padding: 0;
220
220
  }
@@ -5,7 +5,6 @@ import {
5
5
  Button,
6
6
  CheckboxControl,
7
7
  Dropdown,
8
- __experimentalText as Text,
9
8
  __experimentalVStack as VStack,
10
9
  TextControl,
11
10
  RadioControl,
@@ -49,59 +48,29 @@ const postStatusesInfo = {
49
48
 
50
49
  export const STATUS_OPTIONS = [
51
50
  {
52
- label: (
53
- <>
54
- { __( 'Draft' ) }
55
- <Text variant="muted" size={ 12 }>
56
- { __( 'Not ready to publish.' ) }
57
- </Text>
58
- </>
59
- ),
51
+ label: __( 'Draft' ),
60
52
  value: 'draft',
53
+ description: __( 'Not ready to publish.' ),
61
54
  },
62
55
  {
63
- label: (
64
- <>
65
- { __( 'Pending' ) }
66
- <Text variant="muted" size={ 12 }>
67
- { __( 'Waiting for review before publishing.' ) }
68
- </Text>
69
- </>
70
- ),
56
+ label: __( 'Pending' ),
71
57
  value: 'pending',
58
+ description: __( 'Waiting for review before publishing.' ),
72
59
  },
73
60
  {
74
- label: (
75
- <>
76
- { __( 'Private' ) }
77
- <Text variant="muted" size={ 12 }>
78
- { __( 'Only visible to site admins and editors.' ) }
79
- </Text>
80
- </>
81
- ),
61
+ label: __( 'Private' ),
82
62
  value: 'private',
63
+ description: __( 'Only visible to site admins and editors.' ),
83
64
  },
84
65
  {
85
- label: (
86
- <>
87
- { __( 'Scheduled' ) }
88
- <Text variant="muted" size={ 12 }>
89
- { __( 'Publish automatically on a chosen date.' ) }
90
- </Text>
91
- </>
92
- ),
66
+ label: __( 'Scheduled' ),
93
67
  value: 'future',
68
+ description: __( 'Publish automatically on a chosen date.' ),
94
69
  },
95
70
  {
96
- label: (
97
- <>
98
- { __( 'Published' ) }
99
- <Text variant="muted" size={ 12 }>
100
- { __( 'Visible to everyone.' ) }
101
- </Text>
102
- </>
103
- ),
71
+ label: __( 'Published' ),
104
72
  value: 'publish',
73
+ description: __( 'Visible to everyone.' ),
105
74
  },
106
75
  ];
107
76
 
@@ -285,6 +254,7 @@ export default function PostStatus() {
285
254
  id={ passwordInputId }
286
255
  __next40pxDefaultSize
287
256
  __nextHasNoMarginBottom
257
+ maxLength={ 255 }
288
258
  />
289
259
  </div>
290
260
  ) }
@@ -118,6 +118,7 @@ export default function CreateNewTemplateModal( { onClose } ) {
118
118
  >
119
119
  <VStack spacing="3">
120
120
  <TextControl
121
+ __next40pxDefaultSize
121
122
  __nextHasNoMarginBottom
122
123
  label={ __( 'Name' ) }
123
124
  value={ title }
@@ -129,11 +130,16 @@ export default function CreateNewTemplateModal( { onClose } ) {
129
130
  ) }
130
131
  />
131
132
  <HStack justify="right">
132
- <Button variant="tertiary" onClick={ cancel }>
133
+ <Button
134
+ __next40pxDefaultSize
135
+ variant="tertiary"
136
+ onClick={ cancel }
137
+ >
133
138
  { __( 'Cancel' ) }
134
139
  </Button>
135
140
 
136
141
  <Button
142
+ __next40pxDefaultSize
137
143
  variant="primary"
138
144
  type="submit"
139
145
  isBusy={ isBusy }
@@ -3,7 +3,11 @@
3
3
  */
4
4
  import { useMemo, useState } from '@wordpress/element';
5
5
  import { useSelect } from '@wordpress/data';
6
- import { Dropdown, Button } from '@wordpress/components';
6
+ import {
7
+ Dropdown,
8
+ Button,
9
+ __experimentalTruncate as Truncate,
10
+ } from '@wordpress/components';
7
11
  import { __, sprintf } from '@wordpress/i18n';
8
12
  import { safeDecodeURIComponent } from '@wordpress/url';
9
13
  import { store as coreStore } from '@wordpress/core-data';
@@ -86,7 +90,9 @@ function PostURLToggle( { isOpen, onClick } ) {
86
90
  aria-label={ sprintf( __( 'Change link: %s' ), decodedSlug ) }
87
91
  onClick={ onClick }
88
92
  >
89
- { isFrontPage ? postLink : <>/{ decodedSlug }</> }
93
+ <Truncate numberOfLines={ 1 }>
94
+ { isFrontPage ? postLink : `/${ decodedSlug }` }
95
+ </Truncate>
90
96
  </Button>
91
97
  );
92
98
  }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import clsx from 'clsx';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
@@ -6,14 +11,17 @@ import {
6
11
  DropdownMenu,
7
12
  MenuGroup,
8
13
  MenuItem,
14
+ MenuItemsChoice,
9
15
  VisuallyHidden,
10
16
  Icon,
11
17
  } from '@wordpress/components';
12
18
  import { __ } from '@wordpress/i18n';
13
- import { check, desktop, mobile, tablet, external } from '@wordpress/icons';
19
+ import { desktop, mobile, tablet, external } from '@wordpress/icons';
14
20
  import { useSelect, useDispatch } from '@wordpress/data';
15
21
  import { store as coreStore } from '@wordpress/core-data';
22
+ import { useEffect, useRef } from '@wordpress/element';
16
23
  import { store as preferencesStore } from '@wordpress/preferences';
24
+ import { store as blockEditorStore } from '@wordpress/block-editor';
17
25
 
18
26
  /**
19
27
  * Internal dependencies
@@ -22,21 +30,50 @@ import { store as editorStore } from '../../store';
22
30
  import PostPreviewButton from '../post-preview-button';
23
31
 
24
32
  export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
25
- const { deviceType, homeUrl, isTemplate, isViewable, showIconLabels } =
26
- useSelect( ( select ) => {
27
- const { getDeviceType, getCurrentPostType } = select( editorStore );
28
- const { getUnstableBase, getPostType } = select( coreStore );
29
- const { get } = select( preferencesStore );
30
- const _currentPostType = getCurrentPostType();
31
- return {
32
- deviceType: getDeviceType(),
33
- homeUrl: getUnstableBase()?.home,
34
- isTemplate: _currentPostType === 'wp_template',
35
- isViewable: getPostType( _currentPostType )?.viewable ?? false,
36
- showIconLabels: get( 'core', 'showIconLabels' ),
37
- };
38
- }, [] );
33
+ const {
34
+ deviceType,
35
+ editorMode,
36
+ homeUrl,
37
+ isTemplate,
38
+ isViewable,
39
+ showIconLabels,
40
+ } = useSelect( ( select ) => {
41
+ const { getDeviceType, getCurrentPostType } = select( editorStore );
42
+ const { getUnstableBase, getPostType } = select( coreStore );
43
+ const { get } = select( preferencesStore );
44
+ const { __unstableGetEditorMode } = select( blockEditorStore );
45
+ const _currentPostType = getCurrentPostType();
46
+ return {
47
+ deviceType: getDeviceType(),
48
+ editorMode: __unstableGetEditorMode(),
49
+ homeUrl: getUnstableBase()?.home,
50
+ isTemplate: _currentPostType === 'wp_template',
51
+ isViewable: getPostType( _currentPostType )?.viewable ?? false,
52
+ showIconLabels: get( 'core', 'showIconLabels' ),
53
+ };
54
+ }, [] );
39
55
  const { setDeviceType } = useDispatch( editorStore );
56
+ const { __unstableSetEditorMode } = useDispatch( blockEditorStore );
57
+
58
+ /**
59
+ * Save the original editing mode in a ref to restore it when we exit zoom out.
60
+ */
61
+ const originalEditingMode = useRef( editorMode );
62
+ useEffect( () => {
63
+ if ( editorMode !== 'zoom-out' ) {
64
+ originalEditingMode.current = editorMode;
65
+ }
66
+
67
+ return () => {
68
+ if (
69
+ editorMode === 'zoom-out' &&
70
+ editorMode !== originalEditingMode.current
71
+ ) {
72
+ __unstableSetEditorMode( originalEditingMode.current );
73
+ }
74
+ };
75
+ }, [ editorMode, __unstableSetEditorMode ] );
76
+
40
77
  const isMobile = useViewportMatch( 'medium', '<' );
41
78
  if ( isMobile ) {
42
79
  return null;
@@ -47,6 +84,7 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
47
84
  };
48
85
  const toggleProps = {
49
86
  className: 'editor-preview-dropdown__toggle',
87
+ iconPosition: 'right',
50
88
  size: 'compact',
51
89
  showTooltip: ! showIconLabels,
52
90
  disabled,
@@ -57,42 +95,81 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
57
95
  };
58
96
 
59
97
  const deviceIcons = {
98
+ desktop,
60
99
  mobile,
61
100
  tablet,
62
- desktop,
101
+ };
102
+
103
+ /**
104
+ * The choices for the device type.
105
+ *
106
+ * @type {Array}
107
+ */
108
+ const choices = [
109
+ {
110
+ value: 'Desktop',
111
+ label: __( 'Desktop' ),
112
+ icon: desktop,
113
+ },
114
+ {
115
+ value: 'ZoomOut',
116
+ label: __( 'Desktop (50%)' ),
117
+ icon: desktop,
118
+ },
119
+ {
120
+ value: 'Tablet',
121
+ label: __( 'Tablet' ),
122
+ icon: tablet,
123
+ },
124
+ {
125
+ value: 'Mobile',
126
+ label: __( 'Mobile' ),
127
+ icon: mobile,
128
+ },
129
+ ];
130
+
131
+ const previewValue = editorMode === 'zoom-out' ? 'ZoomOut' : deviceType;
132
+
133
+ /**
134
+ * Handles the selection of a device type.
135
+ *
136
+ * @param {string} value The device type.
137
+ */
138
+ const onSelect = ( value ) => {
139
+ let newEditorMode = originalEditingMode.current;
140
+
141
+ if ( value === 'ZoomOut' ) {
142
+ newEditorMode = 'zoom-out';
143
+ setDeviceType( 'Desktop' );
144
+ } else {
145
+ setDeviceType( value );
146
+ }
147
+
148
+ __unstableSetEditorMode( newEditorMode );
63
149
  };
64
150
 
65
151
  return (
66
152
  <DropdownMenu
67
- className="editor-preview-dropdown"
153
+ className={ clsx(
154
+ 'editor-preview-dropdown',
155
+ `editor-preview-dropdown--${ deviceType.toLowerCase() }`
156
+ ) }
68
157
  popoverProps={ popoverProps }
69
158
  toggleProps={ toggleProps }
70
159
  menuProps={ menuProps }
71
160
  icon={ deviceIcons[ deviceType.toLowerCase() ] }
161
+ text={ editorMode === 'zoom-out' ? __( '50%' ) : undefined }
72
162
  label={ __( 'View' ) }
73
163
  disableOpenOnArrowDown={ disabled }
74
164
  >
75
165
  { ( { onClose } ) => (
76
166
  <>
77
167
  <MenuGroup>
78
- <MenuItem
79
- onClick={ () => setDeviceType( 'Desktop' ) }
80
- icon={ deviceType === 'Desktop' && check }
81
- >
82
- { __( 'Desktop' ) }
83
- </MenuItem>
84
- <MenuItem
85
- onClick={ () => setDeviceType( 'Tablet' ) }
86
- icon={ deviceType === 'Tablet' && check }
87
- >
88
- { __( 'Tablet' ) }
89
- </MenuItem>
90
- <MenuItem
91
- onClick={ () => setDeviceType( 'Mobile' ) }
92
- icon={ deviceType === 'Mobile' && check }
93
- >
94
- { __( 'Mobile' ) }
95
- </MenuItem>
168
+ <MenuItemsChoice
169
+ choices={ choices }
170
+ value={ previewValue }
171
+ onSelect={ onSelect }
172
+ />
96
173
  </MenuGroup>
97
174
  { isTemplate && (
98
175
  <MenuGroup>
@@ -118,6 +195,7 @@ export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
118
195
  className="editor-preview-dropdown__button-external"
119
196
  role="menuitem"
120
197
  forceIsAutosaveable={ forceIsAutosaveable }
198
+ aria-label={ __( 'Preview in new tab' ) }
121
199
  textContent={
122
200
  <>
123
201
  { __( 'Preview in new tab' ) }
@@ -1,3 +1,8 @@
1
+ .editor-preview-dropdown .editor-preview-dropdown__toggle.has-icon.has-text {
2
+ padding-right: 4px;
3
+ padding-left: 6px;
4
+ }
5
+
1
6
  .editor-preview-dropdown__button-external {
2
7
  width: 100%;
3
8
  display: flex;
@@ -3,14 +3,19 @@
3
3
  */
4
4
  import { useSelect, useRegistry } from '@wordpress/data';
5
5
  import { store as blockEditorStore } from '@wordpress/block-editor';
6
- import { useEffect } from '@wordpress/element';
6
+ import { useEffect, useMemo } from '@wordpress/element';
7
7
  import { applyFilters } from '@wordpress/hooks';
8
8
 
9
- const DEFAULT_CONTENT_ONLY_BLOCKS = [
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { store as editorStore } from '../../store';
13
+ import { unlock } from '../../lock-unlock';
14
+
15
+ const POST_CONTENT_BLOCK_TYPES = [
10
16
  'core/post-title',
11
17
  'core/post-featured-image',
12
18
  'core/post-content',
13
- 'core/template-part',
14
19
  ];
15
20
 
16
21
  /**
@@ -18,32 +23,30 @@ const DEFAULT_CONTENT_ONLY_BLOCKS = [
18
23
  * page content to be edited.
19
24
  */
20
25
  export default function DisableNonPageContentBlocks() {
21
- const contentOnlyBlocks = applyFilters(
22
- 'editor.postContentBlockTypes',
23
- DEFAULT_CONTENT_ONLY_BLOCKS
26
+ const contentOnlyBlockTypes = useMemo(
27
+ () => [
28
+ ...applyFilters(
29
+ 'editor.postContentBlockTypes',
30
+ POST_CONTENT_BLOCK_TYPES
31
+ ),
32
+ 'core/template-part',
33
+ ],
34
+ []
24
35
  );
25
36
 
26
- // Note that there are two separate subscription because the result for each
37
+ // Note that there are two separate subscriptions because the result for each
27
38
  // returns a new array.
28
- const contentOnlyIds = useSelect( ( select ) => {
29
- const { getBlocksByName, getBlockParents, getBlockName } =
30
- select( blockEditorStore );
31
- return getBlocksByName( contentOnlyBlocks ).filter( ( clientId ) =>
32
- getBlockParents( clientId ).every( ( parentClientId ) => {
33
- const parentBlockName = getBlockName( parentClientId );
34
- return (
35
- // Ignore descendents of the query block.
36
- parentBlockName !== 'core/query' &&
37
- // Enable only the top-most block.
38
- ! contentOnlyBlocks.includes( parentBlockName )
39
- );
40
- } )
41
- );
42
- }, [] );
39
+ const contentOnlyIds = useSelect(
40
+ ( select ) => {
41
+ const { getPostBlocksByName } = unlock( select( editorStore ) );
42
+ return getPostBlocksByName( contentOnlyBlockTypes );
43
+ },
44
+ [ contentOnlyBlockTypes ]
45
+ );
43
46
  const disabledIds = useSelect( ( select ) => {
44
47
  const { getBlocksByName, getBlockOrder } = select( blockEditorStore );
45
- return getBlocksByName( [ 'core/template-part' ] ).flatMap(
46
- ( clientId ) => getBlockOrder( clientId )
48
+ return getBlocksByName( 'core/template-part' ).flatMap( ( clientId ) =>
49
+ getBlockOrder( clientId )
47
50
  );
48
51
  }, [] );
49
52
 
@@ -23,29 +23,17 @@ import { store as editorStore } from '../../store';
23
23
 
24
24
  const COMMENT_OPTIONS = [
25
25
  {
26
- label: (
27
- <>
28
- { _x( 'Open', 'Adjective: e.g. "Comments are open"' ) }
29
- <Text variant="muted" size={ 12 }>
30
- { __( 'Visitors can add new comments and replies.' ) }
31
- </Text>
32
- </>
33
- ),
26
+ label: _x( 'Open', 'Adjective: e.g. "Comments are open"' ),
34
27
  value: 'open',
28
+ description: __( 'Visitors can add new comments and replies.' ),
35
29
  },
36
30
  {
37
- label: (
38
- <>
39
- { __( 'Closed' ) }
40
- <Text variant="muted" size={ 12 }>
41
- { __( 'Visitors cannot add new comments or replies.' ) }
42
- </Text>
43
- <Text variant="muted" size={ 12 }>
44
- { __( 'Existing comments remain visible.' ) }
45
- </Text>
46
- </>
47
- ),
31
+ label: __( 'Closed' ),
48
32
  value: '',
33
+ description: [
34
+ __( 'Visitors cannot add new comments or replies.' ),
35
+ __( 'Existing comments remain visible.' ),
36
+ ].join( ' ' ),
49
37
  },
50
38
  ];
51
39
 
@@ -2,13 +2,12 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { useSelect, useDispatch } from '@wordpress/data';
5
- import {
6
- store as blockEditorStore,
7
- privateApis as blockEditorPrivateApis,
8
- } from '@wordpress/block-editor';
5
+ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
9
6
  import { PanelBody } from '@wordpress/components';
10
7
  import { __ } from '@wordpress/i18n';
11
8
  import { store as interfaceStore } from '@wordpress/interface';
9
+ import { applyFilters } from '@wordpress/hooks';
10
+ import { useMemo } from '@wordpress/element';
12
11
 
13
12
  /**
14
13
  * Internal dependencies
@@ -19,30 +18,46 @@ import { store as editorStore } from '../../store';
19
18
 
20
19
  const { BlockQuickNavigation } = unlock( blockEditorPrivateApis );
21
20
 
22
- const PAGE_CONTENT_BLOCKS = [
23
- 'core/post-content',
24
- 'core/post-featured-image',
21
+ const POST_CONTENT_BLOCK_TYPES = [
25
22
  'core/post-title',
23
+ 'core/post-featured-image',
24
+ 'core/post-content',
26
25
  ];
27
26
 
28
27
  const TEMPLATE_PART_BLOCK = 'core/template-part';
29
28
 
30
29
  export default function TemplateContentPanel() {
31
- const { enableComplementaryArea } = useDispatch( interfaceStore );
32
- const { clientIds, postType, renderingMode } = useSelect( ( select ) => {
33
- const { getBlocksByName } = select( blockEditorStore );
34
- const { getCurrentPostType } = select( editorStore );
35
- const _postType = getCurrentPostType();
36
- return {
37
- postType: _postType,
38
- clientIds: getBlocksByName(
39
- TEMPLATE_POST_TYPE === _postType
40
- ? TEMPLATE_PART_BLOCK
41
- : PAGE_CONTENT_BLOCKS
30
+ const postContentBlockTypes = useMemo(
31
+ () =>
32
+ applyFilters(
33
+ 'editor.postContentBlockTypes',
34
+ POST_CONTENT_BLOCK_TYPES
42
35
  ),
43
- renderingMode: select( editorStore ).getRenderingMode(),
44
- };
45
- }, [] );
36
+ []
37
+ );
38
+
39
+ const { clientIds, postType, renderingMode } = useSelect(
40
+ ( select ) => {
41
+ const {
42
+ getCurrentPostType,
43
+ getPostBlocksByName,
44
+ getRenderingMode,
45
+ } = unlock( select( editorStore ) );
46
+ const _postType = getCurrentPostType();
47
+ return {
48
+ postType: _postType,
49
+ clientIds: getPostBlocksByName(
50
+ TEMPLATE_POST_TYPE === _postType
51
+ ? TEMPLATE_PART_BLOCK
52
+ : postContentBlockTypes
53
+ ),
54
+ renderingMode: getRenderingMode(),
55
+ };
56
+ },
57
+ [ postContentBlockTypes ]
58
+ );
59
+
60
+ const { enableComplementaryArea } = useDispatch( interfaceStore );
46
61
 
47
62
  if ( renderingMode === 'post-only' && postType !== TEMPLATE_POST_TYPE ) {
48
63
  return null;