@wordpress/editor 14.22.0 → 14.24.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 (79) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/components/collab-sidebar/comment-form.js +3 -1
  3. package/build/components/collab-sidebar/comment-form.js.map +1 -1
  4. package/build/components/editor-interface/index.js +11 -6
  5. package/build/components/editor-interface/index.js.map +1 -1
  6. package/build/components/post-author/check.js +3 -7
  7. package/build/components/post-author/check.js.map +1 -1
  8. package/build/components/post-author/panel.js +10 -2
  9. package/build/components/post-author/panel.js.map +1 -1
  10. package/build/components/post-publish-panel/postpublish.js +11 -3
  11. package/build/components/post-publish-panel/postpublish.js.map +1 -1
  12. package/build/components/post-template/swap-template-button.js +18 -4
  13. package/build/components/post-template/swap-template-button.js.map +1 -1
  14. package/build/components/template-part-menu-items/convert-to-template-part.js +4 -1
  15. package/build/components/template-part-menu-items/convert-to-template-part.js.map +1 -1
  16. package/build/components/visual-editor/index.js +1 -2
  17. package/build/components/visual-editor/index.js.map +1 -1
  18. package/build/store/private-actions.js +2 -1
  19. package/build/store/private-actions.js.map +1 -1
  20. package/build/store/utils/notice-builder.js +2 -1
  21. package/build/store/utils/notice-builder.js.map +1 -1
  22. package/build/utils/search-templates.js +75 -0
  23. package/build/utils/search-templates.js.map +1 -0
  24. package/build-module/components/collab-sidebar/comment-form.js +4 -2
  25. package/build-module/components/collab-sidebar/comment-form.js.map +1 -1
  26. package/build-module/components/editor-interface/index.js +11 -6
  27. package/build-module/components/editor-interface/index.js.map +1 -1
  28. package/build-module/components/post-author/check.js +3 -7
  29. package/build-module/components/post-author/check.js.map +1 -1
  30. package/build-module/components/post-author/panel.js +10 -2
  31. package/build-module/components/post-author/panel.js.map +1 -1
  32. package/build-module/components/post-publish-panel/postpublish.js +12 -4
  33. package/build-module/components/post-publish-panel/postpublish.js.map +1 -1
  34. package/build-module/components/post-template/swap-template-button.js +19 -5
  35. package/build-module/components/post-template/swap-template-button.js.map +1 -1
  36. package/build-module/components/template-part-menu-items/convert-to-template-part.js +4 -1
  37. package/build-module/components/template-part-menu-items/convert-to-template-part.js.map +1 -1
  38. package/build-module/components/visual-editor/index.js +1 -2
  39. package/build-module/components/visual-editor/index.js.map +1 -1
  40. package/build-module/store/private-actions.js +2 -1
  41. package/build-module/store/private-actions.js.map +1 -1
  42. package/build-module/store/utils/notice-builder.js +2 -1
  43. package/build-module/store/utils/notice-builder.js.map +1 -1
  44. package/build-module/utils/search-templates.js +68 -0
  45. package/build-module/utils/search-templates.js.map +1 -0
  46. package/build-style/style-rtl.css +146 -28
  47. package/build-style/style.css +146 -28
  48. package/build-types/components/collab-sidebar/comment-form.d.ts.map +1 -1
  49. package/build-types/components/editor-interface/index.d.ts.map +1 -1
  50. package/build-types/components/post-author/check.d.ts.map +1 -1
  51. package/build-types/components/post-author/panel.d.ts.map +1 -1
  52. package/build-types/components/post-publish-panel/postpublish.d.ts.map +1 -1
  53. package/build-types/components/post-template/swap-template-button.d.ts.map +1 -1
  54. package/build-types/components/template-part-menu-items/convert-to-template-part.d.ts.map +1 -1
  55. package/build-types/components/visual-editor/index.d.ts.map +1 -1
  56. package/build-types/store/private-actions.d.ts.map +1 -1
  57. package/build-types/store/utils/notice-builder.d.ts.map +1 -1
  58. package/build-types/utils/search-templates.d.ts +10 -0
  59. package/build-types/utils/search-templates.d.ts.map +1 -0
  60. package/package.json +37 -37
  61. package/src/components/collab-sidebar/comment-form.js +3 -1
  62. package/src/components/editor-interface/index.js +17 -15
  63. package/src/components/editor-interface/style.scss +1 -2
  64. package/src/components/post-author/check.js +2 -7
  65. package/src/components/post-author/panel.js +10 -2
  66. package/src/components/post-author/test/check.js +3 -11
  67. package/src/components/post-publish-panel/postpublish.js +19 -3
  68. package/src/components/post-publish-panel/style.scss +3 -1
  69. package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +82 -12
  70. package/src/components/post-template/style.scss +10 -0
  71. package/src/components/post-template/swap-template-button.js +23 -6
  72. package/src/components/template-part-menu-items/convert-to-template-part.js +5 -2
  73. package/src/components/visual-editor/index.js +0 -1
  74. package/src/components/visual-editor/style.scss +6 -29
  75. package/src/store/private-actions.js +1 -0
  76. package/src/store/utils/notice-builder.js +1 -0
  77. package/src/store/utils/test/notice-builder.js +3 -1
  78. package/src/utils/search-templates.js +77 -0
  79. package/tsconfig.tsbuildinfo +1 -1
