@wordpress/editor 12.9.0 → 12.12.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 (224) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/components/document-outline/index.js +7 -9
  3. package/build/components/document-outline/index.js.map +1 -1
  4. package/build/components/editor-help/index.native.js.map +1 -1
  5. package/build/components/entities-saved-states/entity-record-item.js.map +1 -1
  6. package/build/components/entities-saved-states/index.js.map +1 -1
  7. package/build/components/error-boundary/index.js +3 -0
  8. package/build/components/error-boundary/index.js.map +1 -1
  9. package/build/components/global-keyboard-shortcuts/save-shortcut.js.map +1 -1
  10. package/build/components/index.js +61 -9
  11. package/build/components/index.js.map +1 -1
  12. package/build/components/local-autosave-monitor/index.js +24 -19
  13. package/build/components/local-autosave-monitor/index.js.map +1 -1
  14. package/build/components/page-attributes/order.js +3 -7
  15. package/build/components/page-attributes/order.js.map +1 -1
  16. package/build/components/page-attributes/parent.js +2 -2
  17. package/build/components/page-attributes/parent.js.map +1 -1
  18. package/build/components/post-author/select.js.map +1 -1
  19. package/build/components/post-comments/index.js.map +1 -1
  20. package/build/components/post-format/index.js +5 -8
  21. package/build/components/post-format/index.js.map +1 -1
  22. package/build/components/post-last-revision/check.js.map +1 -1
  23. package/build/components/post-last-revision/index.js.map +1 -1
  24. package/build/components/post-pending-status/check.js.map +1 -1
  25. package/build/components/post-pingbacks/index.js.map +1 -1
  26. package/build/components/post-publish-button/index.js +4 -2
  27. package/build/components/post-publish-button/index.js.map +1 -1
  28. package/build/components/post-publish-panel/index.js.map +1 -1
  29. package/build/components/post-publish-panel/maybe-category-panel.js +5 -5
  30. package/build/components/post-publish-panel/maybe-category-panel.js.map +1 -1
  31. package/build/components/post-publish-panel/maybe-post-format-panel.js.map +1 -1
  32. package/build/components/post-publish-panel/postpublish.js.map +1 -1
  33. package/build/components/post-publish-panel/prepublish.js.map +1 -1
  34. package/build/components/post-schedule/label.js +93 -13
  35. package/build/components/post-schedule/label.js.map +1 -1
  36. package/build/components/post-slug/index.js +8 -13
  37. package/build/components/post-slug/index.js.map +1 -1
  38. package/build/components/post-sticky/index.js.map +1 -1
  39. package/build/components/post-switch-to-draft-button/index.js.map +1 -1
  40. package/build/components/post-taxonomies/flat-term-selector.js +8 -4
  41. package/build/components/post-taxonomies/flat-term-selector.js.map +1 -1
  42. package/build/components/post-taxonomies/hierarchical-term-selector.js +1 -0
  43. package/build/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
  44. package/build/components/post-taxonomies/index.js +3 -1
  45. package/build/components/post-taxonomies/index.js.map +1 -1
  46. package/build/components/post-template/index.js +1 -2
  47. package/build/components/post-template/index.js.map +1 -1
  48. package/build/components/post-title/index.js.map +1 -1
  49. package/build/components/post-title/index.native.js.map +1 -1
  50. package/build/components/post-trash/check.js.map +1 -1
  51. package/build/components/post-url/check.js +54 -0
  52. package/build/components/post-url/check.js.map +1 -0
  53. package/build/components/post-url/index.js +115 -0
  54. package/build/components/post-url/index.js.map +1 -0
  55. package/build/components/post-url/label.js +30 -0
  56. package/build/components/post-url/label.js.map +1 -0
  57. package/build/components/post-visibility/index.js +10 -11
  58. package/build/components/post-visibility/index.js.map +1 -1
  59. package/build/components/post-visibility/label.js +5 -0
  60. package/build/components/post-visibility/label.js.map +1 -1
  61. package/build/components/provider/index.js.map +1 -1
  62. package/build/components/provider/index.native.js +0 -1
  63. package/build/components/provider/index.native.js.map +1 -1
  64. package/build/components/provider/use-block-editor-settings.js +3 -1
  65. package/build/components/provider/use-block-editor-settings.js.map +1 -1
  66. package/build/components/table-of-contents/panel.js +5 -1
  67. package/build/components/table-of-contents/panel.js.map +1 -1
  68. package/build/components/template-validation-notice/index.js.map +1 -1
  69. package/build/components/theme-support-check/index.js +1 -1
  70. package/build/components/theme-support-check/index.js.map +1 -1
  71. package/build/components/time-to-read/index.js +60 -0
  72. package/build/components/time-to-read/index.js.map +1 -0
  73. package/build/hooks/custom-sources-backwards-compatibility.js.map +1 -1
  74. package/build/store/actions.js +5 -1
  75. package/build/store/actions.js.map +1 -1
  76. package/build/store/reducer.js +1 -1
  77. package/build/store/reducer.js.map +1 -1
  78. package/build/store/selectors.js +2 -2
  79. package/build/store/selectors.js.map +1 -1
  80. package/build/utils/media-upload/index.js +4 -8
  81. package/build/utils/media-upload/index.js.map +1 -1
  82. package/build-module/components/document-outline/index.js +7 -8
  83. package/build-module/components/document-outline/index.js.map +1 -1
  84. package/build-module/components/editor-help/index.native.js.map +1 -1
  85. package/build-module/components/entities-saved-states/entity-record-item.js.map +1 -1
  86. package/build-module/components/entities-saved-states/index.js.map +1 -1
  87. package/build-module/components/error-boundary/index.js +2 -0
  88. package/build-module/components/error-boundary/index.js.map +1 -1
  89. package/build-module/components/global-keyboard-shortcuts/save-shortcut.js.map +1 -1
  90. package/build-module/components/index.js +7 -4
  91. package/build-module/components/index.js.map +1 -1
  92. package/build-module/components/local-autosave-monitor/index.js +24 -18
  93. package/build-module/components/local-autosave-monitor/index.js.map +1 -1
  94. package/build-module/components/page-attributes/order.js +3 -6
  95. package/build-module/components/page-attributes/order.js.map +1 -1
  96. package/build-module/components/page-attributes/parent.js +3 -3
  97. package/build-module/components/page-attributes/parent.js.map +1 -1
  98. package/build-module/components/post-author/select.js.map +1 -1
  99. package/build-module/components/post-comments/index.js.map +1 -1
  100. package/build-module/components/post-format/index.js +5 -8
  101. package/build-module/components/post-format/index.js.map +1 -1
  102. package/build-module/components/post-last-revision/check.js.map +1 -1
  103. package/build-module/components/post-last-revision/index.js.map +1 -1
  104. package/build-module/components/post-pending-status/check.js.map +1 -1
  105. package/build-module/components/post-pingbacks/index.js.map +1 -1
  106. package/build-module/components/post-publish-button/index.js +4 -1
  107. package/build-module/components/post-publish-button/index.js.map +1 -1
  108. package/build-module/components/post-publish-panel/index.js.map +1 -1
  109. package/build-module/components/post-publish-panel/maybe-category-panel.js +5 -5
  110. package/build-module/components/post-publish-panel/maybe-category-panel.js.map +1 -1
  111. package/build-module/components/post-publish-panel/maybe-post-format-panel.js.map +1 -1
  112. package/build-module/components/post-publish-panel/postpublish.js.map +1 -1
  113. package/build-module/components/post-publish-panel/prepublish.js.map +1 -1
  114. package/build-module/components/post-schedule/label.js +90 -13
  115. package/build-module/components/post-schedule/label.js.map +1 -1
  116. package/build-module/components/post-slug/index.js +8 -14
  117. package/build-module/components/post-slug/index.js.map +1 -1
  118. package/build-module/components/post-sticky/index.js.map +1 -1
  119. package/build-module/components/post-switch-to-draft-button/index.js.map +1 -1
  120. package/build-module/components/post-taxonomies/flat-term-selector.js +8 -6
  121. package/build-module/components/post-taxonomies/flat-term-selector.js.map +1 -1
  122. package/build-module/components/post-taxonomies/hierarchical-term-selector.js +1 -2
  123. package/build-module/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
  124. package/build-module/components/post-taxonomies/index.js +4 -1
  125. package/build-module/components/post-taxonomies/index.js.map +1 -1
  126. package/build-module/components/post-template/index.js +1 -2
  127. package/build-module/components/post-template/index.js.map +1 -1
  128. package/build-module/components/post-title/index.js.map +1 -1
  129. package/build-module/components/post-title/index.native.js.map +1 -1
  130. package/build-module/components/post-trash/check.js.map +1 -1
  131. package/build-module/components/post-url/check.js +44 -0
  132. package/build-module/components/post-url/check.js.map +1 -0
  133. package/build-module/components/post-url/index.js +102 -0
  134. package/build-module/components/post-url/index.js.map +1 -0
  135. package/build-module/components/post-url/label.js +18 -0
  136. package/build-module/components/post-url/label.js.map +1 -0
  137. package/build-module/components/post-visibility/index.js +12 -13
  138. package/build-module/components/post-visibility/index.js.map +1 -1
  139. package/build-module/components/post-visibility/label.js +3 -0
  140. package/build-module/components/post-visibility/label.js.map +1 -1
  141. package/build-module/components/provider/index.js.map +1 -1
  142. package/build-module/components/provider/index.native.js +0 -1
  143. package/build-module/components/provider/index.native.js.map +1 -1
  144. package/build-module/components/provider/use-block-editor-settings.js +4 -2
  145. package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
  146. package/build-module/components/table-of-contents/panel.js +4 -1
  147. package/build-module/components/table-of-contents/panel.js.map +1 -1
  148. package/build-module/components/template-validation-notice/index.js.map +1 -1
  149. package/build-module/components/theme-support-check/index.js +2 -2
  150. package/build-module/components/theme-support-check/index.js.map +1 -1
  151. package/build-module/components/time-to-read/index.js +50 -0
  152. package/build-module/components/time-to-read/index.js.map +1 -0
  153. package/build-module/hooks/custom-sources-backwards-compatibility.js.map +1 -1
  154. package/build-module/store/actions.js +5 -1
  155. package/build-module/store/actions.js.map +1 -1
  156. package/build-module/store/reducer.js +2 -2
  157. package/build-module/store/reducer.js.map +1 -1
  158. package/build-module/store/selectors.js +3 -3
  159. package/build-module/store/selectors.js.map +1 -1
  160. package/build-module/utils/media-upload/index.js +3 -5
  161. package/build-module/utils/media-upload/index.js.map +1 -1
  162. package/build-style/style-rtl.css +12 -30
  163. package/build-style/style.css +15 -29
  164. package/package.json +28 -28
  165. package/src/components/document-outline/index.js +9 -8
  166. package/src/components/editor-help/index.native.js +6 -6
  167. package/src/components/entities-saved-states/entity-record-item.js +6 -6
  168. package/src/components/entities-saved-states/index.js +6 -9
  169. package/src/components/error-boundary/index.js +3 -0
  170. package/src/components/global-keyboard-shortcuts/save-shortcut.js +2 -3
  171. package/src/components/index.js +13 -4
  172. package/src/components/local-autosave-monitor/index.js +39 -38
  173. package/src/components/page-attributes/order.js +1 -9
  174. package/src/components/page-attributes/parent.js +6 -10
  175. package/src/components/post-author/select.js +2 -3
  176. package/src/components/post-comments/index.js +4 -3
  177. package/src/components/post-format/index.js +15 -22
  178. package/src/components/post-format/style.scss +2 -17
  179. package/src/components/post-last-revision/check.js +2 -4
  180. package/src/components/post-last-revision/index.js +2 -4
  181. package/src/components/post-pending-status/check.js +2 -5
  182. package/src/components/post-pingbacks/index.js +2 -3
  183. package/src/components/post-publish-button/index.js +7 -8
  184. package/src/components/post-publish-panel/index.js +2 -3
  185. package/src/components/post-publish-panel/maybe-category-panel.js +7 -5
  186. package/src/components/post-publish-panel/maybe-post-format-panel.js +2 -3
  187. package/src/components/post-publish-panel/postpublish.js +2 -5
  188. package/src/components/post-publish-panel/prepublish.js +2 -3
  189. package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +1 -1
  190. package/src/components/post-schedule/label.js +111 -17
  191. package/src/components/post-schedule/test/label.js +127 -15
  192. package/src/components/post-slug/index.js +9 -16
  193. package/src/components/post-slug/test/index.js +7 -6
  194. package/src/components/post-sticky/index.js +2 -3
  195. package/src/components/post-switch-to-draft-button/index.js +2 -5
  196. package/src/components/post-taxonomies/flat-term-selector.js +10 -13
  197. package/src/components/post-taxonomies/hierarchical-term-selector.js +5 -7
  198. package/src/components/post-taxonomies/index.js +3 -1
  199. package/src/components/post-template/index.js +1 -1
  200. package/src/components/post-title/index.js +21 -31
  201. package/src/components/post-title/index.native.js +10 -16
  202. package/src/components/post-title/style.scss +1 -1
  203. package/src/components/post-trash/check.js +2 -3
  204. package/src/components/post-url/check.js +38 -0
  205. package/src/components/post-url/index.js +122 -0
  206. package/src/components/post-url/label.js +22 -0
  207. package/src/components/post-url/style.scss +16 -0
  208. package/src/components/post-visibility/index.js +11 -17
  209. package/src/components/post-visibility/label.js +4 -0
  210. package/src/components/post-visibility/style.scss +0 -17
  211. package/src/components/provider/index.js +2 -3
  212. package/src/components/provider/index.native.js +12 -17
  213. package/src/components/provider/use-block-editor-settings.js +4 -8
  214. package/src/components/table-of-contents/panel.js +7 -2
  215. package/src/components/template-validation-notice/index.js +2 -3
  216. package/src/components/theme-support-check/index.js +2 -2
  217. package/src/components/time-to-read/index.js +59 -0
  218. package/src/hooks/custom-sources-backwards-compatibility.js +45 -44
  219. package/src/store/actions.js +213 -190
  220. package/src/store/reducer.js +2 -2
  221. package/src/store/selectors.js +17 -25
  222. package/src/store/test/selectors.js +10 -13
  223. package/src/style.scss +1 -0
  224. package/src/utils/media-upload/index.js +2 -5
