@wordpress/block-editor 12.3.3 → 12.3.4

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 (52) hide show
  1. package/build/components/block-mobile-toolbar/block-actions-menu.native.js +3 -6
  2. package/build/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  3. package/build/components/block-removal-warning-modal/index.js +1 -1
  4. package/build/components/block-removal-warning-modal/index.js.map +1 -1
  5. package/build/components/global-styles/filters-panel.js +1 -1
  6. package/build/components/global-styles/filters-panel.js.map +1 -1
  7. package/build/components/inserter/block-patterns-explorer/patterns-list.js +2 -2
  8. package/build/components/inserter/block-patterns-explorer/patterns-list.js.map +1 -1
  9. package/build/components/inserter/block-patterns-tab.js +7 -35
  10. package/build/components/inserter/block-patterns-tab.js.map +1 -1
  11. package/build/components/inserter/hooks/use-block-types-state.js +3 -4
  12. package/build/components/inserter/hooks/use-block-types-state.js.map +1 -1
  13. package/build/components/inserter/hooks/use-patterns-state.js +9 -3
  14. package/build/components/inserter/hooks/use-patterns-state.js.map +1 -1
  15. package/build/components/inserter/reusable-blocks-tab.js +1 -1
  16. package/build/components/inserter/reusable-blocks-tab.js.map +1 -1
  17. package/build/store/selectors.js +31 -15
  18. package/build/store/selectors.js.map +1 -1
  19. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js +4 -6
  20. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  21. package/build-module/components/block-removal-warning-modal/index.js +2 -2
  22. package/build-module/components/block-removal-warning-modal/index.js.map +1 -1
  23. package/build-module/components/global-styles/filters-panel.js +2 -2
  24. package/build-module/components/global-styles/filters-panel.js.map +1 -1
  25. package/build-module/components/inserter/block-patterns-explorer/patterns-list.js +2 -2
  26. package/build-module/components/inserter/block-patterns-explorer/patterns-list.js.map +1 -1
  27. package/build-module/components/inserter/block-patterns-tab.js +7 -33
  28. package/build-module/components/inserter/block-patterns-tab.js.map +1 -1
  29. package/build-module/components/inserter/hooks/use-block-types-state.js +3 -4
  30. package/build-module/components/inserter/hooks/use-block-types-state.js.map +1 -1
  31. package/build-module/components/inserter/hooks/use-patterns-state.js +9 -3
  32. package/build-module/components/inserter/hooks/use-patterns-state.js.map +1 -1
  33. package/build-module/components/inserter/reusable-blocks-tab.js +1 -1
  34. package/build-module/components/inserter/reusable-blocks-tab.js.map +1 -1
  35. package/build-module/store/selectors.js +31 -15
  36. package/build-module/store/selectors.js.map +1 -1
  37. package/build-style/content-rtl.css +3 -0
  38. package/build-style/content.css +3 -0
  39. package/build-style/style-rtl.css +1 -2
  40. package/build-style/style.css +1 -2
  41. package/package.json +9 -9
  42. package/src/components/block-mobile-toolbar/block-actions-menu.native.js +4 -8
  43. package/src/components/block-removal-warning-modal/index.js +4 -6
  44. package/src/components/default-block-appender/content.scss +11 -0
  45. package/src/components/global-styles/filters-panel.js +2 -2
  46. package/src/components/inserter/block-patterns-explorer/patterns-list.js +8 -2
  47. package/src/components/inserter/block-patterns-tab.js +8 -56
  48. package/src/components/inserter/hooks/use-block-types-state.js +3 -4
  49. package/src/components/inserter/hooks/use-patterns-state.js +35 -19
  50. package/src/components/inserter/reusable-blocks-tab.js +1 -1
  51. package/src/components/list-view/style.scss +1 -2
  52. package/src/store/selectors.js +51 -20
@@ -707,6 +707,9 @@
707
707
  .block-editor-default-block-appender .block-editor-default-block-appender__content {
708
708
  opacity: 0.62;
709
709
  }
710
+ :where(body .is-layout-constrained) .block-editor-default-block-appender > :first-child:first-child {
711
+ margin-block-start: 0;
712
+ }
710
713
  .block-editor-default-block-appender .components-drop-zone__content-icon {
711
714
  display: none;
712
715
  }