@@ -7,7 +7,7 @@ import {
7
7
  Button,
8
8
  TextareaControl,
9
9
  } from '@wordpress/components';
10
- import { _x } from '@wordpress/i18n';
10
+ import { _x, __ } from '@wordpress/i18n';
11
11
 
12
12
  /**
13
13
  * Internal dependencies
@@ -36,6 +36,8 @@ function CommentForm( { onSubmit, onCancel, thread, submitButtonText } ) {
36
36
  __nextHasNoMarginBottom
37
37
  value={ inputComment ?? '' }
38
38
  onChange={ setInputComment }
39
+ label={ __( 'Comment' ) }
40
+ hideLabelFromVision
39
41
  />
40
42
  <HStack alignment="left" spacing="3" justify="flex-start">
41
43
  <Button
@@ -56,7 +56,6 @@ export default function EditorInterface( {
56
56
  } ) {
57
57
  const {
58
58
  mode,
59
- isRichEditingEnabled,
60
59
  isInserterOpened,
61
60
  isListViewOpened,
62
61
  isDistractionFree,
@@ -69,9 +68,16 @@ export default function EditorInterface( {
69
68
  const editorSettings = getEditorSettings();
70
69
  const postTypeLabel = getPostTypeLabel();
71
70
 
71
+ let _mode = select( editorStore ).getEditorMode();
72
+ if ( ! editorSettings.richEditingEnabled && _mode === 'visual' ) {
73
+ _mode = 'text';
74
+ }
75
+ if ( ! editorSettings.codeEditingEnabled && _mode === 'text' ) {
76
+ _mode = 'visual';
77
+ }
78
+
72
79
  return {
73
- mode: select( editorStore ).getEditorMode(),
74
- isRichEditingEnabled: editorSettings.richEditingEnabled,
80
+ mode: _mode,
75
81
  isInserterOpened: select( editorStore ).isInserterOpened(),
76
82
  isListViewOpened: select( editorStore ).isListViewOpened(),
77
83
  isDistractionFree: get( 'core', 'distractionFree' ),
@@ -148,23 +154,20 @@ export default function EditorInterface( {
148
154
  editorCanvasView
149
155
  ) : (
150
156
  <>
151
- { ! isPreviewMode &&
152
- ( mode === 'text' ||
153
- ! isRichEditingEnabled ) && (
154
- <TextEditor
155
- // We should auto-focus the canvas (title) on load.
156
- // eslint-disable-next-line jsx-a11y/no-autofocus
157
- autoFocus={ autoFocus }
158
- />
159
- ) }
157
+ { ! isPreviewMode && mode === 'text' && (
158
+ <TextEditor
159
+ // We should auto-focus the canvas (title) on load.
160
+ // eslint-disable-next-line jsx-a11y/no-autofocus
161
+ autoFocus={ autoFocus }
162
+ />
163
+ ) }
160
164
  { ! isPreviewMode &&
161
165
  ! isLargeViewport &&
162
166
  mode === 'visual' && (
163
167
  <BlockToolbar hideDragHandle />
164
168
  ) }
165
169
  { ( isPreviewMode ||
166
- ( isRichEditingEnabled &&
167
- mode === 'visual' ) ) && (
170
+ mode === 'visual' ) && (
168
171
  <VisualEditor
169
172
  styles={ styles }
170
173
  contentRef={ contentRef }
@@ -187,7 +190,6 @@ export default function EditorInterface( {
187
190
  ! isDistractionFree &&
188
191
  isLargeViewport &&
189
192
  showBlockBreadcrumbs &&
190
- isRichEditingEnabled &&
191
193
  mode === 'visual' && (
192
194
  <BlockBreadcrumb rootLabelText={ documentLabel } />
193
195
  )
@@ -8,6 +8,5 @@
8
8
  }
9
9
 
10
10
  .editor-visual-editor {
11
- // Fits the height to the parent — flex-shrink ensures it doesn’t create overflow.
12
- flex: 1 1 0%;
11
+ flex: 1 0 auto;
13
12
  }
@@ -2,14 +2,12 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { useSelect } from '@wordpress/data';
5
- import { store as coreStore } from '@wordpress/core-data';
6
5
 
7
6
  /**
8
7
  * Internal dependencies
9
8
  */