@@ -37,37 +37,27 @@ function PostTitle( _, forwardedRef ) {
37
37
  const ref = useRef();
38
38
  const [ isSelected, setIsSelected ] = useState( false );
39
39
  const { editPost } = useDispatch( editorStore );
40
- const {
41
- insertDefaultBlock,
42
- clearSelectedBlock,
43
- insertBlocks,
44
- } = useDispatch( blockEditorStore );
45
- const {
46
- isCleanNewPost,
47
- title,
48
- placeholder,
49
- isFocusMode,
50
- hasFixedToolbar,
51
- } = useSelect( ( select ) => {
52
- const {
53
- getEditedPostAttribute,
54
- isCleanNewPost: _isCleanNewPost,
55
- } = select( editorStore );
56
- const { getSettings } = select( blockEditorStore );
57
- const {
58
- titlePlaceholder,
59
- focusMode,
60
- hasFixedToolbar: _hasFixedToolbar,
61
- } = getSettings();
62
-
63
- return {
64
- isCleanNewPost: _isCleanNewPost(),
65
- title: getEditedPostAttribute( 'title' ),
66
- placeholder: titlePlaceholder,
67
- isFocusMode: focusMode,
68
- hasFixedToolbar: _hasFixedToolbar,
69
- };
70
- }, [] );
40
+ const { insertDefaultBlock, clearSelectedBlock, insertBlocks } =
41
+ useDispatch( blockEditorStore );
42
+ const { isCleanNewPost, title, placeholder, isFocusMode, hasFixedToolbar } =
43
+ useSelect( ( select ) => {
44
+ const { getEditedPostAttribute, isCleanNewPost: _isCleanNewPost } =
45
+ select( editorStore );
46
+ const { getSettings } = select( blockEditorStore );
47
+ const {
48
+ titlePlaceholder,
49
+ focusMode,
50
+ hasFixedToolbar: _hasFixedToolbar,
51
+ } = getSettings();
52
+
53
+ return {
54
+ isCleanNewPost: _isCleanNewPost(),
55
+ title: getEditedPostAttribute( 'title' ),
56
+ placeholder: titlePlaceholder,
57
+ isFocusMode: focusMode,
58
+ hasFixedToolbar: _hasFixedToolbar,
59
+ };
60
+ }, [] );
71
61
 
72
62
  useImperativeHandle( forwardedRef, () => ( {
73
63
  focus: () => {
@@ -169,19 +169,15 @@ class PostTitle extends Component {
169
169
 
170
170
  export default compose(
171
171
  withSelect( ( select ) => {
172
- const { isPostTitleSelected, getEditedPostAttribute } = select(
173
- editorStore
174
- );
175
- const {
176
- getSelectedBlockClientId,
177
- getBlockRootClientId,
178
- getSettings,
179
- } = select( blockEditorStore );
172
+ const { isPostTitleSelected, getEditedPostAttribute } =
173
+ select( editorStore );
174
+ const { getSelectedBlockClientId, getBlockRootClientId, getSettings } =
175
+ select( blockEditorStore );
180
176
 
181
177
  const selectedId = getSelectedBlockClientId();
182
178
  const selectionIsNested = !! getBlockRootClientId( selectedId );
183
- const globalStyles = getSettings()?.__experimentalGlobalStylesBaseStyles
184
- ?.color;
179
+ const globalStyles =
180
+ getSettings()?.__experimentalGlobalStylesBaseStyles?.color;
185
181
 
186
182
  return {
187
183
  postType: getEditedPostAttribute( 'type' ),
@@ -192,13 +188,11 @@ export default compose(
192
188
  };
193
189
  } ),
194
190
  withDispatch( ( dispatch ) => {
195
- const { undo, redo, togglePostTitleSelection } = dispatch(
196
- editorStore
197
- );
191
+ const { undo, redo, togglePostTitleSelection } =
192
+ dispatch( editorStore );
198
193
 
199
- const { clearSelectedBlock, insertDefaultBlock } = dispatch(
200
- blockEditorStore
201
- );
194
+ const { clearSelectedBlock, insertDefaultBlock } =
195
+ dispatch( blockEditorStore );
202
196
 
203
197
  return {
204
198
  onEnterPress() {
@@ -2,7 +2,7 @@
2
2
  position: relative;
3
3
 
4
4
  &.is-focus-mode {
5
- opacity: 0.5;
5
+ opacity: 0.2;
6
6
  transition: opacity 0.1s linear;
7
7
  @include reduce-motion("transition");
8
8
 
@@ -18,9 +18,8 @@ function PostTrashCheck( { isNew, postId, canUserDelete, children } ) {
18
18
  }
19
19
 
20
20
  export default withSelect( ( select ) => {
21
- const { isEditedPostNew, getCurrentPostId, getCurrentPostType } = select(
22
- editorStore
23
- );
21
+ const { isEditedPostNew, getCurrentPostId, getCurrentPostType } =
22
+ select( editorStore );
24
23
  const { getPostType, canUser } = select( coreStore );
25
24
  const postId = getCurrentPostId();
26
25
  const postType = getPostType( getCurrentPostType() );
@@ -0,0 +1,38 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { store as coreStore } from '@wordpress/core-data';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { store as editorStore } from '../../store';
11
+
12
+ export default function PostURLCheck( { children } ) {
13
+ const isVisible = useSelect( ( select ) => {
14
+ const postTypeSlug = select( editorStore ).getCurrentPostType();
15
+ const postType = select( coreStore ).getPostType( postTypeSlug );
16
+ if ( ! postType?.viewable ) {
17
+ return false;
18
+ }
19
+
20
+ const post = select( editorStore ).getCurrentPost();
21
+ if ( ! post.link ) {
22
+ return false;
23
+ }
24
+
25
+ const permalinkParts = select( editorStore ).getPermalinkParts();
26
+ if ( ! permalinkParts ) {
27
+ return false;
28
+ }
29
+
30
+ return true;
31
+ }, [] );
32
+
33
+ if ( ! isVisible ) {
34
+ return null;
35
+ }
36
+
37
+ return children;
38
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+ import { safeDecodeURIComponent, cleanForSlug } from '@wordpress/url';
6
+ import { useState } from '@wordpress/element';
7
+ import { __experimentalInspectorPopoverHeader as InspectorPopoverHeader } from '@wordpress/block-editor';
8
+ import { __ } from '@wordpress/i18n';
9
+ import { TextControl, ExternalLink } from '@wordpress/components';
10
+ import { store as coreStore } from '@wordpress/core-data';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import { store as editorStore } from '../../store';
16
+
17
+ export default function PostURL( { onClose } ) {
18
+ const {
19
+ isEditable,
20
+ postSlug,
21
+ viewPostLabel,
22
+ postLink,
23
+ permalinkPrefix,
24
+ permalinkSuffix,
25
+ } = useSelect( ( select ) => {
26
+ const postTypeSlug = select( editorStore ).getCurrentPostType();
27
+ const postType = select( coreStore ).getPostType( postTypeSlug );
28
+ const permalinkParts = select( editorStore ).getPermalinkParts();
29
+ return {
30
+ isEditable: select( editorStore ).isPermalinkEditable(),
31
+ postSlug: safeDecodeURIComponent(
32
+ select( editorStore ).getEditedPostSlug()
33
+ ),
34
+ viewPostLabel: postType?.labels.view_item,
35
+ postLink: select( editorStore ).getCurrentPost().link,
36
+ permalinkPrefix: permalinkParts?.prefix,
37
+ permalinkSuffix: permalinkParts?.suffix,
38
+ };
39
+ }, [] );
40
+
41
+ const { editPost } = useDispatch( editorStore );
42
+
43
+ const [ forceEmptyField, setForceEmptyField ] = useState( false );
44
+
45
+ return (
46
+ <div className="editor-post-url">
47
+ <InspectorPopoverHeader title={ __( 'URL' ) } onClose={ onClose } />
48
+ { isEditable && (
49
+ <TextControl
50
+ label={ __( 'Permalink' ) }
51
+ value={ forceEmptyField ? '' : postSlug }
52
+ autoComplete="off"
53
+ spellCheck="false"
54
+ help={
55
+ <>
56
+ { __( 'The last part of the URL.' ) }{ ' ' }
57
+ <ExternalLink
58
+ href={ __(
59
+ 'https://wordpress.org/support/article/settings-sidebar/#permalink'
60
+ ) }
61
+ >
62
+ { __( 'Learn more.' ) }
63
+ </ExternalLink>
64
+ </>
65
+ }
66
+ onChange={ ( newValue ) => {
67
+ editPost( { slug: newValue } );
68
+ // When we delete the field the permalink gets
69
+ // reverted to the original value.
70
+ // The forceEmptyField logic allows the user to have
71
+ // the field temporarily empty while typing.
72
+ if ( ! newValue ) {
73
+ if ( ! forceEmptyField ) {
74
+ setForceEmptyField( true );
75
+ }
76
+ return;
77
+ }
78
+ if ( forceEmptyField ) {
79
+ setForceEmptyField( false );
80
+ }
81
+ } }
82
+ onBlur={ ( event ) => {
83
+ editPost( {
84
+ slug: cleanForSlug( event.target.value ),
85
+ } );
86
+ if ( forceEmptyField ) {
87
+ setForceEmptyField( false );
88
+ }
89
+ } }
90
+ />
91
+ ) }
92
+ { isEditable && (
93
+ <h3 className="editor-post-url__link-label">
94
+ { viewPostLabel ?? __( 'View post' ) }
95
+ </h3>
96
+ ) }
97
+ <p>
98
+ <ExternalLink
99
+ className="editor-post-url__link"
100
+ href={ postLink }
101
+ target="_blank"
102
+ >
103
+ { isEditable ? (
104
+ <>
105
+ <span className="editor-post-url__link-prefix">
106
+ { permalinkPrefix }
107
+ </span>
108
+ <span className="editor-post-url__link-slug">
109
+ { postSlug }
110
+ </span>
111
+ <span className="editor-post-url__link-suffix">
112
+ { permalinkSuffix }
113
+ </span>
114
+ </>
115
+ ) : (
116
+ postLink
117
+ ) }
118
+ </ExternalLink>
119
+ </p>
120
+ </div>
121
+ );
122
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { filterURLForDisplay } from '@wordpress/url';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { store as editorStore } from '../../store';
11
+
12
+ export default function PostURLLabel() {
13
+ return usePostURLLabel();
14
+ }
15
+
16
+ export function usePostURLLabel() {
17
+ const postLink = useSelect(
18
+ ( select ) => select( editorStore ).getCurrentPost().link,
19
+ []
20
+ );
21
+ return filterURLForDisplay( postLink );
22
+ }
@@ -0,0 +1,16 @@
1
+ .editor-post-url__link-label {
2
+ font-size: $default-font-size;
3
+ font-weight: 400;
4
+ margin: 0;
5
+ }
6
+
7
+ /* rtl:begin:ignore */
8
+ .editor-post-url__link {
9
+ direction: ltr;
10
+ word-break: break-word;
11
+ }
12
+ /* rtl:end:ignore */
13
+
14
+ .editor-post-url__link-slug {
15
+ font-weight: 600;
16
+ }
@@ -6,11 +6,10 @@ import { useState } from '@wordpress/element';
6
6
  import {
7
7
  VisuallyHidden,
8
8
  __experimentalConfirmDialog as ConfirmDialog,
9
- Button,
10
9
  } from '@wordpress/components';
11
10
  import { useInstanceId } from '@wordpress/compose';
12
11
  import { useSelect, useDispatch } from '@wordpress/data';
13
- import { close as closeIcon } from '@wordpress/icons';
12
+ import { __experimentalInspectorPopoverHeader as InspectorPopoverHeader } from '@wordpress/block-editor';
14
13
 
15
14
  /**
16
15
  * Internal dependencies
@@ -30,9 +29,8 @@ export default function PostVisibility( { onClose } ) {
30
29
  const { editPost, savePost } = useDispatch( editorStore );
31
30
 
32
31
  const [ hasPassword, setHasPassword ] = useState( !! password );
33
- const [ showPrivateConfirmDialog, setShowPrivateConfirmDialog ] = useState(
34
- false
35
- );
32
+ const [ showPrivateConfirmDialog, setShowPrivateConfirmDialog ] =
33
+ useState( false );
36
34
 
37
35
  const setPublic = () => {
38
36
  editPost( {
@@ -70,20 +68,16 @@ export default function PostVisibility( { onClose } ) {
70
68
  };
71
69
 
72
70
  return (
73
- <>
74
- <Button
75
- className="editor-post-visibility__close"
76
- isSmall
77
- icon={ closeIcon }
78
- onClick={ onClose }
71
+ <div className="editor-post-visibility">
72
+ <InspectorPopoverHeader
73
+ title={ __( 'Visibility' ) }
74
+ help={ __( 'Control how this post is viewed.' ) }
75
+ onClose={ onClose }
79
76
  />
80
77
  <fieldset className="editor-post-visibility__fieldset">
81
- <legend className="editor-post-visibility__legend">
78
+ <VisuallyHidden as="legend">
82
79
  { __( 'Visibility' ) }
83
- </legend>
84
- <p className="editor-post-visibility__description">
85
- { __( 'Control how this post is viewed.' ) }
86
- </p>
80
+ </VisuallyHidden>
87
81
  <PostVisibilityChoice
88
82
  instanceId={ instanceId }
89
83
  value="public"
@@ -134,7 +128,7 @@ export default function PostVisibility( { onClose } ) {
134
128
  >
135
129
  { __( 'Would you like to privately publish this post now?' ) }
136
130
  </ConfirmDialog>
137
- </>
131
+ </div>
138
132
  );
139
133
  }
140
134
 
@@ -10,6 +10,10 @@ import { visibilityOptions } from './utils';
10
10
  import { store as editorStore } from '../../store';
11
11
 
12
12
  export default function PostVisibilityLabel() {
13
+ return usePostVisibilityLabel();
14
+ }
15
+
16
+ export function usePostVisibilityLabel() {
13
17
  const visibility = useSelect( ( select ) =>
14
18
  select( editorStore ).getEditedPostVisibility()
15
19
  );
@@ -1,21 +1,4 @@
1
- .editor-post-visibility__close {
2
- position: absolute;
3
- right: $grid-unit-20;
4
- top: $grid-unit-20;
5
- }
6
-
7
1
  .editor-post-visibility__fieldset {
8
- padding: $grid-unit-10;
9
-
10
- .editor-post-visibility__legend {
11
- font-weight: 600;
12
- padding: 1em 0 0 0;
13
- }
14
-
15
- .editor-post-visibility__description {
16
- margin-top: 0.5em;
17
- }
18
-
19
2
  .editor-post-visibility__radio[type="radio"] {
20
3
  @include radio-control;
21
4
  margin-top: 2px;
@@ -34,9 +34,8 @@ function EditorProvider( {
34
34
  return { postId: post.id, postType: post.type };
35
35
  }, [ post.id, post.type ] );
36
36
  const { selection, isReady } = useSelect( ( select ) => {
37
- const { getEditorSelection, __unstableIsEditorReady } = select(
38
- editorStore
39
- );
37
+ const { getEditorSelection, __unstableIsEditorReady } =
38
+ select( editorStore );
40
39
  return {
41
40
  isReady: __unstableIsEditorReady(),
42
41
  selection: getEditorSelection(),
@@ -130,9 +130,8 @@ class NativeEditorProvider extends Component {
130
130
  const blockName = 'core/' + payload.mediaType;
131
131
  const newBlock = createBlock( blockName, {
132
132
  id: payload.mediaId,
133
- [ payload.mediaType === 'image'
134
- ? 'url'
135
- : 'src' ]: payload.mediaUrl,
133
+ [ payload.mediaType === 'image' ? 'url' : 'src' ]:
134
+ payload.mediaUrl,
136
135
  } );
137
136
 
138
137
  const indexAfterSelected = this.props.selectedBlockIndex + 1;
@@ -143,14 +142,16 @@ class NativeEditorProvider extends Component {
143
142
  }
144
143
  );
145
144
 
146
- this.subscriptionParentUpdateEditorSettings = subscribeUpdateEditorSettings(
147
- ( { galleryWithImageBlocks, ...editorSettings } ) => {
148
- if ( typeof galleryWithImageBlocks === 'boolean' ) {
149
- window.wp.galleryBlockV2Enabled = galleryWithImageBlocks;
145
+ this.subscriptionParentUpdateEditorSettings =
146
+ subscribeUpdateEditorSettings(
147
+ ( { galleryWithImageBlocks, ...editorSettings } ) => {
148
+ if ( typeof galleryWithImageBlocks === 'boolean' ) {
149
+ window.wp.galleryBlockV2Enabled =
150
+ galleryWithImageBlocks;
151
+ }
152
+ updateSettings( this.getThemeColors( editorSettings ) );
150
153
  }
151
- updateSettings( this.getThemeColors( editorSettings ) );
152
- }
153
- );
154
+ );
154
155
 
155
156
  this.subscriptionParentUpdateCapabilities = subscribeUpdateCapabilities(
156
157
  ( payload ) => {
@@ -318,13 +319,7 @@ class NativeEditorProvider extends Component {
318
319
  }
319
320
 
320
321
  render() {
321
- const {
322
- children,
323
- post, // eslint-disable-line no-unused-vars
324
- capabilities,
325
- settings,
326
- ...props
327
- } = this.props;
322
+ const { children, post, capabilities, settings, ...props } = this.props;
328
323
  const editorSettings = this.getEditorSettings( settings, capabilities );
329
324
 
330
325
  return (
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { pick, defaultTo, unionBy } from 'lodash';
4
+ import { pick, unionBy } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -52,10 +52,7 @@ function useBlockEditorSettings( settings, hasTemplate ) {
52
52
  { per_page: -1 }
53
53
  )
54
54
  : [], // Reusable blocks are fetched in the native version of this hook.
55
- hasUploadPermissions: defaultTo(
56
- canUser( 'create', 'media' ),
57
- true
58
- ),
55
+ hasUploadPermissions: canUser( 'create', 'media' ) ?? true,
59
56
  userCanCreatePages: canUser( 'create', 'pages' ),
60
57
  pageOnFront: siteSettings?.page_on_front,
61
58
  };
@@ -71,9 +68,8 @@ function useBlockEditorSettings( settings, hasTemplate ) {
71
68
  const { restBlockPatterns, restBlockPatternCategories } = useSelect(
72
69
  ( select ) => ( {
73
70
  restBlockPatterns: select( coreStore ).getBlockPatterns(),
74
- restBlockPatternCategories: select(
75
- coreStore
76
- ).getBlockPatternCategories(),
71
+ restBlockPatternCategories:
72
+ select( coreStore ).getBlockPatternCategories(),
77
73
  } ),
78
74
  []
79
75
  );
@@ -9,6 +9,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
9
9
  * Internal dependencies
10
10
  */
11
11
  import WordCount from '../word-count';
12
+ import TimeToRead from '../time-to-read';
12
13
  import DocumentOutline from '../document-outline';
13
14
  import CharacterCount from '../character-count';
14
15
 
@@ -38,6 +39,10 @@ function TableOfContentsPanel( { hasOutlineItemsDisabled, onRequestClose } ) {
38
39
  tabIndex="0"
39
40
  >
40
41
  <ul role="list" className="table-of-contents__counts">
42
+ <li className="table-of-contents__count">
43
+ { __( 'Words' ) }
44
+ <WordCount />
45
+ </li>
41
46
  <li className="table-of-contents__count">
42
47
  { __( 'Characters' ) }
43
48
  <span className="table-of-contents__number">
@@ -45,8 +50,8 @@ function TableOfContentsPanel( { hasOutlineItemsDisabled, onRequestClose } ) {
45
50
  </span>
46
51
  </li>
47
52
  <li className="table-of-contents__count">
48
- { __( 'Words' ) }
49
- <WordCount />
53
+ { __( 'Time to read' ) }
54
+ <TimeToRead />
50
55
  </li>
51
56
  <li className="table-of-contents__count">
52
57
  { __( 'Headings' ) }
@@ -53,9 +53,8 @@ export default compose( [
53
53
  isValid: select( blockEditorStore ).isValidTemplate(),
54
54
  } ) ),
55
55
  withDispatch( ( dispatch ) => {
56
- const { setTemplateValidity, synchronizeTemplate } = dispatch(
57
- blockEditorStore
58
- );
56
+ const { setTemplateValidity, synchronizeTemplate } =
57
+ dispatch( blockEditorStore );
59
58
  return {
60
59
  resetTemplateValidity: () => setTemplateValidity( true ),
61
60
  synchronizeTemplate,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { castArray, includes, isArray, get, some } from 'lodash';
4
+ import { castArray, includes, get, some } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -26,7 +26,7 @@ export function ThemeSupportCheck( {
26
26
  // In the latter case, we need to verify `postType` exists
27
27
  // within `supported`. If `postType` isn't passed, then the check
28
28
  // should fail.
29
- if ( 'post-thumbnails' === key && isArray( supported ) ) {
29
+ if ( 'post-thumbnails' === key && Array.isArray( supported ) ) {
30
30
  return includes( supported, postType );
31
31
  }
32
32
  return supported;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { _x, _n, __, sprintf } from '@wordpress/i18n';
6
+ import { count as wordCount } from '@wordpress/wordcount';
7
+ import { createInterpolateElement } from '@wordpress/element';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { store as editorStore } from '../../store';
13
+
14
+ /**
15
+ * Average reading rate - based on average taken from
16
+ * https://irisreading.com/average-reading-speed-in-various-languages/
17
+ * (Characters/minute used for Chinese rather than words).
18
+ *
19
+ * @type {number} A rough estimate of the average reading rate across multiple languages.
20
+ */
21
+ const AVERAGE_READING_RATE = 189;
22
+
23
+ export default function TimeToRead() {
24
+ const content = useSelect(
25
+ ( select ) => select( editorStore ).getEditedPostAttribute( 'content' ),
26
+ []
27
+ );
28
+
29
+ /*
30
+ * translators: If your word count is based on single characters (e.g. East Asian characters),
31
+ * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
32
+ * Do not translate into your own language.
33
+ */
34
+ const wordCountType = _x( 'words', 'Word count type. Do not translate!' );
35
+ const minutesToRead = Math.round(
36
+ wordCount( content, wordCountType ) / AVERAGE_READING_RATE
37
+ );
38
+ const minutesToReadString =
39
+ minutesToRead === 0
40
+ ? createInterpolateElement( __( '<span>< 1</span> minute' ), {
41
+ span: <span className="table-of-contents__number" />,
42
+ } )
43
+ : createInterpolateElement(
44
+ sprintf(
45
+ /* translators: %s is the number of minutes the post will take to read. */
46
+ _n(
47
+ '<span>%d</span> minute',
48
+ '<span>%d</span> minutes',
49
+ minutesToRead
50
+ ),
51
+ minutesToRead
52
+ ),
53
+ {
54
+ span: <span className="table-of-contents__number" />,
55
+ }
56
+ );
57
+
58
+ return <span className="time-to-read">{ minutesToReadString }</span>;
59
+ }