@@ -707,6 +707,9 @@
707
707
  .block-editor-default-block-appender .block-editor-default-block-appender__content {
708
708
  opacity: 0.62;
709
709
  }
710
+ :where(body .is-layout-constrained) .block-editor-default-block-appender > :first-child:first-child {
711
+ margin-block-start: 0;
712
+ }
710
713
  .block-editor-default-block-appender .components-drop-zone__content-icon {
711
714
  display: none;
712
715
  }
@@ -2654,8 +2654,7 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
2654
2654
  }
2655
2655
  .block-editor-list-view-drop-indicator .block-editor-list-view-drop-indicator__line {
2656
2656
  background: var(--wp-admin-theme-color);
2657
- height: 6px;
2658
- border: 1px solid #fff;
2657
+ height: 4px;
2659
2658
  border-radius: 4px;
2660
2659
  }
2661
2660
 
@@ -2655,8 +2655,7 @@ body.is-fullscreen-mode .block-editor-block-contextual-toolbar.is-fixed {
2655
2655
  }
2656
2656
  .block-editor-list-view-drop-indicator .block-editor-list-view-drop-indicator__line {
2657
2657
  background: var(--wp-admin-theme-color);
2658
- height: 6px;
2659
- border: 1px solid #fff;
2658
+ height: 4px;
2660
2659
  border-radius: 4px;
2661
2660
  }
2662
2661
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "12.3.3",
3
+ "version": "12.3.4",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -37,10 +37,10 @@
37
37
  "@wordpress/a11y": "^3.35.1",
38
38
  "@wordpress/api-fetch": "^6.32.1",
39
39
  "@wordpress/blob": "^3.35.1",
40
- "@wordpress/blocks": "^12.12.1",
41
- "@wordpress/components": "^25.1.3",
40
+ "@wordpress/blocks": "^12.12.2",
41
+ "@wordpress/components": "^25.1.4",
42
42
  "@wordpress/compose": "^6.12.1",
43
- "@wordpress/data": "^9.5.1",
43
+ "@wordpress/data": "^9.5.2",
44
44
  "@wordpress/date": "^4.35.1",
45
45
  "@wordpress/deprecated": "^3.35.1",
46
46
  "@wordpress/dom": "^3.35.1",
@@ -51,12 +51,12 @@
51
51
  "@wordpress/i18n": "^4.35.1",
52
52
  "@wordpress/icons": "^9.26.2",
53
53
  "@wordpress/is-shallow-equal": "^4.35.1",
54
- "@wordpress/keyboard-shortcuts": "^4.12.1",
54
+ "@wordpress/keyboard-shortcuts": "^4.12.2",
55
55
  "@wordpress/keycodes": "^3.35.1",
56
- "@wordpress/notices": "^4.3.1",
57
- "@wordpress/preferences": "^3.12.3",
56
+ "@wordpress/notices": "^4.3.2",
57
+ "@wordpress/preferences": "^3.12.4",
58
58
  "@wordpress/private-apis": "^0.17.1",
59
- "@wordpress/rich-text": "^6.12.1",
59
+ "@wordpress/rich-text": "^6.12.2",
60
60
  "@wordpress/shortcode": "^3.35.1",
61
61
  "@wordpress/style-engine": "^1.18.1",
62
62
  "@wordpress/token-list": "^2.35.1",
@@ -85,5 +85,5 @@
85
85
  "publishConfig": {
86
86
  "access": "public"
87
87
  },
88
- "gitHead": "7efa7c2321a958ddfa723825a0354071435a9d43"
88
+ "gitHead": "65fb4cd5187a47ca274c24c04a220bcdb2ddfa67"
89
89
  }
