@wordpress/editor 12.5.4 → 12.7.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 (36) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/post-featured-image/index.js +84 -41
  3. package/build/components/post-featured-image/index.js.map +1 -1
  4. package/build/components/post-text-editor/index.js +11 -0
  5. package/build/components/post-text-editor/index.js.map +1 -1
  6. package/build/components/post-title/index.js +13 -2
  7. package/build/components/post-title/index.js.map +1 -1
  8. package/build/components/post-visibility/index.js +132 -167
  9. package/build/components/post-visibility/index.js.map +1 -1
  10. package/build/components/post-visibility/label.js +5 -22
  11. package/build/components/post-visibility/label.js.map +1 -1
  12. package/build/components/post-visibility/utils.js +14 -13
  13. package/build/components/post-visibility/utils.js.map +1 -1
  14. package/build-module/components/post-featured-image/index.js +86 -42
  15. package/build-module/components/post-featured-image/index.js.map +1 -1
  16. package/build-module/components/post-text-editor/index.js +12 -1
  17. package/build-module/components/post-text-editor/index.js.map +1 -1
  18. package/build-module/components/post-title/index.js +12 -2
  19. package/build-module/components/post-title/index.js.map +1 -1
  20. package/build-module/components/post-visibility/index.js +132 -166
  21. package/build-module/components/post-visibility/index.js.map +1 -1
  22. package/build-module/components/post-visibility/label.js +5 -20
  23. package/build-module/components/post-visibility/label.js.map +1 -1
  24. package/build-module/components/post-visibility/utils.js +14 -13
  25. package/build-module/components/post-visibility/utils.js.map +1 -1
  26. package/build-style/style-rtl.css +42 -51
  27. package/build-style/style.css +42 -51
  28. package/package.json +28 -27
  29. package/src/components/autosave-monitor/test/index.js +3 -0
  30. package/src/components/post-featured-image/index.js +102 -69
  31. package/src/components/post-text-editor/index.js +14 -1
  32. package/src/components/post-title/index.js +16 -2
  33. package/src/components/post-visibility/index.js +130 -150
  34. package/src/components/post-visibility/label.js +6 -15
  35. package/src/components/post-visibility/style.scss +25 -20
  36. package/src/components/post-visibility/utils.js +7 -12
@@ -740,20 +740,23 @@
740
740
  color: rgba(30, 30, 30, 0.62);
741
741
  }
742
742
 
743
- .edit-post-post-visibility__dialog,
744
- .editor-post-visibility__dialog-fieldset {
745
- padding: 4px;
746
- padding-top: 0;
743
+ .editor-post-visibility__close {
744
+ position: absolute;
745
+ right: 16px;
746
+ top: 16px;
747
+ }
748
+
749
+ .editor-post-visibility__fieldset {
750
+ padding: 8px;
747
751
  }
748
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-legend,
749
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-legend {
752
+ .editor-post-visibility__fieldset .editor-post-visibility__legend {
750
753
  font-weight: 600;
751
- margin-bottom: 1em;
754
+ padding: 1em 0 0 0;
755
+ }
756
+ .editor-post-visibility__fieldset .editor-post-visibility__description {
752
757
  margin-top: 0.5em;
753
- padding: 0;
754
758
  }
755
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio],
756
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio] {
759
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio] {
757
760
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
758
761
  padding: 6px 8px;
759
762
  box-shadow: 0 0 0 transparent;
@@ -773,48 +776,40 @@
773
776
  margin-top: 2px;
774
777
  }
775
778
  @media (prefers-reduced-motion: reduce) {
776
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio],
777
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio] {
779
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio] {
778
780
  transition-duration: 0s;
779
781
  transition-delay: 0s;
780
782
  }
781
783
  }
782
784
  @media (min-width: 600px) {
783
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio],
784
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio] {
785
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio] {
785
786
  font-size: 13px;
786
787
  /* Override core line-height. To be reviewed. */
787
788
  line-height: normal;
788
789
  }
789
790
  }
