@wordpress/editor 13.25.0 → 13.26.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 (223) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE.md +1 -1
  3. package/build/components/document-bar/index.js +19 -7
  4. package/build/components/document-bar/index.js.map +1 -1
  5. package/build/components/document-outline/index.js +82 -1
  6. package/build/components/document-outline/index.js.map +1 -1
  7. package/build/components/document-tools/index.js +160 -0
  8. package/build/components/document-tools/index.js.map +1 -0
  9. package/build/components/editor-canvas/index.js +10 -4
  10. package/build/components/editor-canvas/index.js.map +1 -1
  11. package/build/components/entities-saved-states/index.js +3 -1
  12. package/build/components/entities-saved-states/index.js.map +1 -1
  13. package/build/components/global-keyboard-shortcuts/index.js +12 -2
  14. package/build/components/global-keyboard-shortcuts/index.js.map +1 -1
  15. package/build/components/global-keyboard-shortcuts/register-shortcuts.js +9 -0
  16. package/build/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
  17. package/build/components/index.js +56 -8
  18. package/build/components/index.js.map +1 -1
  19. package/build/components/index.native.js +9 -1
  20. package/build/components/index.native.js.map +1 -1
  21. package/build/components/inserter-sidebar/index.js +77 -0
  22. package/build/components/inserter-sidebar/index.js.map +1 -0
  23. package/build/components/list-view-sidebar/index.js +150 -0
  24. package/build/components/list-view-sidebar/index.js.map +1 -0
  25. package/build/components/list-view-sidebar/list-view-outline.js +28 -0
  26. package/build/components/list-view-sidebar/list-view-outline.js.map +1 -0
  27. package/build/components/offline-status/index.native.js +85 -0
  28. package/build/components/offline-status/index.native.js.map +1 -0
  29. package/build/components/page-attributes/panel.js +63 -0
  30. package/build/components/page-attributes/panel.js.map +1 -0
  31. package/build/components/post-discussion/panel.js +59 -0
  32. package/build/components/post-discussion/panel.js.map +1 -0
  33. package/build/components/post-excerpt/check.js +19 -0
  34. package/build/components/post-excerpt/check.js.map +1 -1
  35. package/build/components/post-excerpt/panel.js +55 -0
  36. package/build/components/post-excerpt/panel.js.map +1 -0
  37. package/build/components/post-excerpt/plugin.js +72 -0
  38. package/build/components/post-excerpt/plugin.js.map +1 -0
  39. package/build/components/post-featured-image/index.js +5 -8
  40. package/build/components/post-featured-image/index.js.map +1 -1
  41. package/build/components/post-featured-image/panel.js +60 -0
  42. package/build/components/post-featured-image/panel.js.map +1 -0
  43. package/build/components/post-last-revision/panel.js +27 -0
  44. package/build/components/post-last-revision/panel.js.map +1 -0
  45. package/build/components/post-saved-state/index.js +12 -8
  46. package/build/components/post-saved-state/index.js.map +1 -1
  47. package/build/components/post-taxonomies/panel.js +68 -0
  48. package/build/components/post-taxonomies/panel.js.map +1 -0
  49. package/build/components/post-template/block-theme.js +2 -1
  50. package/build/components/post-template/block-theme.js.map +1 -1
  51. package/build/components/post-template/hooks.js +6 -6
  52. package/build/components/post-template/hooks.js.map +1 -1
  53. package/build/components/post-template/panel.js +1 -2
  54. package/build/components/post-template/panel.js.map +1 -1
  55. package/build/components/post-template/swap-template-button.js +4 -2
  56. package/build/components/post-template/swap-template-button.js.map +1 -1
  57. package/build/components/post-title/index.native.js +25 -14
  58. package/build/components/post-title/index.native.js.map +1 -1
  59. package/build/components/post-view-link/index.js +58 -0
  60. package/build/components/post-view-link/index.js.map +1 -0
  61. package/build/components/post-visibility/check.js +5 -17
  62. package/build/components/post-visibility/check.js.map +1 -1
  63. package/build/components/preview-dropdown/index.js +8 -3
  64. package/build/components/preview-dropdown/index.js.map +1 -1
  65. package/build/components/provider/index.native.js +19 -0
  66. package/build/components/provider/index.native.js.map +1 -1
  67. package/build/components/provider/use-block-editor-settings.js +29 -5
  68. package/build/components/provider/use-block-editor-settings.js.map +1 -1
  69. package/build/private-apis.js +10 -0
  70. package/build/private-apis.js.map +1 -1
  71. package/build/store/actions.js +102 -2
  72. package/build/store/actions.js.map +1 -1
  73. package/build/store/index.js +2 -0
  74. package/build/store/index.js.map +1 -1
  75. package/build/store/private-selectors.js +52 -0
  76. package/build/store/private-selectors.js.map +1 -0
  77. package/build/store/reducer.js +78 -1
  78. package/build/store/reducer.js.map +1 -1
  79. package/build/store/selectors.js +76 -2
  80. package/build/store/selectors.js.map +1 -1
  81. package/build/utils/media-upload/index.js +8 -2
  82. package/build/utils/media-upload/index.js.map +1 -1
  83. package/build-module/components/document-bar/index.js +19 -7
  84. package/build-module/components/document-bar/index.js.map +1 -1
  85. package/build-module/components/document-outline/index.js +82 -1
  86. package/build-module/components/document-outline/index.js.map +1 -1
  87. package/build-module/components/document-tools/index.js +151 -0
  88. package/build-module/components/document-tools/index.js.map +1 -0
  89. package/build-module/components/editor-canvas/index.js +10 -4
  90. package/build-module/components/editor-canvas/index.js.map +1 -1
  91. package/build-module/components/entities-saved-states/index.js +3 -1
  92. package/build-module/components/entities-saved-states/index.js.map +1 -1
  93. package/build-module/components/global-keyboard-shortcuts/index.js +12 -2
  94. package/build-module/components/global-keyboard-shortcuts/index.js.map +1 -1
  95. package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js +9 -0
  96. package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
  97. package/build-module/components/index.js +6 -0
  98. package/build-module/components/index.js.map +1 -1
  99. package/build-module/components/index.native.js +1 -0
  100. package/build-module/components/index.native.js.map +1 -1
  101. package/build-module/components/inserter-sidebar/index.js +70 -0
  102. package/build-module/components/inserter-sidebar/index.js.map +1 -0
  103. package/build-module/components/list-view-sidebar/index.js +142 -0
  104. package/build-module/components/list-view-sidebar/index.js.map +1 -0
  105. package/build-module/components/list-view-sidebar/list-view-outline.js +20 -0
  106. package/build-module/components/list-view-sidebar/list-view-outline.js.map +1 -0
  107. package/build-module/components/offline-status/index.native.js +77 -0
  108. package/build-module/components/offline-status/index.native.js.map +1 -0
  109. package/build-module/components/page-attributes/panel.js +53 -0
  110. package/build-module/components/page-attributes/panel.js.map +1 -0
  111. package/build-module/components/post-discussion/panel.js +50 -0
  112. package/build-module/components/post-discussion/panel.js.map +1 -0
  113. package/build-module/components/post-excerpt/check.js +19 -0
  114. package/build-module/components/post-excerpt/check.js.map +1 -1
  115. package/build-module/components/post-excerpt/panel.js +48 -0
  116. package/build-module/components/post-excerpt/panel.js.map +1 -0
  117. package/build-module/components/post-excerpt/plugin.js +64 -0
  118. package/build-module/components/post-excerpt/plugin.js.map +1 -0
  119. package/build-module/components/post-featured-image/index.js +5 -8
  120. package/build-module/components/post-featured-image/index.js.map +1 -1
  121. package/build-module/components/post-featured-image/panel.js +51 -0
  122. package/build-module/components/post-featured-image/panel.js.map +1 -0
  123. package/build-module/components/post-last-revision/panel.js +18 -0
  124. package/build-module/components/post-last-revision/panel.js.map +1 -0
  125. package/build-module/components/post-saved-state/index.js +12 -8
  126. package/build-module/components/post-saved-state/index.js.map +1 -1
  127. package/build-module/components/post-taxonomies/panel.js +59 -0
  128. package/build-module/components/post-taxonomies/panel.js.map +1 -0
  129. package/build-module/components/post-template/block-theme.js +2 -1
  130. package/build-module/components/post-template/block-theme.js.map +1 -1
  131. package/build-module/components/post-template/hooks.js +6 -6
  132. package/build-module/components/post-template/hooks.js.map +1 -1
  133. package/build-module/components/post-template/panel.js +1 -2
  134. package/build-module/components/post-template/panel.js.map +1 -1
  135. package/build-module/components/post-template/swap-template-button.js +4 -2
  136. package/build-module/components/post-template/swap-template-button.js.map +1 -1
  137. package/build-module/components/post-title/index.native.js +26 -15
  138. package/build-module/components/post-title/index.native.js.map +1 -1
  139. package/build-module/components/post-view-link/index.js +51 -0
  140. package/build-module/components/post-view-link/index.js.map +1 -0
  141. package/build-module/components/post-visibility/check.js +6 -16
  142. package/build-module/components/post-visibility/check.js.map +1 -1
  143. package/build-module/components/preview-dropdown/index.js +8 -3
  144. package/build-module/components/preview-dropdown/index.js.map +1 -1
  145. package/build-module/components/provider/index.native.js +19 -0
  146. package/build-module/components/provider/index.native.js.map +1 -1
  147. package/build-module/components/provider/use-block-editor-settings.js +29 -5
  148. package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
  149. package/build-module/private-apis.js +10 -0
  150. package/build-module/private-apis.js.map +1 -1
  151. package/build-module/store/actions.js +94 -0
  152. package/build-module/store/actions.js.map +1 -1
  153. package/build-module/store/index.js +2 -0
  154. package/build-module/store/index.js.map +1 -1
  155. package/build-module/store/private-selectors.js +43 -0
  156. package/build-module/store/private-selectors.js.map +1 -0
  157. package/build-module/store/reducer.js +74 -1
  158. package/build-module/store/reducer.js.map +1 -1
  159. package/build-module/store/selectors.js +67 -0
  160. package/build-module/store/selectors.js.map +1 -1
  161. package/build-module/utils/media-upload/index.js +8 -2
  162. package/build-module/utils/media-upload/index.js.map +1 -1
  163. package/build-style/style-rtl.css +251 -0
  164. package/build-style/style.css +251 -0
  165. package/package.json +32 -32
  166. package/src/components/document-bar/index.js +39 -28
  167. package/src/components/document-outline/index.js +48 -1
  168. package/src/components/document-outline/style.scss +12 -0
  169. package/src/components/document-tools/index.js +177 -0
  170. package/src/components/document-tools/style.scss +98 -0
  171. package/src/components/editor-canvas/index.js +12 -7
  172. package/src/components/editor-canvas/style.scss +5 -0
  173. package/src/components/entities-saved-states/index.js +3 -1
  174. package/src/components/entities-saved-states/style.scss +4 -0
  175. package/src/components/global-keyboard-shortcuts/index.js +12 -2
  176. package/src/components/global-keyboard-shortcuts/register-shortcuts.js +10 -0
  177. package/src/components/index.js +6 -0
  178. package/src/components/index.native.js +1 -0
  179. package/src/components/inserter-sidebar/index.js +73 -0
  180. package/src/components/inserter-sidebar/style.scss +22 -0
  181. package/src/components/list-view-sidebar/index.js +169 -0
  182. package/src/components/list-view-sidebar/list-view-outline.js +37 -0
  183. package/src/components/list-view-sidebar/style.scss +84 -0
  184. package/src/components/offline-status/index.native.js +101 -0
  185. package/src/components/offline-status/style.native.scss +28 -0
  186. package/src/components/offline-status/test/index.native.js +108 -0
  187. package/src/components/page-attributes/panel.js +62 -0
  188. package/src/components/post-discussion/panel.js +57 -0
  189. package/src/components/post-excerpt/check.js +18 -0
  190. package/src/components/post-excerpt/panel.js +57 -0
  191. package/src/components/post-excerpt/plugin.js +61 -0
  192. package/src/components/post-excerpt/test/plugin.js +36 -0
  193. package/src/components/post-featured-image/index.js +3 -7
  194. package/src/components/post-featured-image/panel.js +55 -0
  195. package/src/components/post-last-revision/panel.js +22 -0
  196. package/src/components/post-last-revision/style.scss +10 -0
  197. package/src/components/post-saved-state/index.js +8 -8
  198. package/src/components/post-taxonomies/panel.js +66 -0
  199. package/src/components/post-template/block-theme.js +2 -1
  200. package/src/components/post-template/hooks.js +6 -6
  201. package/src/components/post-template/panel.js +1 -2
  202. package/src/components/post-template/swap-template-button.js +7 -4
  203. package/src/components/post-title/index.native.js +32 -17
  204. package/src/components/post-title/style.scss +1 -0
  205. package/src/components/post-title/test/__snapshots__/index.native.js.snap +25 -0
  206. package/src/components/post-title/test/index.native.js +78 -0
  207. package/src/components/post-view-link/index.js +47 -0
  208. package/src/components/post-visibility/check.js +10 -15
  209. package/src/components/post-visibility/test/check.js +24 -13
  210. package/src/components/preview-dropdown/index.js +7 -10
  211. package/src/components/provider/index.native.js +29 -2
  212. package/src/components/provider/use-block-editor-settings.js +36 -8
  213. package/src/private-apis.js +10 -0
  214. package/src/store/actions.js +109 -0
  215. package/src/store/index.js +2 -0
  216. package/src/store/private-selectors.js +51 -0
  217. package/src/store/reducer.js +72 -0
  218. package/src/store/selectors.js +80 -0
  219. package/src/store/test/actions.js +56 -0
  220. package/src/store/test/reducer.js +98 -0
  221. package/src/store/test/selectors.js +49 -0
  222. package/src/style.scss +4 -0
  223. package/src/utils/media-upload/index.js +9 -2