@@ -213,16 +213,12 @@ const BlockActionsMenu = ( {
213
213
  id: 'convertToRegularBlocksOption',
214
214
  label:
215
215
  innerBlockCount > 1
216
- ? __( 'Convert to regular blocks' )
217
- : __( 'Convert to regular block' ),
216
+ ? __( 'Detach patterns' )
217
+ : __( 'Detach pattern' ),
218
218
  value: 'convertToRegularBlocksOption',
219
219
  onSelect: () => {
220
- const successNotice =
221
- innerBlockCount > 1
222
- ? /* translators: %s: name of the reusable block */
223
- __( '%s converted to regular blocks' )
224
- : /* translators: %s: name of the reusable block */
225
- __( '%s converted to regular block' );
220
+ /* translators: %s: name of the synced block */
221
+ const successNotice = __( '%s detached' );
226
222
  createSuccessNotice(
227
223
  sprintf(
228
224
  successNotice,
@@ -8,7 +8,7 @@ import {
8
8
  Button,
9
9
  __experimentalHStack as HStack,
10
10
  } from '@wordpress/components';
11
- import { __, _n } from '@wordpress/i18n';
11
+ import { __ } from '@wordpress/i18n';
12
12
 
13
13
  /**
14
14
  * Internal dependencies
@@ -75,11 +75,9 @@ export function BlockRemovalWarningModal() {
75
75
  </ul>
76
76
  ) }
77
77
  <p>
78
- { _n(
79
- 'Removing this block is not advised.',
80
- 'Removing these blocks is not advised.',
81
- blockNamesForPrompt.length
82
- ) }
78
+ { blockNamesForPrompt.length > 1
79
+ ? __( 'Removing these blocks is not advised.' )
80
+ : __( 'Removing this block is not advised.' ) }
83
81
  </p>
84
82
  <HStack justify="right">
85
83
  <Button variant="tertiary" onClick={ clearRemovalPrompt }>
@@ -26,6 +26,17 @@
26
26
  opacity: 0.62;
27
27
  }
28
28
 
29
+ // In "constrained" layout containers, the first and last paragraphs have their margins zeroed out.
30
+ // In the case of this appender, it needs to apply those same rules to avoid layout shifts.
31
+ // Such shifts happen when the bottom margin of the Title block has been set to less than the default 1em margin of paragraphs.
32
+ :where(body .is-layout-constrained) & {
33
+ > :first-child:first-child {
34
+ margin-block-start: 0;
35
+ }
36
+
37
+ // Since this particular appender will only ever appear on an entirely empty document, we don't account for last-child.
38
+ }
39
+
29
40
  // Dropzone.
30
41
  .components-drop-zone__content-icon {
31
42
  display: none;
@@ -22,7 +22,7 @@ import {
22
22
  Flex,
23
23
  FlexItem,
24
24
  } from '@wordpress/components';
25
- import { __ } from '@wordpress/i18n';
25
+ import { __, _x } from '@wordpress/i18n';
26
26
  import { useCallback, useMemo } from '@wordpress/element';
27
27
 
28
28
  /**
@@ -77,7 +77,7 @@ function FiltersToolsPanel( {
77
77
 
78
78
  return (
79
79
  <ToolsPanel
80
- label={ __( 'Filters' ) }
80
+ label={ _x( 'Filters', 'Name for applying graphical effects' ) }
81
81
  resetAll={ resetAll }
82
82
  panelId={ panelId }
83
83
  >
@@ -52,6 +52,7 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) {
52
52
  onInsertBlocks,
53
53
  destinationRootClientId
54
54
  );
55
+
55
56
  const registeredPatternCategories = useMemo(
56
57
  () =>
57
58
  patternCategories.map(
@@ -75,7 +76,12 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) {
75
76
  );
76
77
  }
77
78
  return searchItems( allPatterns, filterValue );
78
- }, [ filterValue, selectedCategory, allPatterns ] );
79
+ }, [
80
+ filterValue,
81
+ allPatterns,
82
+ selectedCategory,
83
+ registeredPatternCategories,
84
+ ] );
79
85
 
80
86
  // Announce search results on change.
81
87
  useEffect( () => {
@@ -89,7 +95,7 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) {
89
95
  count
90
96
  );
91
97
  debouncedSpeak( resultsFoundMessage );
92
- }, [ filterValue, debouncedSpeak ] );
98
+ }, [ filterValue, debouncedSpeak, filteredBlockPatterns.length ] );
93
99
 
94
100
  const currentShownPatterns = useAsyncList( filteredBlockPatterns, {
95
101
  step: INITIAL_INSERTER_RESULTS,
@@ -18,7 +18,6 @@ import {
18
18
  Button,
19
19
  } from '@wordpress/components';
20
20
  import { Icon, chevronRight, chevronLeft } from '@wordpress/icons';
21
- import { parse } from '@wordpress/blocks';
22
21
  import { focus } from '@wordpress/dom';
23
22
 
24
23
  /**
@@ -28,13 +27,13 @@ import usePatternsState from './hooks/use-patterns-state';
28
27
  import BlockPatternList from '../block-patterns-list';
29
28
  import PatternsExplorerModal from './block-patterns-explorer/explorer';
30
29
  import MobileTabNavigation from './mobile-tab-navigation';
31
- import useBlockTypesState from './hooks/use-block-types-state';
32
30
 
33
31
  const noop = () => {};
34
32
 
35
33
  // Preferred order of pattern categories. Any other categories should
36
34
  // be at the bottom without any re-ordering.
37
35
  const patternCategoriesOrder = [
36
+ 'custom',
38
37
  'featured',
39
38
  'posts',
40
39
  'text',
@@ -51,18 +50,6 @@ function usePatternsCategories( rootClientId ) {
51
50
  rootClientId
52
51
  );
53
52
 
54
- const [ unsyncedPatterns ] = useBlockTypesState(
55
- rootClientId,
56
- undefined,
57
- 'unsynced'
58
- );
59
-
60
- const filteredUnsyncedPatterns = useMemo( () => {
61
- return unsyncedPatterns.filter(
62
- ( { category: unsyncedPatternCategory } ) =>
63
- unsyncedPatternCategory === 'reusable'
64
- );
65
- }, [ unsyncedPatterns ] );
66
53
  const hasRegisteredCategory = useCallback(
67
54
  ( pattern ) => {
68
55
  if ( ! pattern.categories || ! pattern.categories.length ) {
@@ -107,20 +94,9 @@ function usePatternsCategories( rootClientId ) {
107
94
  label: _x( 'Uncategorized' ),
108
95
  } );
109
96
  }
110
- if ( filteredUnsyncedPatterns.length > 0 ) {
111
- categories.push( {
112
- name: 'reusable',
113
- label: _x( 'Custom patterns' ),
114
- } );
115
- }
116
97
 
117
98
  return categories;
118
- }, [
119
- allCategories,
120
- allPatterns,
121
- filteredUnsyncedPatterns.length,
122
- hasRegisteredCategory,
123
- ] );
99
+ }, [ allCategories, allPatterns, hasRegisteredCategory ] );
124
100
 
125
101
  return populatedCategories;
126
102
  }
@@ -169,24 +145,6 @@ export function BlockPatternsCategoryPanel( {
169
145
  onInsert,
170
146
  rootClientId
171
147
  );
172
- const [ unsyncedPatterns ] = useBlockTypesState(
173
- rootClientId,
174
- onInsert,
175
- 'unsynced'
176
- );
177
- const filteredUnsyncedPatterns = useMemo( () => {
178
- return unsyncedPatterns
179
- .filter(
180
- ( { category: unsyncedPatternCategory } ) =>
181
- unsyncedPatternCategory === 'reusable'
182
- )
183
- .map( ( syncedPattern ) => ( {
184
- ...syncedPattern,
185
- blocks: parse( syncedPattern.content, {
186
- __unstableSkipMigrationLogs: true,
187
- } ),
188
- } ) );
189
- }, [ unsyncedPatterns ] );
190
148
 
191
149
  const availableCategories = usePatternsCategories( rootClientId );
192
150
  const currentCategoryPatterns = useMemo(
@@ -208,21 +166,15 @@ export function BlockPatternsCategoryPanel( {
208
166
 
209
167
  return availablePatternCategories.length === 0;
210
168
  } ),
211
- [ allPatterns, category ]
169
+ [ allPatterns, availableCategories, category.name ]
212
170
  );
213
- const patterns =
214
- category.name === 'reusable'
215
- ? filteredUnsyncedPatterns
216
- : currentCategoryPatterns;
217
- const currentShownPatterns = useAsyncList( patterns );
171
+
172
+ const categoryPatternsList = useAsyncList( currentCategoryPatterns );
218
173
 
219
174
  // Hide block pattern preview on unmount.
220
175
  useEffect( () => () => onHover( null ), [] );
221
176
 
222
- if (
223
- ! currentCategoryPatterns.length &&
224
- ! filteredUnsyncedPatterns.length
225
- ) {
177
+ if ( ! currentCategoryPatterns.length ) {
226
178
  return null;
227
179
  }
228
180
 
@@ -233,8 +185,8 @@ export function BlockPatternsCategoryPanel( {
233
185
  </div>
234
186
  <p>{ category.description }</p>
235
187
  <BlockPatternList
236
- shownPatterns={ currentShownPatterns }
237
- blockPatterns={ patterns }
188
+ shownPatterns={ categoryPatternsList }
189
+ blockPatterns={ currentCategoryPatterns }
238
190
  onClickPattern={ onClick }
239
191
  onHover={ onHover }
240
192
  label={ category.label }
@@ -19,10 +19,9 @@ import { store as blockEditorStore } from '../../../store';
19
19
  *
20
20
  * @param {string=} rootClientId Insertion's root client ID.
21
21
  * @param {Function} onInsert function called when inserter a list of blocks.
22
- * @param {?string} syncStatus Optional sync status to filter pattern blocks by.
23
22
  * @return {Array} Returns the block types state. (block types, categories, collections, onSelect handler)
24
23
  */
25
- const useBlockTypesState = ( rootClientId, onInsert, syncStatus ) => {
24
+ const useBlockTypesState = ( rootClientId, onInsert ) => {
26
25
  const { categories, collections, items } = useSelect(
27
26
  ( select ) => {
28
27
  const { getInserterItems } = select( blockEditorStore );
@@ -31,10 +30,10 @@ const useBlockTypesState = ( rootClientId, onInsert, syncStatus ) => {
31
30
  return {
32
31
  categories: getCategories(),
33
32
  collections: getCollections(),
34
- items: getInserterItems( rootClientId, syncStatus ),
33
+ items: getInserterItems( rootClientId ),
35
34
  };
36
35
  },
37
- [ rootClientId, syncStatus ]
36
+ [ rootClientId ]
38
37
  );
39
38
 
40
39
  const onSelectItem = useCallback(
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useCallback } from '@wordpress/element';
4
+ import { useCallback, useMemo } from '@wordpress/element';
5
5
  import { cloneBlock } from '@wordpress/blocks';
6
6
  import { useDispatch, useSelect } from '@wordpress/data';
7
7
  import { __, sprintf } from '@wordpress/i18n';
@@ -12,6 +12,12 @@ import { store as noticesStore } from '@wordpress/notices';
12
12
  */
13
13
  import { store as blockEditorStore } from '../../../store';
14
14
 
15
+ const CUSTOM_CATEGORY = {
16
+ name: 'custom',
17
+ label: __( 'My patterns' ),
18
+ description: __( 'Custom patterns add by site users' ),
19
+ };
20
+
15
21
  /**
16
22
  * Retrieves the block patterns inserter state.
17
23
  *
@@ -25,6 +31,7 @@ const usePatternsState = ( onInsert, rootClientId ) => {
25
31
  ( select ) => {
26
32
  const { __experimentalGetAllowedPatterns, getSettings } =
27
33
  select( blockEditorStore );
34
+
28
35
  return {
29
36
  patterns: __experimentalGetAllowedPatterns( rootClientId ),
30
37
  patternCategories:
@@ -33,25 +40,34 @@ const usePatternsState = ( onInsert, rootClientId ) => {
33
40
  },
34
41
  [ rootClientId ]
35
42
  );
43
+
44
+ const allCategories = useMemo(
45
+ () => [ ...patternCategories, CUSTOM_CATEGORY ],
46
+ [ patternCategories ]
47
+ );
48
+
36
49
  const { createSuccessNotice } = useDispatch( noticesStore );
37
- const onClickPattern = useCallback( ( pattern, blocks ) => {
38
- onInsert(
39
- ( blocks ?? [] ).map( ( block ) => cloneBlock( block ) ),
40
- pattern.name
41
- );
42
- createSuccessNotice(
43
- sprintf(
44
- /* translators: %s: block pattern title. */
45
- __( 'Block pattern "%s" inserted.' ),
46
- pattern.title
47
- ),
48
- {
49
- type: 'snackbar',
50
- }
51
- );
52
- }, [] );
53
-
54
- return [ patterns, patternCategories, onClickPattern ];
50
+ const onClickPattern = useCallback(
51
+ ( pattern, blocks ) => {
52
+ onInsert(
53
+ ( blocks ?? [] ).map( ( block ) => cloneBlock( block ) ),
54
+ pattern.name
55
+ );
56
+ createSuccessNotice(
57
+ sprintf(
58
+ /* translators: %s: block pattern title. */
59
+ __( 'Block pattern "%s" inserted.' ),
60
+ pattern.title
61
+ ),
62
+ {
63
+ type: 'snackbar',
64
+ }
65
+ );
66
+ },
67
+ [ createSuccessNotice, onInsert ]
68
+ );
69
+
70
+ return [ patterns, allCategories, onClickPattern ];
55
71
  };
56
72
 
57
73
  export default usePatternsState;
@@ -67,7 +67,7 @@ export function ReusableBlocksTab( { rootClientId, onInsert, onHover } ) {
67
67
  post_type: 'wp_block',
68
68
  } ) }
69
69
  >
70
- { __( 'Manage custom patterns' ) }
70
+ { __( 'Manage my patterns' ) }
71
71
  </Button>
72
72
  </div>
73
73
  </>
@@ -408,8 +408,7 @@ $block-navigation-max-indent: 8;
408
408
 
409
409
  .block-editor-list-view-drop-indicator__line {
410
410
  background: var(--wp-admin-theme-color);
411
- height: 6px;
412
- border: 1px solid $white;
411
+ height: 4px;
413
412
  border-radius: 4px;
414
413
  }
415
414
  }
