@wordpress/editor 12.18.0 → 12.20.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 (111) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/entities-saved-states/entity-type-list.js +1 -7
  3. package/build/components/entities-saved-states/entity-type-list.js.map +1 -1
  4. package/build/components/entities-saved-states/index.js +1 -1
  5. package/build/components/entities-saved-states/index.js.map +1 -1
  6. package/build/components/index.js +18 -0
  7. package/build/components/index.js.map +1 -1
  8. package/build/components/post-format/index.js +1 -1
  9. package/build/components/post-format/index.js.map +1 -1
  10. package/build/components/post-publish-button/index.js +1 -1
  11. package/build/components/post-publish-button/index.js.map +1 -1
  12. package/build/components/post-publish-panel/maybe-category-panel.js +1 -7
  13. package/build/components/post-publish-panel/maybe-category-panel.js.map +1 -1
  14. package/build/components/post-publish-panel/maybe-post-format-panel.js +1 -1
  15. package/build/components/post-publish-panel/maybe-post-format-panel.js.map +1 -1
  16. package/build/components/post-publish-panel/maybe-tags-panel.js +1 -7
  17. package/build/components/post-publish-panel/maybe-tags-panel.js.map +1 -1
  18. package/build/components/post-schedule/index.js +13 -16
  19. package/build/components/post-schedule/index.js.map +1 -1
  20. package/build/components/post-taxonomies/check.js +1 -7
  21. package/build/components/post-taxonomies/check.js.map +1 -1
  22. package/build/components/post-taxonomies/flat-term-selector.js +3 -1
  23. package/build/components/post-taxonomies/flat-term-selector.js.map +1 -1
  24. package/build/components/post-taxonomies/hierarchical-term-selector.js +2 -2
  25. package/build/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
  26. package/build/components/post-taxonomies/index.js +1 -1
  27. package/build/components/post-taxonomies/index.js.map +1 -1
  28. package/build/components/post-taxonomies/most-used-terms.js +2 -1
  29. package/build/components/post-taxonomies/most-used-terms.js.map +1 -1
  30. package/build/components/post-type-support-check/index.js +1 -7
  31. package/build/components/post-type-support-check/index.js.map +1 -1
  32. package/build/components/provider/use-block-editor-settings.js +1 -1
  33. package/build/components/provider/use-block-editor-settings.js.map +1 -1
  34. package/build/components/theme-support-check/index.js +2 -2
  35. package/build/components/theme-support-check/index.js.map +1 -1
  36. package/build/components/time-to-read/index.js +2 -6
  37. package/build/components/time-to-read/index.js.map +1 -1
  38. package/build/store/selectors.js +1 -6
  39. package/build/store/selectors.js.map +1 -1
  40. package/build/store/utils/notice-builder.js +2 -2
  41. package/build/store/utils/notice-builder.js.map +1 -1
  42. package/build-module/components/entities-saved-states/entity-type-list.js +1 -6
  43. package/build-module/components/entities-saved-states/entity-type-list.js.map +1 -1
  44. package/build-module/components/entities-saved-states/index.js +2 -2
  45. package/build-module/components/entities-saved-states/index.js.map +1 -1
  46. package/build-module/components/index.js +3 -1
  47. package/build-module/components/index.js.map +1 -1
  48. package/build-module/components/post-format/index.js +2 -2
  49. package/build-module/components/post-format/index.js.map +1 -1
  50. package/build-module/components/post-publish-button/index.js +2 -2
  51. package/build-module/components/post-publish-button/index.js.map +1 -1
  52. package/build-module/components/post-publish-panel/maybe-category-panel.js +1 -6
  53. package/build-module/components/post-publish-panel/maybe-category-panel.js.map +1 -1
  54. package/build-module/components/post-publish-panel/maybe-post-format-panel.js +2 -2
  55. package/build-module/components/post-publish-panel/maybe-post-format-panel.js.map +1 -1
  56. package/build-module/components/post-publish-panel/maybe-tags-panel.js +1 -6
  57. package/build-module/components/post-publish-panel/maybe-tags-panel.js.map +1 -1
  58. package/build-module/components/post-schedule/index.js +12 -17
  59. package/build-module/components/post-schedule/index.js.map +1 -1
  60. package/build-module/components/post-taxonomies/check.js +1 -6
  61. package/build-module/components/post-taxonomies/check.js.map +1 -1
  62. package/build-module/components/post-taxonomies/flat-term-selector.js +3 -2
  63. package/build-module/components/post-taxonomies/flat-term-selector.js.map +1 -1
  64. package/build-module/components/post-taxonomies/hierarchical-term-selector.js +3 -3
  65. package/build-module/components/post-taxonomies/hierarchical-term-selector.js.map +1 -1
  66. package/build-module/components/post-taxonomies/index.js +2 -2
  67. package/build-module/components/post-taxonomies/index.js.map +1 -1
  68. package/build-module/components/post-taxonomies/most-used-terms.js +3 -2
  69. package/build-module/components/post-taxonomies/most-used-terms.js.map +1 -1
  70. package/build-module/components/post-type-support-check/index.js +1 -6
  71. package/build-module/components/post-type-support-check/index.js.map +1 -1
  72. package/build-module/components/provider/use-block-editor-settings.js +1 -1
  73. package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
  74. package/build-module/components/theme-support-check/index.js +3 -3
  75. package/build-module/components/theme-support-check/index.js.map +1 -1
  76. package/build-module/components/time-to-read/index.js +2 -6
  77. package/build-module/components/time-to-read/index.js.map +1 -1
  78. package/build-module/store/selectors.js +1 -6
  79. package/build-module/store/selectors.js.map +1 -1
  80. package/build-module/store/utils/notice-builder.js +3 -3
  81. package/build-module/store/utils/notice-builder.js.map +1 -1
  82. package/build-style/style-rtl.css +1 -6
  83. package/build-style/style.css +1 -6
  84. package/package.json +30 -28
  85. package/src/components/document-outline/test/index.js +4 -4
  86. package/src/components/entities-saved-states/entity-type-list.js +1 -7
  87. package/src/components/entities-saved-states/index.js +2 -3
  88. package/src/components/index.js +2 -0
  89. package/src/components/post-format/index.js +2 -2
  90. package/src/components/post-preview-button/test/index.js +1 -1
  91. package/src/components/post-publish-button/index.js +2 -3
  92. package/src/components/post-publish-panel/maybe-category-panel.js +1 -6
  93. package/src/components/post-publish-panel/maybe-post-format-panel.js +2 -2
  94. package/src/components/post-publish-panel/maybe-tags-panel.js +1 -6
  95. package/src/components/post-saved-state/style.scss +0 -4
  96. package/src/components/post-schedule/index.js +16 -20
  97. package/src/components/post-taxonomies/check.js +2 -7
  98. package/src/components/post-taxonomies/flat-term-selector.js +3 -2
  99. package/src/components/post-taxonomies/hierarchical-term-selector.js +3 -3
  100. package/src/components/post-taxonomies/index.js +2 -2
  101. package/src/components/post-taxonomies/most-used-terms.js +6 -3
  102. package/src/components/post-taxonomies/style.scss +1 -2
  103. package/src/components/post-text-editor/test/index.js +51 -71
  104. package/src/components/post-type-support-check/index.js +3 -9
  105. package/src/components/post-type-support-check/test/index.js +12 -13
  106. package/src/components/provider/use-block-editor-settings.js +1 -1
  107. package/src/components/theme-support-check/index.js +5 -3
  108. package/src/components/time-to-read/index.js +2 -2
  109. package/src/store/selectors.js +1 -10
  110. package/src/store/test/selectors.js +2 -56
  111. package/src/store/utils/notice-builder.js +3 -3
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { some } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -67,8 +62,7 @@ export default function EntityTypeList( {
67
62
  key={ record.key || record.property }
68
63
  record={ record }
69
64
  checked={
70
- ! some(
71
- unselectedEntities,
65
+ ! unselectedEntities.some(
72
66
  ( elt ) =>
73
67
  elt.kind === record.kind &&
74
68
  elt.name === record.name &&
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { some, groupBy } from 'lodash';
4
+ import { groupBy } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -127,8 +127,7 @@ export default function EntitiesSavedStates( { close } ) {
127
127
  const saveCheckedEntities = () => {
128
128
  const entitiesToSave = dirtyEntityRecords.filter(
129
129
  ( { kind, name, key, property } ) => {
130
- return ! some(
131
- unselectedEntities,
130
+ return ! unselectedEntities.some(
132
131
  ( elt ) =>
133
132
  elt.kind === kind &&
134
133
  elt.name === name &&
@@ -72,6 +72,8 @@ export { default as TableOfContents } from './table-of-contents';
72
72
  export { default as ThemeSupportCheck } from './theme-support-check';
73
73
  export { default as UnsavedChangesWarning } from './unsaved-changes-warning';
74
74
  export { default as WordCount } from './word-count';
75
+ export { default as TimeToRead } from './time-to-read';
76
+ export { default as CharacterCount } from './character-count';
75
77
 
76
78
  // State Related Components.
77
79
  export { default as EditorProvider } from './provider';
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { find, includes } from 'lodash';
4
+ import { find } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -66,7 +66,7 @@ export default function PostFormat() {
66
66
  // Ensure current format is always in the set.
67
67
  // The current format may not be a format supported by the theme.
68
68
  return (
69
- includes( supportedFormats, format.id ) || postFormat === format.id
69
+ supportedFormats?.includes( format.id ) || postFormat === format.id
70
70
  );
71
71
  } );
72
72
  const suggestion = find(
@@ -111,7 +111,7 @@ describe( 'PostPreviewButton', () => {
111
111
  it( 'should not be disabled if post is saveable.', async () => {
112
112
  render( <PostPreviewButton isSaveable postId={ 123 } /> );
113
113
 
114
- expect( screen.getByRole( 'button' ) ).not.toBeDisabled();
114
+ expect( screen.getByRole( 'button' ) ).toBeEnabled();
115
115
  } );
116
116
 
117
117
  it( 'should set `href` to `previewLink` if `previewLink` is specified.', async () => {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { get, some } from 'lodash';
4
+ import { get } from 'lodash';
5
5
  import classnames from 'classnames';
6
6
 
7
7
  /**
@@ -77,8 +77,7 @@ export class PostPublishButton extends Component {
77
77
  this.setState( { entitiesSavedStatesCallback: false }, () => {
78
78
  if (
79
79
  savedEntities &&
80
- some(
81
- savedEntities,
80
+ savedEntities.some(
82
81
  ( elt ) =>
83
82
  elt.kind === 'postType' &&
84
83
  elt.name === postType &&
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { some } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -34,7 +29,7 @@ function MaybeCategoryPanel() {
34
29
  );
35
30
  const postTypeSupportsCategories =
36
31
  categoriesTaxonomy &&
37
- some( categoriesTaxonomy.types, ( type ) => type === postType );
32
+ categoriesTaxonomy.types.some( ( type ) => type === postType );
38
33
  const categories =
39
34
  categoriesTaxonomy &&
40
35
  select( editorStore ).getEditedPostAttribute(
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { find, get, includes } from 'lodash';
4
+ import { find, get } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -19,7 +19,7 @@ import { store as editorStore } from '../../store';
19
19
 
20
20
  const getSuggestion = ( supportedFormats, suggestedPostFormat ) => {
21
21
  const formats = POST_FORMATS.filter( ( format ) =>
22
- includes( supportedFormats, format.id )
22
+ supportedFormats?.includes( format.id )
23
23
  );
24
24
  return find( formats, ( format ) => format.id === suggestedPostFormat );
25
25
  };
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { some } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -79,7 +74,7 @@ export default compose(
79
74
  areTagsFetched: tagsTaxonomy !== undefined,
80
75
  isPostTypeSupported:
81
76
  tagsTaxonomy &&
82
- some( tagsTaxonomy.types, ( type ) => type === postType ),
77
+ tagsTaxonomy.types.some( ( type ) => type === postType ),
83
78
  hasTags: tags && tags.length,
84
79
  };
85
80
  } ),
@@ -38,7 +38,3 @@
38
38
  .editor-post-save-draft.has-text.has-icon svg {
39
39
  margin-right: 0;
40
40
  }
41
-
42
- :root[dir="rtl"] .editor-post-saved-state.has-text.has-icon {
43
- justify-content: right;
44
- }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { parseISO, endOfMonth, startOfMonth } from 'date-fns';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
@@ -12,15 +17,6 @@ import { store as coreStore } from '@wordpress/core-data';
12
17
  */
13
18
  import { store as editorStore } from '../../store';
14
19
 
15
- function getDayOfTheMonth( date = new Date(), firstDay = true ) {
16
- const d = new Date( date );
17
- return new Date(
18
- d.getFullYear(),
19
- d.getMonth() + ( firstDay ? 0 : 1 ),
20
- firstDay ? 1 : 0
21
- ).toISOString();
22
- }
23
-
24
20
  export default function PostSchedule( { onClose } ) {
25
21
  const { postDate, postType } = useSelect(
26
22
  ( select ) => ( {
@@ -34,7 +30,7 @@ export default function PostSchedule( { onClose } ) {
34
30
  const onUpdateDate = ( date ) => editPost( { date } );
35
31
 
36
32
  const [ previewedMonth, setPreviewedMonth ] = useState(
37
- getDayOfTheMonth( postDate )
33
+ startOfMonth( new Date( postDate ) )
38
34
  );
39
35
 
40
36
  // Pick up published and schduled site posts.
@@ -42,22 +38,20 @@ export default function PostSchedule( { onClose } ) {
42
38
  ( select ) =>
43
39
  select( coreStore ).getEntityRecords( 'postType', postType, {
44
40
  status: 'publish,future',
45
- after: getDayOfTheMonth( previewedMonth ),
46
- before: getDayOfTheMonth( previewedMonth, false ),
41
+ after: startOfMonth( previewedMonth ).toISOString(),
42
+ before: endOfMonth( previewedMonth ).toISOString(),
47
43
  exclude: [ select( editorStore ).getCurrentPostId() ],
44
+ per_page: 100,
45
+ _fields: 'id,date',
48
46
  } ),
49
47
  [ previewedMonth, postType ]
50
48
  );
51
49
 
52
50
  const events = useMemo(
53
51
  () =>
54
- ( eventsByPostType || [] ).map(
55
- ( { title, type, date: eventDate } ) => ( {
56
- title: title?.rendered,
57
- type,
58
- date: new Date( eventDate ),
59
- } )
60
- ),
52
+ ( eventsByPostType || [] ).map( ( { date: eventDate } ) => ( {
53
+ date: new Date( eventDate ),
54
+ } ) ),
61
55
  [ eventsByPostType ]
62
56
  );
63
57
 
@@ -80,7 +74,9 @@ export default function PostSchedule( { onClose } ) {
80
74
  onChange={ onUpdateDate }
81
75
  is12Hour={ is12HourTime }
82
76
  events={ events }
83
- onMonthPreviewed={ setPreviewedMonth }
77
+ onMonthPreviewed={ ( date ) =>
78
+ setPreviewedMonth( parseISO( date ) )
79
+ }
84
80
  onClose={ onClose }
85
81
  />
86
82
  );
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { some, includes } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -16,8 +11,8 @@ import { store as coreStore } from '@wordpress/core-data';
16
11
  import { store as editorStore } from '../../store';
17
12
 
18
13
  export function PostTaxonomiesCheck( { postType, taxonomies, children } ) {
19
- const hasTaxonomies = some( taxonomies, ( taxonomy ) =>
20
- includes( taxonomy.types, postType )
14
+ const hasTaxonomies = taxonomies?.some( ( taxonomy ) =>
15
+ taxonomy.types.includes( postType )
21
16
  );
22
17
  if ( ! hasTaxonomies ) {
23
18
  return null;
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { escape as escapeString, find, get } from 'lodash';
4
+ import { find, get } from 'lodash';
5
+ import escapeHtml from 'escape-html';
5
6
 
6
7
  /**
7
8
  * WordPress dependencies
@@ -55,7 +56,7 @@ const termNamesToIds = ( names, terms ) => {
55
56
 
56
57
  // Tries to create a term or fetch it if it already exists.
57
58
  function findOrCreateTerm( termName, restBase, namespace ) {
58
- const escapedTermName = escapeString( termName );
59
+ const escapedTermName = escapeHtml( termName );
59
60
 
60
61
  return apiFetch( {
61
62
  path: `/${ namespace }/${ restBase }`,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { find, get, some, unescape as unescapeString, without } from 'lodash';
4
+ import { find, get, unescape as unescapeString } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -258,7 +258,7 @@ export function HierarchicalTermSelector( { slug } ) {
258
258
  const onChange = ( termId ) => {
259
259
  const hasTerm = terms.includes( termId );
260
260
  const newTerms = hasTerm
261
- ? without( terms, termId )
261
+ ? terms.filter( ( id ) => id !== termId )
262
262
  : [ ...terms, termId ];
263
263
  onUpdateTerms( newTerms );
264
264
  };
@@ -290,7 +290,7 @@ export function HierarchicalTermSelector( { slug } ) {
290
290
  const existingTerm = findTerm( availableTerms, formParent, formName );
291
291
  if ( existingTerm ) {
292
292
  // If the term we are adding exists but is not selected select it.
293
- if ( ! some( terms, ( term ) => term === existingTerm.id ) ) {
293
+ if ( ! terms.some( ( term ) => term === existingTerm.id ) ) {
294
294
  onUpdateTerms( [ ...terms, existingTerm.id ] );
295
295
  }
296
296
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { filter, includes } from 'lodash';
4
+ import { filter } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -26,7 +26,7 @@ export function PostTaxonomies( {
26
26
  taxonomyWrapper = identity,
27
27
  } ) {
28
28
  const availableTaxonomies = filter( taxonomies, ( taxonomy ) =>
29
- includes( taxonomy.types, postType )
29
+ taxonomy.types.includes( postType )
30
30
  );
31
31
  const visibleTaxonomies = filter(
32
32
  availableTaxonomies,
@@ -6,7 +6,7 @@ import { get } from 'lodash';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { Button } from '@wordpress/components';
9
+ import { BaseControl, Button } from '@wordpress/components';
10
10
  import { useSelect } from '@wordpress/data';
11
11
  import { store as coreStore } from '@wordpress/core-data';
12
12
 
@@ -47,9 +47,12 @@ export default function MostUsedTerms( { onSelect, taxonomy } ) {
47
47
 
48
48
  return (
49
49
  <div className="editor-post-taxonomies__flat-term-most-used">
50
- <h3 className="editor-post-taxonomies__flat-term-most-used-label">
50
+ <BaseControl.VisualLabel
51
+ as="h3"
52
+ className="editor-post-taxonomies__flat-term-most-used-label"
53
+ >
51
54
  { label }
52
- </h3>
55
+ </BaseControl.VisualLabel>
53
56
  { /*
54
57
  * Disable reason: The `list` ARIA role is redundant but
55
58
  * Safari+VoiceOver won't announce the list otherwise.
@@ -38,8 +38,7 @@
38
38
 
39
39
  .editor-post-taxonomies__flat-term-most-used {
40
40
  .editor-post-taxonomies__flat-term-most-used-label {
41
- font-weight: 400;
42
- margin-bottom: $grid-unit-15;
41
+ margin-bottom: $grid-unit-05;
43
42
  }
44
43
  }
45
44
 
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { act, create } from 'react-test-renderer';
5
- import Textarea from 'react-autosize-textarea';
4
+ import { act, render, screen } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
6
 
7
7
  /**
8
8
  * WordPress dependencies
@@ -38,6 +38,8 @@ jest.mock( '@wordpress/data/src/components/use-dispatch', () => {
38
38
  };
39
39
  } );
40
40
 
41
+ jest.useRealTimers();
42
+
41
43
  describe( 'PostTextEditor', () => {
42
44
  beforeEach( () => {
43
45
  useSelect.mockImplementation( () => 'Hello World' );
@@ -47,132 +49,110 @@ describe( 'PostTextEditor', () => {
47
49
  } );
48
50
 
49
51
  it( 'should render via the value from useSelect', () => {
50
- let wrapper;
51
-
52
- act( () => {
53
- wrapper = create( <PostTextEditor /> );
54
- } );
52
+ render( <PostTextEditor /> );
55
53
 
56
- const textarea = wrapper.root.findByType( Textarea );
57
- expect( textarea.props.value ).toBe( 'Hello World' );
54
+ expect( screen.getByLabelText( 'Type text or HTML' ) ).toHaveValue(
55
+ 'Hello World'
56
+ );
58
57
  } );
59
58
 
60
- it( 'should render via the state value when edits made', () => {
61
- let wrapper;
59
+ it( 'should render via the state value when edits made', async () => {
60
+ const user = userEvent.setup();
61
+ render( <PostTextEditor /> );
62
62
 
63
- act( () => {
64
- wrapper = create( <PostTextEditor /> );
65
- } );
63
+ const textarea = screen.getByLabelText( 'Type text or HTML' );
66
64
 
67
- const textarea = wrapper.root.findByType( Textarea );
65
+ await user.clear( textarea );
66
+ await user.type( textarea, 'Hello Chicken' );
68
67
 
69
- act( () =>
70
- textarea.props.onChange( { target: { value: 'Hello Chicken' } } )
71
- );
72
-
73
- expect( textarea.props.value ).toBe( 'Hello Chicken' );
68
+ expect( textarea ).toHaveValue( 'Hello Chicken' );
74
69
  expect( mockEditPost ).toHaveBeenCalledWith( {
75
70
  content: 'Hello Chicken',
76
71
  } );
77
72
  } );
78
73
 
79
- it( 'should render via the state value when edits made, even if prop value changes', () => {
80
- let wrapper;
74
+ it( 'should render via the state value when edits made, even if prop value changes', async () => {
75
+ const user = userEvent.setup();
76
+ const { rerender } = render( <PostTextEditor /> );
81
77
 
82
- act( () => {
83
- wrapper = create( <PostTextEditor /> );
84
- } );
78
+ const textarea = screen.getByLabelText( 'Type text or HTML' );
85
79
 
86
- const textarea = wrapper.root.findByType( Textarea );
87
-
88
- act( () =>
89
- textarea.props.onChange( { target: { value: 'Hello Chicken' } } )
90
- );
80
+ await user.clear( textarea );
81
+ await user.type( textarea, 'Hello Chicken' );
91
82
 
92
83
  useSelect.mockImplementation( () => 'Goodbye World' );
93
84
 
94
- act( () => {
95
- wrapper.update( <PostTextEditor /> );
96
- } );
85
+ rerender( <PostTextEditor /> );
97
86
 
98
- expect( textarea.props.value ).toBe( 'Hello Chicken' );
87
+ expect( textarea ).toHaveValue( 'Hello Chicken' );
99
88
  expect( mockEditPost ).toHaveBeenCalledWith( {
100
89
  content: 'Hello Chicken',
101
90
  } );
102
91
  } );
103
92
 
104
- it( 'should render via the state value when edits made, even if prop value changes and state value empty', () => {
105
- let wrapper;
93
+ it( 'should render via the state value when edits made, even if prop value changes and state value empty', async () => {
94
+ const user = userEvent.setup();
95
+ const { rerender } = render( <PostTextEditor /> );
106
96
 
107
- act( () => {
108
- wrapper = create( <PostTextEditor /> );
109
- } );
97
+ const textarea = screen.getByLabelText( 'Type text or HTML' );
110
98
 
111
- const textarea = wrapper.root.findByType( Textarea );
112
- act( () => textarea.props.onChange( { target: { value: '' } } ) );
99
+ await user.clear( textarea );
113
100
 
114
101
  useSelect.mockImplementation( () => 'Goodbye World' );
115
102
 
116
- act( () => {
117
- wrapper.update( <PostTextEditor /> );
118
- } );
103
+ rerender( <PostTextEditor /> );
119
104
 
120
- expect( textarea.props.value ).toBe( '' );
105
+ expect( textarea ).toHaveValue( '' );
121
106
  expect( mockEditPost ).toHaveBeenCalledWith( {
122
107
  content: '',
123
108
  } );
124
109
  } );
125
110
 
126
- it( 'calls onPersist after changes made and user stops editing', () => {
127
- let wrapper;
111
+ it( 'calls onPersist after changes made and user stops editing', async () => {
112
+ const user = userEvent.setup();
113
+ render( <PostTextEditor /> );
128
114
 
129
- act( () => {
130
- wrapper = create( <PostTextEditor /> );
131
- } );
115
+ const textarea = screen.getByLabelText( 'Type text or HTML' );
132
116
 
133
- const textarea = wrapper.root.findByType( Textarea );
117
+ await user.clear( textarea );
134
118
 
135
- act( () => textarea.props.onChange( { target: { value: '' } } ) );
136
- act( () => textarea.props.onBlur() );
119
+ // Stop editing.
120
+ act( () => {
121
+ textarea.blur();
122
+ } );
137
123
 
138
124
  expect( mockResetEditorBlocks ).toHaveBeenCalledWith( [] );
139
125
  } );
140
126
 
141
127
  it( 'does not call onPersist after user stops editing without changes', () => {
142
- let wrapper;
128
+ render( <PostTextEditor /> );
143
129
 
144
- act( () => {
145
- wrapper = create( <PostTextEditor /> );
146
- } );
147
-
148
- const textarea = wrapper.root.findByType( Textarea );
149
- act( () => textarea.props.onBlur() );
130
+ // Stop editing.
131
+ screen.getByLabelText( 'Type text or HTML' ).blur();
150
132
 
151
133
  expect( mockResetEditorBlocks ).not.toHaveBeenCalled();
152
134
  } );
153
135
 
154
- it( 'resets to prop value after user stops editing', () => {
136
+ it( 'resets to prop value after user stops editing', async () => {
155
137
  // This isn't the most realistic case, since typically we'd assume the
156
138
  // parent renderer to pass the value as it had received onPersist. The
157
139
  // test here is more an edge case to stress that it's intentionally
158
140
  // differentiating between state and prop values.
159
- let wrapper;
141
+ const user = userEvent.setup();
142
+ const { rerender } = render( <PostTextEditor /> );
160
143
 
161
- act( () => {
162
- wrapper = create( <PostTextEditor /> );
163
- } );
144
+ const textarea = screen.getByLabelText( 'Type text or HTML' );
164
145
 
165
- const textarea = wrapper.root.findByType( Textarea );
166
- act( () => textarea.props.onChange( { target: { value: '' } } ) );
146
+ await user.clear( textarea );
167
147
 
168
148
  useSelect.mockImplementation( () => 'Goodbye World' );
169
149
 
150
+ rerender( <PostTextEditor /> );
151
+
170
152
  act( () => {
171
- wrapper.update( <PostTextEditor /> );
153
+ textarea.blur();
172
154
  } );
173
155
 
174
- act( () => textarea.props.onBlur() );
175
-
176
- expect( textarea.props.value ).toBe( 'Goodbye World' );
156
+ expect( textarea ).toHaveValue( 'Goodbye World' );
177
157
  } );
178
158
  } );
@@ -1,8 +1,3 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { some, castArray } from 'lodash';
5
-
6
1
  /**
7
2
  * WordPress dependencies
8
3
  */
@@ -30,10 +25,9 @@ import { store as editorStore } from '../../store';
30
25
  export function PostTypeSupportCheck( { postType, children, supportKeys } ) {
31
26
  let isSupported = true;
32
27
  if ( postType ) {
33
- isSupported = some(
34
- castArray( supportKeys ),
35
- ( key ) => !! postType.supports[ key ]
36
- );
28
+ isSupported = (
29
+ Array.isArray( supportKeys ) ? supportKeys : [ supportKeys ]
30
+ ).some( ( key ) => !! postType.supports[ key ] );
37
31
  }
38
32
 
39
33
  if ( ! isSupported ) {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { create } from 'react-test-renderer';
4
+ import { render } from '@testing-library/react';
5
5
 
6
6
  /**
7
7
  * Internal dependencies
@@ -10,27 +10,26 @@ import { PostTypeSupportCheck } from '../';
10
10
 
11
11
  describe( 'PostTypeSupportCheck', () => {
12
12
  it( 'renders its children when post type is not known', () => {
13
- let postType;
14
- const tree = create(
15
- <PostTypeSupportCheck postType={ postType } supportKeys="title">
13
+ const { container } = render(
14
+ <PostTypeSupportCheck postType={ undefined } supportKeys="title">
16
15
  Supported
17
16
  </PostTypeSupportCheck>
18
17
  );
19
18
 
20
- expect( tree.toJSON() ).toBe( 'Supported' );
19
+ expect( container ).toHaveTextContent( 'Supported' );
21
20
  } );
22
21
 
23
22
  it( 'does not render its children when post type is known and not supports', () => {
24
23
  const postType = {
25
24
  supports: {},
26
25
  };
27
- const tree = create(
26
+ const { container } = render(
28
27
  <PostTypeSupportCheck postType={ postType } supportKeys="title">
29
28
  Supported
30
29
  </PostTypeSupportCheck>
31
30
  );
32
31
 
33
- expect( tree.toJSON() ).toBe( null );
32
+ expect( container ).not.toHaveTextContent( 'Supported' );
34
33
  } );
35
34
 
36
35
  it( 'renders its children when post type is known and supports', () => {
@@ -39,13 +38,13 @@ describe( 'PostTypeSupportCheck', () => {
39
38
  title: true,
40
39
  },
41
40
  };
42
- const tree = create(
41
+ const { container } = render(
43
42
  <PostTypeSupportCheck postType={ postType } supportKeys="title">
44
43
  Supported
45
44
  </PostTypeSupportCheck>
46
45
  );
47
46
 
48
- expect( tree.toJSON() ).toBe( 'Supported' );
47
+ expect( container ).toHaveTextContent( 'Supported' );
49
48
  } );
50
49
 
51
50
  it( 'renders its children if some of keys supported', () => {
@@ -54,7 +53,7 @@ describe( 'PostTypeSupportCheck', () => {
54
53
  title: true,
55
54
  },
56
55
  };
57
- const tree = create(
56
+ const { container } = render(
58
57
  <PostTypeSupportCheck
59
58
  postType={ postType }
60
59
  supportKeys={ [ 'title', 'thumbnail' ] }
@@ -63,14 +62,14 @@ describe( 'PostTypeSupportCheck', () => {
63
62
  </PostTypeSupportCheck>
64
63
  );
65
64
 
66
- expect( tree.toJSON() ).toBe( 'Supported' );
65
+ expect( container ).toHaveTextContent( 'Supported' );
67
66
  } );
68
67
 
69
68
  it( 'does not render its children if none of keys supported', () => {
70
69
  const postType = {
71
70
  supports: {},
72
71
  };
73
- const tree = create(
72
+ const { container } = render(
74
73
  <PostTypeSupportCheck
75
74
  postType={ postType }
76
75
  supportKeys={ [ 'title', 'thumbnail' ] }
@@ -79,6 +78,6 @@ describe( 'PostTypeSupportCheck', () => {
79
78
  </PostTypeSupportCheck>
80
79
  );
81
80
 
82
- expect( tree.toJSON() ).toBe( null );
81
+ expect( container ).not.toHaveTextContent( 'Supported' );
83
82
  } );
84
83
  } );