@@ -0,0 +1,57 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { PanelBody, PanelRow } from '@wordpress/components';
6
+ import { useDispatch, useSelect } from '@wordpress/data';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { store as editorStore } from '../../store';
12
+ import PostTypeSupportCheck from '../post-type-support-check';
13
+ import PostComments from '../post-comments';
14
+ import PostPingbacks from '../post-pingbacks';
15
+
16
+ const PANEL_NAME = 'discussion-panel';
17
+
18
+ function PostDiscussionPanel() {
19
+ const { isEnabled, isOpened } = useSelect( ( select ) => {
20
+ const { isEditorPanelEnabled, isEditorPanelOpened } =
21
+ select( editorStore );
22
+ return {
23
+ isEnabled: isEditorPanelEnabled( PANEL_NAME ),
24
+ isOpened: isEditorPanelOpened( PANEL_NAME ),
25
+ };
26
+ }, [] );
27
+
28
+ const { toggleEditorPanelOpened } = useDispatch( editorStore );
29
+
30
+ if ( ! isEnabled ) {
31
+ return null;
32
+ }
33
+
34
+ return (
35
+ <PostTypeSupportCheck supportKeys={ [ 'comments', 'trackbacks' ] }>
36
+ <PanelBody
37
+ title={ __( 'Discussion' ) }
38
+ opened={ isOpened }
39
+ onToggle={ () => toggleEditorPanelOpened( PANEL_NAME ) }
40
+ >
41
+ <PostTypeSupportCheck supportKeys="comments">
42
+ <PanelRow>
43
+ <PostComments />
44
+ </PanelRow>
45
+ </PostTypeSupportCheck>
46
+
47
+ <PostTypeSupportCheck supportKeys="trackbacks">
48
+ <PanelRow>
49
+ <PostPingbacks />
50
+ </PanelRow>
51
+ </PostTypeSupportCheck>
52
+ </PanelBody>
53
+ </PostTypeSupportCheck>
54
+ );
55
+ }
56
+
57
+ export default PostDiscussionPanel;
@@ -1,9 +1,27 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
9
  import PostTypeSupportCheck from '../post-type-support-check';