@@ -1945,7 +1945,6 @@ const buildBlockTypeItem =
1945
1945
  *
1946
1946
  * @param {Object} state Editor state.
1947
1947
  * @param {?string} rootClientId Optional root client ID of block list.
1948
- * @param {?string} syncStatus Optional sync status to filter pattern blocks by.
1949
1948
  *
1950
1949
  * @return {WPEditorInserterItem[]} Items that appear in inserter.
1951
1950
  *
@@ -1962,11 +1961,7 @@ const buildBlockTypeItem =
1962
1961
  * @property {number} frecency Heuristic that combines frequency and recency.
1963
1962
  */
1964
1963
  export const getInserterItems = createSelector(
1965
- ( state, rootClientId = null, syncStatus ) => {
1966
- const buildBlockTypeInserterItem = buildBlockTypeItem( state, {
1967
- buildScope: 'inserter',
1968
- } );
1969
-
1964
+ ( state, rootClientId = null ) => {
1970
1965
  /*
1971
1966
  * Matches block comment delimiters amid serialized content.
1972
1967
  *
@@ -2031,13 +2026,7 @@ export const getInserterItems = createSelector(
2031
2026
  };
2032
2027
  };
2033
2028
 
2034
- const blockTypeInserterItems = getBlockTypes()
2035
- .filter( ( blockType ) =>
2036
- canIncludeBlockTypeInInserter( state, blockType, rootClientId )
2037
- )
2038
- .map( buildBlockTypeInserterItem );
2039
-
2040
- const reusableBlockInserterItems = canInsertBlockTypeUnmemoized(
2029
+ const syncedPatternInserterItems = canInsertBlockTypeUnmemoized(
2041
2030
  state,
2042
2031
  'core/block',
2043
2032
  rootClientId
@@ -2045,13 +2034,25 @@ export const getInserterItems = createSelector(
2045
2034
  ? getReusableBlocks( state )
2046
2035
  .filter(
2047
2036
  ( reusableBlock ) =>
2048
- syncStatus === reusableBlock.meta?.sync_status ||
2049
- ( ! syncStatus &&
2050
- reusableBlock.meta?.sync_status === '' )
2037
+ // Filter to either fully synced patterns (sync_status === 'fully'),
2038
+ // or old school reusable blocks (sync_status === '').
2039
+ reusableBlock.meta?.sync_status === 'fully' ||
2040
+ reusableBlock.meta?.sync_status === '' ||
2041
+ ! reusableBlock.meta?.sync_status
2051
2042
  )
2052
2043
  .map( buildReusableBlockInserterItem )
2053
2044
  : [];
2054
2045
 
2046
+ const buildBlockTypeInserterItem = buildBlockTypeItem( state, {
2047
+ buildScope: 'inserter',
2048
+ } );
2049
+
2050
+ const blockTypeInserterItems = getBlockTypes()
2051
+ .filter( ( blockType ) =>
2052
+ canIncludeBlockTypeInInserter( state, blockType, rootClientId )
2053
+ )
2054
+ .map( buildBlockTypeInserterItem );
2055
+
2055
2056
  const items = blockTypeInserterItems.reduce( ( accumulator, item ) => {
2056
2057
  const { variations = [] } = item;
2057
2058
  // Exclude any block type item that is to be replaced by a default variation.
@@ -2082,7 +2083,7 @@ export const getInserterItems = createSelector(
2082
2083
  { core: [], noncore: [] }
2083
2084
  );
2084
2085
  const sortedBlockTypes = [ ...coreItems, ...nonCoreItems ];
2085
- return [ ...sortedBlockTypes, ...reusableBlockInserterItems ];
2086
+ return [ ...sortedBlockTypes, ...syncedPatternInserterItems ];
2086
2087
  },
2087
2088
  ( state, rootClientId ) => [
2088
2089
  state.blockListSettings[ rootClientId ],
@@ -2306,10 +2307,32 @@ const checkAllowListRecursive = ( blocks, allowedBlockTypes ) => {
2306
2307
  return true;
2307
2308
  };
2308
2309
 
2310
+ function getUnsyncedPatterns( state ) {
2311
+ const reusableBlocks =
2312
+ state?.settings?.__experimentalReusableBlocks ?? EMPTY_ARRAY;
2313
+
2314
+ return reusableBlocks
2315
+ .filter(
2316
+ ( reusableBlock ) => reusableBlock.meta?.sync_status === 'unsynced'
2317
+ )
2318
+ .map( ( reusableBlock ) => {
2319
+ return {
2320
+ name: `core/block/${ reusableBlock.id }`,
2321
+ title: reusableBlock.title.raw,
2322
+ categories: [ 'custom' ],
2323
+ content: reusableBlock.content.raw,
2324
+ };
2325
+ } );
2326
+ }
2327
+
2309
2328
  export const __experimentalGetParsedPattern = createSelector(
2310
2329
  ( state, patternName ) => {
2311
2330
  const patterns = state.settings.__experimentalBlockPatterns;
2312
- const pattern = patterns.find( ( { name } ) => name === patternName );
2331
+ const unsyncedPatterns = getUnsyncedPatterns( state );
2332
+
2333
+ const pattern = [ ...patterns, ...unsyncedPatterns ].find(
2334
+ ( { name } ) => name === patternName
2335
+ );
2313
2336
  if ( ! pattern ) {
2314
2337
  return null;
2315
2338
  }
@@ -2320,14 +2343,20 @@ export const __experimentalGetParsedPattern = createSelector(
2320
2343
  } ),
2321
2344
  };
2322
2345
  },
2323
- ( state ) => [ state.settings.__experimentalBlockPatterns ]
2346
+ ( state ) => [
2347
+ state.settings.__experimentalBlockPatterns,
2348
+ state.settings.__experimentalReusableBlocks,
2349
+ ]
2324
2350
  );
2325
2351
 
2326
2352
  const getAllAllowedPatterns = createSelector(
2327
2353
  ( state ) => {
2328
2354
  const patterns = state.settings.__experimentalBlockPatterns;
2355
+ const unsyncedPatterns = getUnsyncedPatterns( state );
2356
+
2329
2357
  const { allowedBlockTypes } = getSettings( state );
2330
- const parsedPatterns = patterns
2358
+
2359
+ const parsedPatterns = [ ...patterns, ...unsyncedPatterns ]
2331
2360
  .filter( ( { inserter = true } ) => !! inserter )
2332
2361
  .map( ( { name } ) =>
2333
2362
  __experimentalGetParsedPattern( state, name )
@@ -2339,6 +2368,7 @@ const getAllAllowedPatterns = createSelector(
2339
2368
  },
2340
2369
  ( state ) => [
2341
2370
  state.settings.__experimentalBlockPatterns,
2371
+ state.settings.__experimentalReusableBlocks,
2342
2372
  state.settings.allowedBlockTypes,
2343
2373
  ]
2344
2374
  );
@@ -2365,6 +2395,7 @@ export const __experimentalGetAllowedPatterns = createSelector(
2365
2395
  },
2366
2396
  ( state, rootClientId ) => [
2367
2397
  state.settings.__experimentalBlockPatterns,
2398
+ state.settings.__experimentalReusableBlocks,
2368
2399
  state.settings.allowedBlockTypes,
2369
2400
  state.settings.templateLock,
2370
2401
  state.blockListSettings[ rootClientId ],