790
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio]:focus,
791
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio]:focus {
791
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus {
792
792
  border-color: var(--wp-admin-theme-color);
793
793
  box-shadow: 0 0 0 1px var(--wp-admin-theme-color);
794
794
  outline: 2px solid transparent;
795
795
  }
796
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio]::-webkit-input-placeholder,
797
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio]::-webkit-input-placeholder {
796
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-webkit-input-placeholder {
798
797
  color: rgba(30, 30, 30, 0.62);
799
798
  }
800
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio]::-moz-placeholder,
801
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio]::-moz-placeholder {
799
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-moz-placeholder {
802
800
  opacity: 1;
803
801
  color: rgba(30, 30, 30, 0.62);
804
802
  }
805
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio]:-ms-input-placeholder,
806
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio]:-ms-input-placeholder {
803
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:-ms-input-placeholder {
807
804
  color: rgba(30, 30, 30, 0.62);
808
805
  }
809
806
  @media (min-width: 600px) {
810
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio],
811
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio] {
807
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio] {
812
808
  height: 20px;
813
809
  width: 20px;
814
810
  }
815
811
  }
816
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio]:checked::before,
817
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio]:checked::before {
812
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked::before {
818
813
  box-sizing: inherit;
819
814
  width: 8px;
820
815
  height: 8px;
@@ -824,36 +819,32 @@
824
819
  border: 4px solid #fff;
825
820
  }
826
821
  @media (min-width: 600px) {
827
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio]:checked::before,
828
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio]:checked::before {
822
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked::before {
829
823
  transform: translate(5px, 5px);
830
824
  }
831
825
  }
832
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio]:focus,
833
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio]:focus {
826
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus {
834
827
  box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--wp-admin-theme-color);
835
828
  outline: 2px solid transparent;
836
829
  }