10
+ import { store as editorStore } from '../../store';
5
11
 
6
12
  function PostExcerptCheck( { children } ) {
13
+ const postType = useSelect( ( select ) => {
14
+ const { getEditedPostAttribute } = select( editorStore );
15
+ return getEditedPostAttribute( 'type' );
16
+ }, [] );
17
+
18
+ // This special case is unfortunate, but the REST API of wp_template and wp_template_part
19
+ // support the excerpt field throught the "description" field rather than "excerpt" which means
20
+ // the default ExcerptPanel won't work for these.
21
+ if ( [ 'wp_template', 'wp_template_part' ].includes( postType ) ) {
22
+ return null;
23
+ }
24
+
7
25
  return (
8
26
  <PostTypeSupportCheck supportKeys="excerpt">
9
27
  { children }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { PanelBody } from '@wordpress/components';
6
+ import { useDispatch, useSelect } from '@wordpress/data';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import PostExcerptForm from './index';
12
+ import PostExcerptCheck from './check';
13
+ import PluginPostExcerpt from './plugin';
14
+ import { store as editorStore } from '../../store';
15
+
16
+ /**
17
+ * Module Constants
18
+ */
19
+ const PANEL_NAME = 'post-excerpt';
20
+
21
+ export default function PostExcerptPanel() {
22
+ const { isOpened, isEnabled } = useSelect( ( select ) => {
23
+ const { isEditorPanelOpened, isEditorPanelEnabled } =
24
+ select( editorStore );
25
+
26
+ return {
27
+ isOpened: isEditorPanelOpened( PANEL_NAME ),
28
+ isEnabled: isEditorPanelEnabled( PANEL_NAME ),
29
+ };
30
+ }, [] );
31
+
32
+ const { toggleEditorPanelOpened } = useDispatch( editorStore );
33
+ const toggleExcerptPanel = () => toggleEditorPanelOpened( PANEL_NAME );
34
+
35
+ if ( ! isEnabled ) {
36
+ return null;
37
+ }
38
+
39
+ return (
40
+ <PostExcerptCheck>
41
+ <PanelBody
42
+ title={ __( 'Excerpt' ) }
43
+ opened={ isOpened }
44
+ onToggle={ toggleExcerptPanel }
45
+ >
46
+ <PluginPostExcerpt.Slot>
47
+ { ( fills ) => (
48
+ <>
49
+ <PostExcerptForm />
50
+ { fills }
51
+ </>
52
+ ) }
53
+ </PluginPostExcerpt.Slot>
54
+ </PanelBody>
55
+ </PostExcerptCheck>
56
+ );
57
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Defines as extensibility slot for the Excerpt panel.
3
+ */
4
+
5
+ /**
6
+ * WordPress dependencies
7
+ */
8
+ import { createSlotFill, PanelRow } from '@wordpress/components';
9
+
10
+ const { Fill, Slot } = createSlotFill( 'PluginPostExcerpt' );
11
+
12
+ /**
13
+ * Renders a post excerpt panel in the post sidebar.
14
+ *
15
+ * @param {Object} props Component properties.
16
+ * @param {string} [props.className] An optional class name added to the row.
17
+ * @param {Element} props.children Children to be rendered.
18
+ *
19
+ * @example
20
+ * ```js
21
+ * // Using ES5 syntax
22
+ * var __ = wp.i18n.__;
23
+ * var PluginPostExcerpt = wp.editPost.PluginPostExcerpt;
24
+ *
25
+ * function MyPluginPostExcerpt() {
26
+ * return React.createElement(
27
+ * PluginPostExcerpt,
28
+ * {
29
+ * className: 'my-plugin-post-excerpt',
30
+ * },
31
+ * __( 'Post excerpt custom content' )
32
+ * )
33
+ * }
34
+ * ```
35
+ *
36
+ * @example
37
+ * ```jsx
38
+ * // Using ESNext syntax
39
+ * import { __ } from '@wordpress/i18n';
40
+ * import { PluginPostExcerpt } from '@wordpress/edit-post';
41
+ *
42
+ * const MyPluginPostExcerpt = () => (
43
+ * <PluginPostExcerpt className="my-plugin-post-excerpt">
44
+ * { __( 'Post excerpt custom content' ) }
45
+ * </PluginPostExcerpt>
46
+ * );
47
+ * ```
48
+ *
49
+ * @return {Component} The component to be rendered.
50
+ */
51
+ const PluginPostExcerpt = ( { children, className } ) => {
52
+ return (
53
+ <Fill>
54
+ <PanelRow className={ className }>{ children }</PanelRow>
55
+ </Fill>
56
+ );
57
+ };
58
+
59
+ PluginPostExcerpt.Slot = Slot;
60
+
61
+ export default PluginPostExcerpt;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render, screen } from '@testing-library/react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { SlotFillProvider } from '@wordpress/components';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import PluginPostExcerptPanel from '../plugin';
15
+
16
+ describe( 'PluginPostExcerptPanel', () => {
17
+ test( 'renders fill properly', () => {
18
+ render(
19
+ <SlotFillProvider>
20
+ <PluginPostExcerptPanel className="my-plugin-post-excerpt-custom-content">
21
+ Post Excerpt - Custom content
22
+ </PluginPostExcerptPanel>
23
+ <div role="tabpanel">
24
+ <PluginPostExcerptPanel.Slot />
25
+ </div>
26
+ </SlotFillProvider>
27
+ );
28
+
29
+ expect( screen.getByRole( 'tabpanel' ) ).toHaveTextContent(
30
+ 'Post Excerpt - Custom content'
31
+ );
32
+ expect(
33
+ screen.getByText( 'Post Excerpt - Custom content' )
34
+ ).toHaveClass( 'my-plugin-post-excerpt-custom-content' );
35
+ } );
36
+ } );
@@ -98,17 +98,15 @@ function PostFeaturedImage( {
98
98
  } ) {
99
99
  const toggleRef = useRef();
100
100
  const [ isLoading, setIsLoading ] = useState( false );
101
- const mediaUpload = useSelect( ( select ) => {
102
- return select( blockEditorStore ).getSettings().mediaUpload;
103
- }, [] );
101
+ const { getSettings } = useSelect( blockEditorStore );
104
102
  const { mediaWidth, mediaHeight, mediaSourceUrl } = getMediaDetails(
105
103
  media,
106
104
  currentPostId
107
105
  );
108
106
 
109
107
  function onDropFiles( filesList ) {
110
- mediaUpload( {
111
- allowedTypes: [ 'image' ],
108
+ getSettings().mediaUpload( {
109
+ allowedTypes: ALLOWED_MEDIA_TYPES,
112
110
  filesList,
113
111
  onFileChange( [ image ] ) {
114
112
  if ( isBlobURL( image?.url ) ) {
@@ -208,8 +206,6 @@ function PostFeaturedImage( {
208
206
  <Button
209
207
  className="editor-post-featured-image__action"
210
208
  onClick={ open }
211
- // Prefer that screen readers use the .editor-post-featured-image__preview button.
212
- aria-hidden="true"
213
209
  >
214
210
  { __( 'Replace' ) }
215
211
  </Button>
@@ -0,0 +1,55 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { PanelBody } from '@wordpress/components';
6
+ import { useSelect, useDispatch } from '@wordpress/data';
7
+ import { store as coreStore } from '@wordpress/core-data';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { store as editorStore } from '../../store';
13
+ import PostFeaturedImage from './index';
14
+ import PostFeaturedImageCheck from './check';
15
+
16
+ const PANEL_NAME = 'featured-image';
17
+
18
+ function FeaturedImage() {
19
+ const { postType, isEnabled, isOpened } = useSelect( ( select ) => {
20
+ const {
21
+ getEditedPostAttribute,
22
+ isEditorPanelEnabled,
23
+ isEditorPanelOpened,
24
+ } = select( editorStore );
25
+ const { getPostType } = select( coreStore );
26
+
27
+ return {
28
+ postType: getPostType( getEditedPostAttribute( 'type' ) ),
29
+ isEnabled: isEditorPanelEnabled( PANEL_NAME ),
30
+ isOpened: isEditorPanelOpened( PANEL_NAME ),
31
+ };
32
+ }, [] );
33
+
34
+ const { toggleEditorPanelOpened } = useDispatch( editorStore );
35
+
36
+ if ( ! isEnabled ) {
37
+ return null;
38
+ }
39
+
40
+ return (
41
+ <PostFeaturedImageCheck>
42
+ <PanelBody
43
+ title={
44
+ postType?.labels?.featured_image ?? __( 'Featured image' )
45
+ }
46
+ opened={ isOpened }
47
+ onToggle={ () => toggleEditorPanelOpened( PANEL_NAME ) }
48
+ >
49
+ <PostFeaturedImage />
50
+ </PanelBody>
51
+ </PostFeaturedImageCheck>
52
+ );
53
+ }
54
+
55
+ export default FeaturedImage;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { PanelBody } from '@wordpress/components';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import PostLastRevision from './';
10
+ import PostLastRevisionCheck from './check';
11
+
12
+ function PostLastRevisionPanel() {
13
+ return (
14
+ <PostLastRevisionCheck>
15
+ <PanelBody className="editor-post-last-revision__panel">
16
+ <PostLastRevision />
17
+ </PanelBody>
18
+ </PostLastRevisionCheck>
19
+ );
20
+ }
21
+
22
+ export default PostLastRevisionPanel;
@@ -21,3 +21,13 @@
21
21
  border-radius: 0;
22
22
  }
23
23
  }
24
+
25
+ // Needs specificity, because this panel is just a button
26
+ .components-panel__body.is-opened.editor-post-last-revision__panel {
27
+ padding: 0;
28
+ height: $grid-unit-60;
29
+
30
+ .editor-post-last-revision__title.components-button.components-button {
31
+ padding: $grid-unit-20;
32
+ }
33
+ }
@@ -17,6 +17,7 @@ import { useEffect, useState } from '@wordpress/element';
17
17
  import { __ } from '@wordpress/i18n';
18
18
  import { Icon, check, cloud, cloudUpload } from '@wordpress/icons';
19
19
  import { displayShortcut } from '@wordpress/keycodes';
20
+ import { store as preferencesStore } from '@wordpress/preferences';
20
21
 
21
22
  /**
22
23
  * Internal dependencies
@@ -27,16 +28,12 @@ import { store as editorStore } from '../../store';
27
28
  * Component showing whether the post is saved or not and providing save
28
29
  * buttons.
29
30
  *
30
- * @param {Object} props Component props.
31
- * @param {?boolean} props.forceIsDirty Whether to force the post to be marked
32
- * as dirty.
33
- * @param {?boolean} props.showIconLabels Whether interface buttons show labels instead of icons
31
+ * @param {Object} props Component props.
32
+ * @param {?boolean} props.forceIsDirty Whether to force the post to be marked
33
+ * as dirty.
34
34
  * @return {import('react').ComponentType} The component.
35
35
  */
36
- export default function PostSavedState( {
37
- forceIsDirty,
38
- showIconLabels = false,
39
- } ) {
36
+ export default function PostSavedState( { forceIsDirty } ) {
40
37
  const [ forceSavedMessage, setForceSavedMessage ] = useState( false );
41
38
  const isLargeViewport = useViewportMatch( 'small' );
42
39
 
@@ -50,6 +47,7 @@ export default function PostSavedState( {
50
47
  isSaving,
51
48
  isScheduled,
52
49
  hasPublishAction,
50
+ showIconLabels,
53
51
  } = useSelect(
54
52
  ( select ) => {
55
53
  const {
@@ -63,6 +61,7 @@ export default function PostSavedState( {
63
61
  isAutosavingPost,
64
62
  getEditedPostAttribute,
65
63
  } = select( editorStore );
64
+ const { get } = select( preferencesStore );
66
65
 
67
66
  return {
68
67
  isAutosaving: isAutosavingPost(),
@@ -75,6 +74,7 @@ export default function PostSavedState( {
75
74
  isScheduled: isCurrentPostScheduled(),
76
75
  hasPublishAction:
77
76
  getCurrentPost()?._links?.[ 'wp:action-publish' ] ?? false,
77
+ showIconLabels: get( 'core', 'showIconLabels' ),
78
78
  };
79
79
  },
80
80
  [ forceIsDirty ]
@@ -0,0 +1,66 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { PanelBody } from '@wordpress/components';
5
+ import { useSelect, useDispatch } from '@wordpress/data';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { store as editorStore } from '../../store';
11
+ import PostTaxonomiesForm from './index';
12
+ import PostTaxonomiesCheck from './check';
13
+
14
+ function TaxonomyPanel( { taxonomy, children } ) {
15
+ const slug = taxonomy?.slug;
16
+ const panelName = slug ? `taxonomy-panel-${ slug }` : '';
17
+ const { isEnabled, isOpened } = useSelect(
18
+ ( select ) => {
19
+ const { isEditorPanelEnabled, isEditorPanelOpened } =
20
+ select( editorStore );
21
+ return {
22
+ isEnabled: slug ? isEditorPanelEnabled( panelName ) : false,
23
+ isOpened: slug ? isEditorPanelOpened( panelName ) : false,
24
+ };
25
+ },
26
+ [ panelName, slug ]
27
+ );
28
+ const { toggleEditorPanelOpened } = useDispatch( editorStore );
29
+
30
+ if ( ! isEnabled ) {
31
+ return null;
32
+ }
33
+
34
+ const taxonomyMenuName = taxonomy?.labels?.menu_name;
35
+ if ( ! taxonomyMenuName ) {
36
+ return null;
37
+ }
38
+
39
+ return (
40
+ <PanelBody
41
+ title={ taxonomyMenuName }
42
+ opened={ isOpened }
43
+ onToggle={ () => toggleEditorPanelOpened( panelName ) }
44
+ >
45
+ { children }
46
+ </PanelBody>
47
+ );
48
+ }
49
+
50
+ function PostTaxonomies() {
51
+ return (
52
+ <PostTaxonomiesCheck>
53
+ <PostTaxonomiesForm
54
+ taxonomyWrapper={ ( content, taxonomy ) => {
55
+ return (
56
+ <TaxonomyPanel taxonomy={ taxonomy }>
57
+ { content }
58
+ </TaxonomyPanel>
59
+ );
60
+ } }
61
+ />
62
+ </PostTaxonomiesCheck>
63
+ );
64
+ }
65
+
66
+ export default PostTaxonomies;
@@ -90,7 +90,8 @@ export default function BlockThemeControl( { id } ) {
90
90
  <MenuGroup>
91
91
  <MenuItem
92
92
  icon={ ! isTemplateHidden ? check : undefined }
93
- isPressed={ ! isTemplateHidden }
93
+ isSelected={ ! isTemplateHidden }
94
+ role="menuitemcheckbox"
94
95
  onClick={ () => {
95
96
  setRenderingMode(
96
97
  isTemplateHidden
@@ -41,21 +41,21 @@ export function useAllowSwitchingTemplates() {
41
41
  );
42
42
  }
43
43
 
44
- function useTemplates() {
44
+ function useTemplates( postType ) {
45
45
  return useSelect(
46
46
  ( select ) =>
47
47
  select( coreStore ).getEntityRecords( 'postType', 'wp_template', {
48
48
  per_page: -1,
49
- post_type: 'page',
49
+ post_type: postType,
50
50
  } ),
51
- []
51
+ [ postType ]
52
52
  );
53
53
  }
54
54
 
55
- export function useAvailableTemplates() {
55
+ export function useAvailableTemplates( postType ) {
56
56
  const currentTemplateSlug = useCurrentTemplateSlug();
57
57
  const allowSwitchingTemplate = useAllowSwitchingTemplates();
58
- const templates = useTemplates();
58
+ const templates = useTemplates( postType );
59
59
  return useMemo(
60
60
  () =>
61
61
  allowSwitchingTemplate &&
@@ -71,7 +71,7 @@ export function useAvailableTemplates() {
71
71
 
72
72
  export function useCurrentTemplateSlug() {
73
73
  const { postType, postId } = useEditedPostContext();
74
- const templates = useTemplates();
74
+ const templates = useTemplates( postType );
75
75
  const entityTemplate = useSelect(
76
76
  ( select ) => {
77
77
  const post = select( coreStore ).getEditedEntityRecord(
@@ -23,8 +23,7 @@ export default function PostTemplatePanel() {
23
23
  };
24
24
  }, [] );
25
25
 
26
- const isVisible = true;
27
- useSelect( ( select ) => {
26
+ const isVisible = useSelect( ( select ) => {
28
27
  const postTypeSlug = select( editorStore ).getCurrentPostType();
29
28
  const postType = select( coreStore ).getPostType( postTypeSlug );
30
29
  if ( ! postType?.viewable ) {
@@ -18,11 +18,11 @@ import { useAvailableTemplates, useEditedPostContext } from './hooks';
18
18
 
19
19
  export default function SwapTemplateButton( { onClick } ) {
20
20
  const [ showModal, setShowModal ] = useState( false );
21
- const availableTemplates = useAvailableTemplates();
22
21
  const onClose = useCallback( () => {
23
22
  setShowModal( false );
24
23
  }, [] );
25
24
  const { postType, postId } = useEditedPostContext();
25
+ const availableTemplates = useAvailableTemplates( postType );
26
26
  const { editEntityRecord } = useDispatch( coreStore );
27
27
  if ( ! availableTemplates?.length ) {
28
28
  return null;
@@ -51,7 +51,10 @@ export default function SwapTemplateButton( { onClick } ) {
51
51
  isFullScreen
52
52
  >
53
53
  <div className="editor-post-template__swap-template-modal-content">
54
- <TemplatesList onSelect={ onTemplateSelect } />
54
+ <TemplatesList
55
+ postType={ postType }
56
+ onSelect={ onTemplateSelect }
57
+ />
55
58
  </div>
56
59
  </Modal>
57
60
  ) }
@@ -59,8 +62,8 @@ export default function SwapTemplateButton( { onClick } ) {
59
62
  );
60
63
  }
61
64
 
62
- function TemplatesList( { onSelect } ) {
63
- const availableTemplates = useAvailableTemplates();
65
+ function TemplatesList( { postType, onSelect } ) {
66
+ const availableTemplates = useAvailableTemplates( postType );
64
67
  const templatesAsPatterns = useMemo(
65
68
  () =>
66
69
  availableTemplates.map( ( template ) => ( {
@@ -7,7 +7,7 @@ import { View } from 'react-native';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { Component } from '@wordpress/element';
10
- import { create, insert } from '@wordpress/rich-text';
10
+ import { create, toHTMLString, insert } from '@wordpress/rich-text';
11
11
  import { decodeEntities } from '@wordpress/html-entities';
12
12
  import { withDispatch, withSelect } from '@wordpress/data';
13
13
  import { withFocusOutside } from '@wordpress/components';
@@ -16,6 +16,7 @@ import { __, sprintf } from '@wordpress/i18n';
16
16
  import { pasteHandler } from '@wordpress/blocks';
17
17
  import { store as blockEditorStore, RichText } from '@wordpress/block-editor';
18
18
  import { store as editorStore } from '@wordpress/editor';
19
+ import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
19
20
 
20
21
  /**
21
22
  * Internal dependencies
@@ -57,7 +58,7 @@ class PostTitle extends Component {
57
58
  this.props.onSelect();
58
59
  }
59
60
 
60
- onPaste( { value, onChange, plainText, html } ) {
61
+ onPaste( { value, plainText, html } ) {
61
62
  const { title, onInsertBlockAfter, onUpdate } = this.props;
62
63
 
63
64
  const content = pasteHandler( {
@@ -65,23 +66,37 @@ class PostTitle extends Component {
65
66
  plainText,
66
67
  } );
67
68
 
68
- if ( content.length ) {
69
- if ( typeof content === 'string' ) {
70
- const valueToInsert = create( { html: content } );
71
- onChange( insert( value, valueToInsert ) );
69
+ if ( ! content.length ) {
70
+ return;
71
+ }
72
+
73
+ if ( typeof content !== 'string' ) {
74
+ const [ firstBlock ] = content;
75
+
76
+ if (
77
+ ! title &&
78
+ ( firstBlock.name === 'core/heading' ||
79
+ firstBlock.name === 'core/paragraph' )
80
+ ) {
81
+ // Strip HTML to avoid unwanted HTML being added to the title.
82
+ // In the majority of cases it is assumed that HTML in the title
83
+ // is undesirable.
84
+ const contentNoHTML = stripHTML(
85
+ firstBlock.attributes.content
86
+ );
87
+ onUpdate( contentNoHTML );
88
+ onInsertBlockAfter( content.slice( 1 ) );
72
89
  } else {
73
- const [ firstBlock ] = content;
74
- if (
75
- ! title &&
76
- ( firstBlock.name === 'core/heading' ||
77
- firstBlock.name === 'core/paragraph' )
78
- ) {
79
- onUpdate( firstBlock.attributes.content );
80
- onInsertBlockAfter( content.slice( 1 ) );
81
- } else {
82
- onInsertBlockAfter( content );
83
- }
90
+ onInsertBlockAfter( content );
84
91
  }
92
+ } else {
93
+ // Strip HTML to avoid unwanted HTML being added to the title.
94
+ // In the majority of cases it is assumed that HTML in the title
95
+ // is undesirable.
96
+ const contentNoHTML = stripHTML( content );
97
+
98
+ const newValue = insert( value, create( { html: contentNoHTML } ) );
99
+ onUpdate( toHTMLString( { value: newValue } ) );
85
100
  }
86
101
  }
87
102
 
@@ -2,4 +2,5 @@
2
2
  .edit-post-text-editor__body .editor-post-title.is-raw-text {
3
3
  margin-bottom: $grid-unit-30;
4
4
  margin-top: 2px; // space for focus outline to appear.
5
+ max-width: none;
5
6
  }