10
9
  import PostTypeSupportCheck from '../post-type-support-check';
11
10
  import { store as editorStore } from '../../store';
12
- import { AUTHORS_QUERY } from './constants';
13
11
 
14
12
  /**
15
13
  * Wrapper component that renders its children only if the post type supports the author.
@@ -21,20 +19,17 @@ import { AUTHORS_QUERY } from './constants';
21
19
  * supports the author or if there are no authors available.
22
20
  */
23
21
  export default function PostAuthorCheck( { children } ) {
24
- const { hasAssignAuthorAction, hasAuthors } = useSelect( ( select ) => {
22
+ const { hasAssignAuthorAction } = useSelect( ( select ) => {
25
23
  const post = select( editorStore ).getCurrentPost();
26
24
  const canAssignAuthor = post?._links?.[ 'wp:action-assign-author' ]
27
25
  ? true
28
26
  : false;
29
27
  return {
30
28
  hasAssignAuthorAction: canAssignAuthor,
31
- hasAuthors: canAssignAuthor
32
- ? select( coreStore ).getUsers( AUTHORS_QUERY )?.length >= 1
33
- : false,
34
29
  };
35
30
  }, [] );
36
31
 
37
- if ( ! hasAssignAuthorAction || ! hasAuthors ) {
32
+ if ( ! hasAssignAuthorAction ) {
38
33
  return null;
39
34
  }
40
35
 
@@ -6,6 +6,8 @@ import { Button, Dropdown } from '@wordpress/components';
6
6
  import { useState, useMemo } from '@wordpress/element';
7
7
  import { decodeEntities } from '@wordpress/html-entities';
8
8
  import { __experimentalInspectorPopoverHeader as InspectorPopoverHeader } from '@wordpress/block-editor';
9
+ import { useSelect } from '@wordpress/data';
10
+ import { store as coreStore } from '@wordpress/core-data';
9
11
 
10
12
  /**
11
13
  * Internal dependencies
@@ -13,10 +15,16 @@ import { __experimentalInspectorPopoverHeader as InspectorPopoverHeader } from '
13
15
  import PostAuthorCheck from './check';
14
16
  import PostAuthorForm from './index';
15
17
  import PostPanelRow from '../post-panel-row';
16
- import { useAuthorsQuery } from './hook';
18
+ import { BASE_QUERY } from './constants';
19
+ import { store as editorStore } from '../../store';
17
20
 
18
21
  function PostAuthorToggle( { isOpen, onClick } ) {
19
- const { postAuthor } = useAuthorsQuery();
22
+ const { postAuthor } = useSelect( ( select ) => {
23
+ const id = select( editorStore ).getEditedPostAttribute( 'author' );
24
+ return {
25
+ postAuthor: select( coreStore ).getUser( id, BASE_QUERY ),
26
+ };
27
+ }, [] );
20
28
  const authorName =
21
29
  decodeEntities( postAuthor?.name ) || __( '(No author)' );
22
30
  return (
@@ -19,7 +19,7 @@ jest.mock( '@wordpress/data/src/components/use-select', () => {
19
19
  return mock;
20
20
  } );
21
21
 
22
- function setupUseSelectMock( hasAssignAuthorAction, hasAuthors ) {
22
+ function setupUseSelectMock( hasAssignAuthorAction ) {
23
23
  useSelect.mockImplementation( ( cb ) => {
24
24
  return cb( () => ( {
25
25
  getPostType: () => ( { supports: { author: true } } ),
@@ -29,28 +29,20 @@ function setupUseSelectMock( hasAssignAuthorAction, hasAuthors ) {
29
29
  'wp:action-assign-author': hasAssignAuthorAction,
30
30
  },
31
31
  } ),
32
- getUsers: () => Array( hasAuthors ? 1 : 0 ).fill( {} ),
33
32
  } ) );
34
33
  } );
35
34
  }
36
35
 
37
36
  describe( 'PostAuthorCheck', () => {
38
- it( 'should not render anything if has no authors', () => {
39
- setupUseSelectMock( false, true );
40
-
41
- render( <PostAuthorCheck>authors</PostAuthorCheck> );
42
- expect( screen.queryByText( 'authors' ) ).not.toBeInTheDocument();
43
- } );
44
-
45
37
  it( "should not render anything if doesn't have author action", () => {
46
- setupUseSelectMock( true, false );
38
+ setupUseSelectMock( false );
47
39
 
48
40
  render( <PostAuthorCheck>authors</PostAuthorCheck> );
49
41
  expect( screen.queryByText( 'authors' ) ).not.toBeInTheDocument();
50
42
  } );
51
43
 
52
44
  it( 'should render control', () => {
53
- setupUseSelectMock( true, true );
45
+ setupUseSelectMock( true );
54
46
 
55
47
  render( <PostAuthorCheck>authors</PostAuthorCheck> );
56
48
  expect( screen.getByText( 'authors' ) ).toBeVisible();
@@ -1,7 +1,13 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { PanelBody, Button, TextControl } from '@wordpress/components';
4
+ import {
5
+ PanelBody,
6
+ Button,
7
+ TextControl,
8
+ ExternalLink,
9
+ VisuallyHidden,
10
+ } from '@wordpress/components';
5
11
  import { __, sprintf } from '@wordpress/i18n';
6
12
  import { useCallback, useEffect, useState, useRef } from '@wordpress/element';
7
13
  import { useSelect } from '@wordpress/data';
@@ -9,6 +15,7 @@ import { addQueryArgs, safeDecodeURIComponent } from '@wordpress/url';
9
15
  import { decodeEntities } from '@wordpress/html-entities';
10
16
  import { useCopyToClipboard } from '@wordpress/compose';
11
17
  import { store as coreStore } from '@wordpress/core-data';
18
+ import { external } from '@wordpress/icons';
12
19
 
13
20
  /**
14
21
  * Internal dependencies
@@ -118,9 +125,9 @@ export default function PostPublishPanelPostpublish( {
118
125
  return (
119
126
  <div className="post-publish-panel__postpublish">
120
127
  <PanelBody className="post-publish-panel__postpublish-header">
121
- <a ref={ postLinkRef } href={ link }>
128
+ <ExternalLink ref={ postLinkRef } href={ link }>
122
129
  { decodeEntities( post.title ) || __( '(no title)' ) }
123
- </a>{ ' ' }
130
+ </ExternalLink>{ ' ' }
124
131
  { postPublishNonLinkHeader }
125
132
  </PanelBody>
126
133
  <PanelBody>
@@ -153,8 +160,17 @@ export default function PostPublishPanelPostpublish( {
153
160
  variant="primary"
154
161
  href={ link }
155
162
  __next40pxDefaultSize
163
+ icon={ external }
164
+ iconPosition="right"
165
+ target="_blank"
156
166
  >
157
167
  { viewPostLabel }
168
+ <VisuallyHidden as="span">
169
+ {
170
+ /* translators: accessibility text */
171
+ __( '(opens in a new tab)' )
172
+ }
173
+ </VisuallyHidden>
158
174
  </Button>
159
175
  ) }
160
176
  <Button
@@ -138,9 +138,11 @@
138
138
  flex-wrap: wrap;
139
139
  gap: $grid-unit-20;
140
140
 
141
- .components-button {
141
+ .components-button,
142
+ .components-button.has-icon {
142
143
  justify-content: center;
143
144
  flex: 1;
145
+ min-width: unset;
144
146
  }
145
147
 
146
148
  .components-clipboard-button {
@@ -27,7 +27,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
27
27
  padding: 0;
28
28
  }
29
29
 
30
- .emotion-10 {
30
+ .emotion-12 {
31
31
  display: -webkit-box;
32
32
  display: -webkit-flex;
33
33
  display: -ms-flexbox;
@@ -47,7 +47,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
47
47
  width: 100%;
48
48
  }
49
49
 
50
- .emotion-10>* {
50
+ .emotion-12>* {
51
51
  min-width: 0;
52
52
  }
53
53
 
@@ -87,9 +87,22 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
87
87
  class="components-panel__body post-publish-panel__postpublish-header is-opened"
88
88
  >
89
89
  <a
90
+ class="components-external-link"
90
91
  href="https://wordpress.local/sample-page/"
92
+ rel="external noreferrer noopener"
93
+ target="_blank"
91
94
  >
92
- (no title)
95
+ <span
96
+ class="components-external-link__contents"
97
+ >
98
+ (no title)
99
+ </span>
100
+ <span
101
+ aria-label="(opens in a new tab)"
102
+ class="components-external-link__icon"
103
+ >
104
+
105
+ </span>
93
106
  </a>
94
107
 
95
108
  is now live.
@@ -143,9 +156,31 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
143
156
  class="post-publish-panel__postpublish-buttons"
144
157
  >
145
158
  <a
146
- class="components-button is-next-40px-default-size is-primary"
159
+ class="components-button is-next-40px-default-size is-primary has-icon"
147
160
  href="https://wordpress.local/sample-page/"
148
- />
161
+ target="_blank"
162
+ >
163
+ <span
164
+ class="components-visually-hidden emotion-6 emotion-7"
165
+ data-wp-c16t="true"
166
+ data-wp-component="VisuallyHidden"
167
+ style="border: 0px; clip: rect(1px, 1px, 1px, 1px); clip-path: inset( 50% ); height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px; word-wrap: normal;"
168
+ >
169
+ (opens in a new tab)
170
+ </span>
171
+ <svg
172
+ aria-hidden="true"
173
+ focusable="false"
174
+ height="24"
175
+ viewBox="0 0 24 24"
176
+ width="24"
177
+ xmlns="http://www.w3.org/2000/svg"
178
+ >
179
+ <path
180
+ d="M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"
181
+ />
182
+ </svg>
183
+ </a>
149
184
  <a
150
185
  class="components-button is-next-40px-default-size is-secondary"
151
186
  href="post-new.php?"
@@ -164,7 +199,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
164
199
  class="components-base-control__field emotion-2 emotion-3"
165
200
  >
166
201
  <div
167
- class="components-flex components-h-stack emotion-10 emotion-11"
202
+ class="components-flex components-h-stack emotion-12 emotion-7"
168
203
  data-wp-c16t="true"
169
204
  data-wp-component="HStack"
170
205
  >
@@ -219,7 +254,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
219
254
  padding: 0;
220
255
  }
221
256
 
222
- .emotion-10 {
257
+ .emotion-12 {
223
258
  display: -webkit-box;
224
259
  display: -webkit-flex;
225
260
  display: -ms-flexbox;
@@ -239,7 +274,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
239
274
  width: 100%;
240
275
  }
241
276
 
242
- .emotion-10>* {
277
+ .emotion-12>* {
243
278
  min-width: 0;
244
279
  }
245
280
 
@@ -279,9 +314,22 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
279
314
  class="components-panel__body post-publish-panel__postpublish-header is-opened"
280
315
  >
281
316
  <a
317
+ class="components-external-link"
282
318
  href="https://wordpress.local/sample-page/"
319
+ rel="external noreferrer noopener"
320
+ target="_blank"
283
321
  >
284
- (no title)
322
+ <span
323
+ class="components-external-link__contents"
324
+ >
325
+ (no title)
326
+ </span>
327
+ <span
328
+ aria-label="(opens in a new tab)"
329
+ class="components-external-link__icon"
330
+ >
331
+
332
+ </span>
285
333
  </a>
286
334
 
287
335
  is now live.
@@ -335,9 +383,31 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
335
383
  class="post-publish-panel__postpublish-buttons"
336
384
  >
337
385
  <a
338
- class="components-button is-next-40px-default-size is-primary"
386
+ class="components-button is-next-40px-default-size is-primary has-icon"
339
387
  href="https://wordpress.local/sample-page/"
340
- />
388
+ target="_blank"
389
+ >
390
+ <span
391
+ class="components-visually-hidden emotion-6 emotion-7"
392
+ data-wp-c16t="true"
393
+ data-wp-component="VisuallyHidden"
394
+ style="border: 0px; clip: rect(1px, 1px, 1px, 1px); clip-path: inset( 50% ); height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px; word-wrap: normal;"
395
+ >
396
+ (opens in a new tab)
397
+ </span>
398
+ <svg
399
+ aria-hidden="true"
400
+ focusable="false"
401
+ height="24"
402
+ viewBox="0 0 24 24"
403
+ width="24"
404
+ xmlns="http://www.w3.org/2000/svg"
405
+ >
406
+ <path
407
+ d="M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"
408
+ />
409
+ </svg>
410
+ </a>
341
411
  <a
342
412
  class="components-button is-next-40px-default-size is-secondary"
343
413
  href="post-new.php?"
@@ -356,7 +426,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
356
426
  class="components-base-control__field emotion-2 emotion-3"
357
427
  >
358
428
  <div
359
- class="components-flex components-h-stack emotion-10 emotion-11"
429
+ class="components-flex components-h-stack emotion-12 emotion-7"
360
430
  data-wp-c16t="true"
361
431
  data-wp-component="HStack"
362
432
  >
@@ -1,5 +1,15 @@
1
1
  .editor-post-template__swap-template-modal {
2
2
  z-index: z-index(".editor-post-template__swap-template-modal");
3
+
4
+ .editor-post-template__swap-template-search {
5
+ background: $white;
6
+ position: sticky;
7
+ top: 0;
8
+ padding: $grid-unit-20 0;
9
+ transform: translateY(- $grid-unit-05); // Offsets the top padding on the modal content container
10
+ margin-bottom: - $grid-unit-05;
11
+ z-index: z-index(".editor-post-template__swap-template-search");
12
+ }
3
13
  }
4
14
 
5
15
  .editor-post-template__create-template-modal {
@@ -4,7 +4,7 @@
4
4
  import { useMemo, useState } from '@wordpress/element';
5
5
  import { decodeEntities } from '@wordpress/html-entities';
6
6
  import { __experimentalBlockPatternsList as BlockPatternsList } from '@wordpress/block-editor';
7
- import { MenuItem, Modal } from '@wordpress/components';
7
+ import { MenuItem, Modal, SearchControl } from '@wordpress/components';
8
8
  import { __ } from '@wordpress/i18n';
9
9
  import { useDispatch } from '@wordpress/data';
10
10
  import { store as coreStore } from '@wordpress/core-data';
@@ -14,6 +14,7 @@ import { parse } from '@wordpress/blocks';
14
14
  * Internal dependencies
15
15
  */
16
16
  import { useAvailableTemplates, useEditedPostContext } from './hooks';
17
+ import { searchTemplates } from '../../utils/search-templates';
17
18
 
18
19
  export default function SwapTemplateButton( { onClick } ) {
19
20
  const [ showModal, setShowModal ] = useState( false );
@@ -61,6 +62,7 @@ export default function SwapTemplateButton( { onClick } ) {
61
62
  }
62
63
 
63
64
  function TemplatesList( { postType, onSelect } ) {
65
+ const [ searchValue, setSearchValue ] = useState( '' );
64
66
  const availableTemplates = useAvailableTemplates( postType );
65
67
  const templatesAsPatterns = useMemo(
66
68
  () =>
@@ -72,11 +74,26 @@ function TemplatesList( { postType, onSelect } ) {
72
74
  } ) ),
73
75
  [ availableTemplates ]
74
76
  );
77
+
78
+ const filteredBlockTemplates = useMemo( () => {
79
+ return searchTemplates( templatesAsPatterns, searchValue );
80
+ }, [ templatesAsPatterns, searchValue ] );
81
+
75
82
  return (
76
- <BlockPatternsList
77
- label={ __( 'Templates' ) }
78
- blockPatterns={ templatesAsPatterns }
79
- onClickPattern={ onSelect }
80
- />
83
+ <>
84
+ <SearchControl
85
+ __nextHasNoMarginBottom
86
+ onChange={ setSearchValue }
87
+ value={ searchValue }
88
+ label={ __( 'Search' ) }
89
+ placeholder={ __( 'Search' ) }
90
+ className="editor-post-template__swap-template-search"
91
+ />
92
+ <BlockPatternsList
93
+ label={ __( 'Templates' ) }
94
+ blockPatterns={ filteredBlockTemplates }
95
+ onClickPattern={ onSelect }
96
+ />
97
+ </>
81
98
  );
82
99
  }
@@ -9,6 +9,7 @@ import { __ } from '@wordpress/i18n';
9
9
  import { useState } from '@wordpress/element';
10
10
  import { store as noticesStore } from '@wordpress/notices';
11
11
  import { symbolFilled } from '@wordpress/icons';
12
+ import { store as coreStore } from '@wordpress/core-data';
12
13
 
13
14
  /**
14
15
  * Internal dependencies
@@ -20,8 +21,10 @@ export default function ConvertToTemplatePart( { clientIds, blocks } ) {
20
21
  const { replaceBlocks } = useDispatch( blockEditorStore );
21
22
  const { createSuccessNotice } = useDispatch( noticesStore );
22
23
 
23
- const { canCreate } = useSelect( ( select ) => {
24
+ const { isBlockBasedTheme, canCreate } = useSelect( ( select ) => {
24
25
  return {
26
+ isBlockBasedTheme:
27
+ select( coreStore ).getCurrentTheme()?.is_block_theme,
25
28
  canCreate:
26
29
  select( blockEditorStore ).canInsertBlockType(
27
30
  'core/template-part'
@@ -29,7 +32,7 @@ export default function ConvertToTemplatePart( { clientIds, blocks } ) {
29
32
  };
30
33
  }, [] );
31
34
 
32
- if ( ! canCreate ) {
35
+ if ( ! isBlockBasedTheme || ! canCreate ) {
33
36
  return null;
34
37
  }
35
38
 
@@ -385,7 +385,6 @@ function VisualEditor( {
385
385
  'has-padding': isFocusedEntity || enableResizing,
386
386
  'is-resizable': enableResizing,
387
387
  'is-iframed': ! disableIframe,
388
- 'is-scrollable': disableIframe || deviceType !== 'Desktop',
389
388
  }
390
389
  ) }
391
390
  >
@@ -6,9 +6,6 @@
6
6
  // when the iframe doesn't cover the whole canvas
7
7
  // like the "focused entities".
8
8
  background-color: $gray-300;
9
- // Allows the height to fit the parent container and avoids parent scrolling contexts from
10
- // having overflow due to popovers of block tools.
11
- overflow: hidden;
12
9
 
13
10
  // This overrides the iframe background since it's applied again here
14
11
  // It also prevents some style glitches if `editor-visual-editor`
@@ -28,6 +25,12 @@
28
25
  padding: $grid-unit-30 $grid-unit-30 0;
29
26
  }
30
27
 
28
+ // In the iframed canvas this keeps extra scrollbars from appearing (when block toolbars overflow). In the
29
+ // legacy (non-iframed) canvas, overflow must not be hidden in order to maintain support for sticky positioning.
30
+ &.is-iframed {
31
+ overflow: hidden;
32
+ }
33
+
31
34
  // The button element easily inherits styles that are meant for the editor style.
32
35
  // These rules enhance the specificity to reduce that inheritance.
33
36
  // This is duplicated in edit-site.
@@ -41,30 +44,4 @@
41
44
  padding: 6px;
42
45
  }
43
46
  }
44
-
45
- // The cases for this are non-iframed editor canvas or previewing devices. The block canvas is
46
- // made the scrolling context.
47
- &.is-scrollable .block-editor-block-canvas {
48
- overflow: auto;
49
-
50
- // Applicable only when legacy (non-iframed).
51
- > .block-editor-writing-flow {
52
- display: flow-root;
53
- min-height: 100%;
54
- box-sizing: border-box; // Ensures that 100% min-height doesn’t create overflow.
55
- }
56
-
57
- // Applicable only when iframed. These styles ensure that if the the iframe is
58
- // given a fixed height and it’s taller than the viewport then scrolling is
59
- // allowed. This is needed for device previews.
60
- > .block-editor-iframe__container {
61
- display: flex;
62
- flex-direction: column;
63
-
64
- > .block-editor-iframe__scale-container {
65
- flex: 1 0 fit-content;
66
- display: flow-root;
67
- }
68
- }
69
- }
70
47
  }
@@ -216,6 +216,7 @@ export const saveDirtyEntities =
216
216
  {
217
217
  label: __( 'View site' ),
218
218
  url: homeUrl,
219
+ openInNewTab: true,
219
220
  },
220
221
  ],
221
222
  } );
@@ -58,6 +58,7 @@ export function getNotificationArgumentsForSaveSuccess( data ) {
58
58
  actions.push( {
59
59
  label: isDraft ? __( 'View Preview' ) : postType.labels.view_item,
60
60
  url: post.link,
61
+ openInNewTab: true,
61
62
  } );
62
63
  }
63
64
  return [
@@ -70,7 +70,9 @@ describe( 'getNotificationArgumentsForSaveSuccess()', () => {
70
70
  'updated',
71
71
  {
72
72
  ...defaultExpectedAction,
73
- actions: [ { label: 'view', url: 'some_link' } ],
73
+ actions: [
74
+ { label: 'view', openInNewTab: true, url: 'some_link' },
75
+ ],
74
76
  },
75
77
  ],
76
78
  ],