837
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-radio[type=radio]:checked,
838
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-radio[type=radio]:checked {
830
+ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked {
839
831
  background: var(--wp-admin-theme-color);
840
832
  border-color: var(--wp-admin-theme-color);
841
833
  }
842
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-label,
843
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-label {
844
- font-weight: 600;
834
+ .editor-post-visibility__fieldset .editor-post-visibility__info {
835
+ color: #757575;
836
+ margin-left: 36px;
837
+ margin-top: 0.5em;
845
838
  }
846
- .edit-post-post-visibility__dialog .editor-post-visibility__dialog-info,
847
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__dialog-info {
848
- margin-top: 0;
849
- margin-left: 32px;
839
+ @media (min-width: 600px) {
840
+ .editor-post-visibility__fieldset .editor-post-visibility__info {
841
+ margin-left: 32px;
842
+ }
850
843
  }
851
- .edit-post-post-visibility__dialog .editor-post-visibility__choice:last-child .editor-post-visibility__dialog-info,
852
- .editor-post-visibility__dialog-fieldset .editor-post-visibility__choice:last-child .editor-post-visibility__dialog-info {
844
+ .editor-post-visibility__fieldset .editor-post-visibility__choice:last-child .editor-post-visibility__info {
853
845
  margin-bottom: 0;
854
846
  }
855
-
856
- .editor-post-visibility__dialog-password .editor-post-visibility__dialog-password-input[type=text] {
847
+ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text] {
857
848
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
858
849
  padding: 6px 8px;
859
850
  box-shadow: 0 0 0 transparent;
@@ -864,35 +855,35 @@
864
855
  font-size: 16px;
865
856
  /* Override core line-height. To be reviewed. */
866
857
  line-height: normal;
867
- margin-left: 36px;
868
- margin-top: 8px;
858
+ margin-left: 32px;
859
+ width: calc(100% - 32px);
869
860
  }
870
861
  @media (prefers-reduced-motion: reduce) {
871
- .editor-post-visibility__dialog-password .editor-post-visibility__dialog-password-input[type=text] {
862
+ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text] {
872
863
  transition-duration: 0s;
873
864
  transition-delay: 0s;
874
865
  }
875
866
  }
876
867
  @media (min-width: 600px) {
877
- .editor-post-visibility__dialog-password .editor-post-visibility__dialog-password-input[type=text] {
868
+ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text] {
878
869
  font-size: 13px;
879
870
  /* Override core line-height. To be reviewed. */
880
871
  line-height: normal;
881
872
  }
882
873
  }
883
- .editor-post-visibility__dialog-password .editor-post-visibility__dialog-password-input[type=text]:focus {
874
+ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:focus {
884
875
  border-color: var(--wp-admin-theme-color);
885
876
  box-shadow: 0 0 0 1px var(--wp-admin-theme-color);
886
877
  outline: 2px solid transparent;
887
878
  }
888
- .editor-post-visibility__dialog-password .editor-post-visibility__dialog-password-input[type=text]::-webkit-input-placeholder {
879
+ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-webkit-input-placeholder {
889
880
  color: rgba(30, 30, 30, 0.62);
890
881
  }
891
- .editor-post-visibility__dialog-password .editor-post-visibility__dialog-password-input[type=text]::-moz-placeholder {
882
+ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-moz-placeholder {
892
883
  opacity: 1;
893
884
  color: rgba(30, 30, 30, 0.62);
894
885
  }
895
- .editor-post-visibility__dialog-password .editor-post-visibility__dialog-password-input[type=text]:-ms-input-placeholder {
886
+ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:-ms-input-placeholder {
896
887
  color: rgba(30, 30, 30, 0.62);
897
888
  }
898
889
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/editor",
3
- "version": "12.5.4",
3
+ "version": "12.7.0",
4
4
  "description": "Enhanced block editor for WordPress posts.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -31,31 +31,32 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "@babel/runtime": "^7.16.0",
34
- "@wordpress/a11y": "^3.6.1",
35
- "@wordpress/api-fetch": "^6.3.1",
36
- "@wordpress/block-editor": "^8.5.4",
37
- "@wordpress/blocks": "^11.5.3",
38
- "@wordpress/components": "^19.8.3",
39
- "@wordpress/compose": "^5.4.1",
40
- "@wordpress/core-data": "^4.4.4",
41
- "@wordpress/data": "^6.6.1",
42
- "@wordpress/date": "^4.6.1",
43
- "@wordpress/deprecated": "^3.6.1",
44
- "@wordpress/element": "^4.4.1",
45
- "@wordpress/hooks": "^3.6.1",
46
- "@wordpress/html-entities": "^3.6.1",
47
- "@wordpress/i18n": "^4.6.1",
48
- "@wordpress/icons": "^8.2.2",
49
- "@wordpress/keyboard-shortcuts": "^3.4.1",
50
- "@wordpress/keycodes": "^3.6.1",
51
- "@wordpress/media-utils": "^3.4.1",
52
- "@wordpress/notices": "^3.6.1",
53
- "@wordpress/preferences": "^1.2.3",
54
- "@wordpress/reusable-blocks": "^3.4.4",
55
- "@wordpress/rich-text": "^5.4.2",
56
- "@wordpress/server-side-render": "^3.4.4",
57
- "@wordpress/url": "^3.7.1",
58
- "@wordpress/wordcount": "^3.6.1",
34
+ "@wordpress/a11y": "^3.8.0",
35
+ "@wordpress/api-fetch": "^6.5.0",
36
+ "@wordpress/blob": "^3.8.0",
37
+ "@wordpress/block-editor": "^9.0.0",
38
+ "@wordpress/blocks": "^11.7.0",
39
+ "@wordpress/components": "^19.10.0",
40
+ "@wordpress/compose": "^5.6.0",
41
+ "@wordpress/core-data": "^4.6.0",
42
+ "@wordpress/data": "^6.8.0",
43
+ "@wordpress/date": "^4.8.0",
44
+ "@wordpress/deprecated": "^3.8.0",
45
+ "@wordpress/element": "^4.6.0",
46
+ "@wordpress/hooks": "^3.8.0",
47
+ "@wordpress/html-entities": "^3.8.0",
48
+ "@wordpress/i18n": "^4.8.0",
49
+ "@wordpress/icons": "^8.4.0",
50
+ "@wordpress/keyboard-shortcuts": "^3.6.0",
51
+ "@wordpress/keycodes": "^3.8.0",
52
+ "@wordpress/media-utils": "^3.6.0",
53
+ "@wordpress/notices": "^3.8.0",
54
+ "@wordpress/preferences": "^2.0.0",
55
+ "@wordpress/reusable-blocks": "^3.6.0",
56
+ "@wordpress/rich-text": "^5.6.0",
57
+ "@wordpress/server-side-render": "^3.6.0",
58
+ "@wordpress/url": "^3.9.0",
59
+ "@wordpress/wordcount": "^3.8.0",
59
60
  "classnames": "^2.3.1",
60
61
  "lodash": "^4.17.21",
61
62
  "memize": "^1.1.0",
@@ -69,5 +70,5 @@
69
70
  "publishConfig": {
70
71
  "access": "public"
71
72
  },
72
- "gitHead": "1fdd4758150247d6b690051aed18fa27c15f3a32"
73
+ "gitHead": "4631d515033397fcfeda77e5755960253caef9bf"
73
74
  }
@@ -23,6 +23,9 @@ describe( 'AutosaveMonitor', () => {
23
23
  } );
24
24
 
25
25
  afterEach( () => {
26
+ jest.runOnlyPendingTimers();
27
+ jest.useRealTimers();
28
+
26
29
  setAutosaveTimerSpy.mockClear();
27
30
  } );
28
31
 
@@ -16,8 +16,10 @@ import {
16
16
  withNotices,
17
17
  withFilters,
18
18
  } from '@wordpress/components';
19
+ import { isBlobURL } from '@wordpress/blob';
20
+ import { useState } from '@wordpress/element';
19
21
  import { compose } from '@wordpress/compose';
20
- import { withSelect, withDispatch } from '@wordpress/data';
22
+ import { useSelect, withDispatch, withSelect } from '@wordpress/data';
21
23
  import {
22
24
  MediaUpload,
23
25
  MediaUploadCheck,
@@ -38,63 +40,94 @@ const DEFAULT_FEATURE_IMAGE_LABEL = __( 'Featured image' );
38
40
  const DEFAULT_SET_FEATURE_IMAGE_LABEL = __( 'Set featured image' );
39
41
  const DEFAULT_REMOVE_FEATURE_IMAGE_LABEL = __( 'Remove image' );
40
42
 
43
+ const instructions = (
44
+ <p>
45
+ { __(
46
+ 'To edit the featured image, you need permission to upload media.'
47
+ ) }
48
+ </p>
49
+ );
50
+
51
+ function getMediaDetails( media, postId ) {
52
+ if ( ! media ) {
53
+ return {};
54
+ }
55
+
56
+ const defaultSize = applyFilters(
57
+ 'editor.PostFeaturedImage.imageSize',
58
+ 'large',
59
+ media.id,
60
+ postId
61
+ );
62
+ if ( has( media, [ 'media_details', 'sizes', defaultSize ] ) ) {
63
+ return {
64
+ mediaWidth: media.media_details.sizes[ defaultSize ].width,
65
+ mediaHeight: media.media_details.sizes[ defaultSize ].height,
66
+ mediaSourceUrl: media.media_details.sizes[ defaultSize ].source_url,
67
+ };
68
+ }
69
+
70
+ // Use fallbackSize when defaultSize is not available.
71
+ const fallbackSize = applyFilters(
72
+ 'editor.PostFeaturedImage.imageSize',
73
+ 'thumbnail',
74
+ media.id,
75
+ postId
76
+ );
77
+ if ( has( media, [ 'media_details', 'sizes', fallbackSize ] ) ) {
78
+ return {
79
+ mediaWidth: media.media_details.sizes[ fallbackSize ].width,
80
+ mediaHeight: media.media_details.sizes[ fallbackSize ].height,
81
+ mediaSourceUrl:
82
+ media.media_details.sizes[ fallbackSize ].source_url,
83
+ };
84
+ }
85
+
86
+ // Use full image size when fallbackSize and defaultSize are not available.
87
+ return {
88
+ mediaWidth: media.media_details.width,
89
+ mediaHeight: media.media_details.height,
90
+ mediaSourceUrl: media.source_url,
91
+ };
92
+ }
93
+
41
94
  function PostFeaturedImage( {
42
95
  currentPostId,
43
96
  featuredImageId,
44
97
  onUpdateImage,
45
- onDropImage,
46
98
  onRemoveImage,
47
99
  media,
48
100
  postType,
49
101
  noticeUI,
102
+ noticeOperations,
50
103
  } ) {
104
+ const [ isLoading, setIsLoading ] = useState( false );
105
+ const mediaUpload = useSelect( ( select ) => {
106
+ return select( blockEditorStore ).getSettings().mediaUpload;
107
+ }, [] );
51
108
  const postLabel = get( postType, [ 'labels' ], {} );
52
- const instructions = (
53
- <p>
54
- { __(
55
- 'To edit the featured image, you need permission to upload media.'
56
- ) }
57
- </p>
109
+ const { mediaWidth, mediaHeight, mediaSourceUrl } = getMediaDetails(
110
+ media,
111
+ currentPostId
58
112
  );
59
113
 
60
- let mediaWidth, mediaHeight, mediaSourceUrl;
61
- if ( media ) {
62
- const mediaSize = applyFilters(
63
- 'editor.PostFeaturedImage.imageSize',
64
- 'post-thumbnail',
65
- media.id,
66
- currentPostId
67
- );
68
- if ( has( media, [ 'media_details', 'sizes', mediaSize ] ) ) {
69
- // Use mediaSize when available.
70
- mediaWidth = media.media_details.sizes[ mediaSize ].width;
71
- mediaHeight = media.media_details.sizes[ mediaSize ].height;
72
- mediaSourceUrl = media.media_details.sizes[ mediaSize ].source_url;
73
- } else {
74
- // Get fallbackMediaSize if mediaSize is not available.
75
- const fallbackMediaSize = applyFilters(
76
- 'editor.PostFeaturedImage.imageSize',
77
- 'thumbnail',
78
- media.id,
79
- currentPostId
80
- );
81
- if (
82
- has( media, [ 'media_details', 'sizes', fallbackMediaSize ] )
83
- ) {
84
- // Use fallbackMediaSize when mediaSize is not available.
85
- mediaWidth =
86
- media.media_details.sizes[ fallbackMediaSize ].width;
87
- mediaHeight =
88
- media.media_details.sizes[ fallbackMediaSize ].height;
89
- mediaSourceUrl =
90
- media.media_details.sizes[ fallbackMediaSize ].source_url;
91
- } else {
92
- // Use full image size when mediaFallbackSize and mediaSize are not available.
93
- mediaWidth = media.media_details.width;
94
- mediaHeight = media.media_details.height;
95
- mediaSourceUrl = media.source_url;
96
- }
97
- }
114
+ function onDropFiles( filesList ) {
115
+ mediaUpload( {
116
+ allowedTypes: [ 'image' ],
117
+ filesList,
118
+ onFileChange( [ image ] ) {
119
+ if ( isBlobURL( image?.url ) ) {
120
+ setIsLoading( true );
121
+ return;
122
+ }
123
+ onUpdateImage( image );
124
+ setIsLoading( false );
125
+ },
126
+ onError( message ) {
127
+ noticeOperations.removeAllNotices();
128
+ noticeOperations.createErrorNotice( message );
129
+ },
130
+ } );
98
131
  }
99
132
 
100
133
  return (
@@ -165,40 +198,40 @@ function PostFeaturedImage( {
165
198
  />
166
199
  </ResponsiveWrapper>
167
200
  ) }
168
- { !! featuredImageId && ! media && (
169
- <Spinner />
170
- ) }
201
+ { isLoading && <Spinner /> }
171
202
  { ! featuredImageId &&
203
+ ! isLoading &&
172
204
  ( postLabel.set_featured_image ||
173
205
  DEFAULT_SET_FEATURE_IMAGE_LABEL ) }
174
206
  </Button>
175
- <DropZone onFilesDrop={ onDropImage } />
207
+ <DropZone onFilesDrop={ onDropFiles } />
176
208
  </div>
177
209
  ) }
178
210
  value={ featuredImageId }
179
211
  />
180
212
  </MediaUploadCheck>
181
- { !! featuredImageId && media && ! media.isLoading && (
182
- <MediaUploadCheck>
183
- <MediaUpload
184
- title={
185
- postLabel.featured_image ||
186
- DEFAULT_FEATURE_IMAGE_LABEL
187
- }
188
- onSelect={ onUpdateImage }
189
- unstableFeaturedImageFlow
190
- allowedTypes={ ALLOWED_MEDIA_TYPES }
191
- modalClass="editor-post-featured-image__media-modal"
192
- render={ ( { open } ) => (
193
- <Button onClick={ open } variant="secondary">
194
- { __( 'Replace Image' ) }
195
- </Button>
196
- ) }
197
- />
198
- </MediaUploadCheck>
199
- ) }
200
213
  { !! featuredImageId && (
201
214
  <MediaUploadCheck>
215
+ { media && (
216
+ <MediaUpload
217
+ title={
218
+ postLabel.featured_image ||
219
+ DEFAULT_FEATURE_IMAGE_LABEL
220
+ }
221
+ onSelect={ onUpdateImage }
222
+ unstableFeaturedImageFlow
223
+ allowedTypes={ ALLOWED_MEDIA_TYPES }
224
+ modalClass="editor-post-featured-image__media-modal"
225
+ render={ ( { open } ) => (
226
+ <Button
227
+ onClick={ open }
228
+ variant="secondary"
229
+ >
230
+ { __( 'Replace Image' ) }
231
+ </Button>
232
+ ) }
233
+ />
234
+ ) }
202
235
  <Button
203
236
  onClick={ onRemoveImage }
204
237
  variant="link"
@@ -7,7 +7,7 @@ import Textarea from 'react-autosize-textarea';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { __ } from '@wordpress/i18n';
10
- import { useState } from '@wordpress/element';
10
+ import { useEffect, useState, useRef } from '@wordpress/element';
11
11
  import { parse } from '@wordpress/blocks';
12
12
  import { useDispatch, useSelect } from '@wordpress/data';
13
13
  import { useInstanceId } from '@wordpress/compose';
@@ -29,6 +29,7 @@ export default function PostTextEditor() {
29
29
  const [ value, setValue ] = useState( postContent );
30
30
  const [ isDirty, setIsDirty ] = useState( false );
31
31
  const instanceId = useInstanceId( PostTextEditor );
32
+ const valueRef = useRef();
32
33
 
33
34
  if ( ! isDirty && value !== postContent ) {
34
35
  setValue( postContent );
@@ -65,6 +66,18 @@ export default function PostTextEditor() {
65
66
  }
66
67
  };
67
68
 
69
+ useEffect( () => {
70
+ valueRef.current = value;
71
+ }, [ value ] );
72
+
73
+ // Ensure changes aren't lost when component unmounts.
74
+ useEffect( () => {
75
+ return () => {
76
+ const blocks = parse( valueRef.current );
77
+ resetEditorBlocks( blocks );
78
+ };
79
+ }, [] );
80
+
68
81
  return (
69
82
  <>
70
83
  <VisuallyHidden
@@ -7,7 +7,13 @@ import classnames from 'classnames';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { __ } from '@wordpress/i18n';
10
- import { useEffect, useRef, useState } from '@wordpress/element';
10
+ import {
11
+ forwardRef,
12
+ useEffect,
13
+ useImperativeHandle,
14
+ useRef,
15
+ useState,
16
+ } from '@wordpress/element';
11
17
  import { decodeEntities } from '@wordpress/html-entities';
12
18
  import { ENTER } from '@wordpress/keycodes';
13
19
  import { useSelect, useDispatch } from '@wordpress/data';
@@ -27,7 +33,7 @@ import { store as editorStore } from '../../store';
27
33
  */
28
34
  const REGEXP_NEWLINES = /[\r\n]+/g;
29
35
 
30
- export default function PostTitle() {
36
+ function PostTitle( _, forwardedRef ) {
31
37
  const ref = useRef();
32
38
  const [ isSelected, setIsSelected ] = useState( false );
33
39
  const { editPost } = useDispatch( editorStore );
@@ -63,6 +69,12 @@ export default function PostTitle() {
63
69
  };
64
70
  }, [] );
65
71
 
72
+ useImperativeHandle( forwardedRef, () => ( {
73
+ focus: () => {
74
+ ref?.current?.focus();
75
+ },
76
+ } ) );
77
+
66
78
  useEffect( () => {
67
79
  if ( ! ref.current ) {
68
80
  return;
@@ -219,3 +231,5 @@ export default function PostTitle() {
219
231
  );
220
232
  /* eslint-enable jsx-a11y/heading-has-content, jsx-a11y/no-noninteractive-element-to-interactive-role */
221
233
  }
234
+
235
+ export default forwardRef( PostTitle );