@wordpress/block-editor 12.3.3 → 12.3.5

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 (92) hide show
  1. package/README.md +4 -0
  2. package/build/components/block-edit/edit.js +25 -13
  3. package/build/components/block-edit/edit.js.map +1 -1
  4. package/build/components/block-mobile-toolbar/block-actions-menu.native.js +3 -6
  5. package/build/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  6. package/build/components/block-parent-selector/index.js +8 -5
  7. package/build/components/block-parent-selector/index.js.map +1 -1
  8. package/build/components/block-removal-warning-modal/index.js +5 -2
  9. package/build/components/block-removal-warning-modal/index.js.map +1 -1
  10. package/build/components/block-tools/block-contextual-toolbar.js +7 -11
  11. package/build/components/block-tools/block-contextual-toolbar.js.map +1 -1
  12. package/build/components/global-styles/filters-panel.js +1 -1
  13. package/build/components/global-styles/filters-panel.js.map +1 -1
  14. package/build/components/index.js +10 -1
  15. package/build/components/index.js.map +1 -1
  16. package/build/components/inserter/block-patterns-explorer/patterns-list.js +2 -2
  17. package/build/components/inserter/block-patterns-explorer/patterns-list.js.map +1 -1
  18. package/build/components/inserter/block-patterns-tab.js +7 -35
  19. package/build/components/inserter/block-patterns-tab.js.map +1 -1
  20. package/build/components/inserter/hooks/use-block-types-state.js +3 -4
  21. package/build/components/inserter/hooks/use-block-types-state.js.map +1 -1
  22. package/build/components/inserter/hooks/use-patterns-state.js +9 -3
  23. package/build/components/inserter/hooks/use-patterns-state.js.map +1 -1
  24. package/build/components/inserter/reusable-block-rename-hint.js +62 -0
  25. package/build/components/inserter/reusable-block-rename-hint.js.map +1 -0
  26. package/build/components/inserter/reusable-blocks-tab.js +6 -2
  27. package/build/components/inserter/reusable-blocks-tab.js.map +1 -1
  28. package/build/components/list-view/use-list-view-client-ids.js +2 -2
  29. package/build/components/list-view/use-list-view-client-ids.js.map +1 -1
  30. package/build/store/private-selectors.js +5 -6
  31. package/build/store/private-selectors.js.map +1 -1
  32. package/build/store/selectors.js +33 -15
  33. package/build/store/selectors.js.map +1 -1
  34. package/build-module/components/block-edit/edit.js +27 -10
  35. package/build-module/components/block-edit/edit.js.map +1 -1
  36. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js +4 -6
  37. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  38. package/build-module/components/block-parent-selector/index.js +7 -5
  39. package/build-module/components/block-parent-selector/index.js.map +1 -1
  40. package/build-module/components/block-removal-warning-modal/index.js +6 -3
  41. package/build-module/components/block-removal-warning-modal/index.js.map +1 -1
  42. package/build-module/components/block-tools/block-contextual-toolbar.js +8 -11
  43. package/build-module/components/block-tools/block-contextual-toolbar.js.map +1 -1
  44. package/build-module/components/global-styles/filters-panel.js +2 -2
  45. package/build-module/components/global-styles/filters-panel.js.map +1 -1
  46. package/build-module/components/index.js +5 -0
  47. package/build-module/components/index.js.map +1 -1
  48. package/build-module/components/inserter/block-patterns-explorer/patterns-list.js +2 -2
  49. package/build-module/components/inserter/block-patterns-explorer/patterns-list.js.map +1 -1
  50. package/build-module/components/inserter/block-patterns-tab.js +7 -33
  51. package/build-module/components/inserter/block-patterns-tab.js.map +1 -1
  52. package/build-module/components/inserter/hooks/use-block-types-state.js +3 -4
  53. package/build-module/components/inserter/hooks/use-block-types-state.js.map +1 -1
  54. package/build-module/components/inserter/hooks/use-patterns-state.js +9 -3
  55. package/build-module/components/inserter/hooks/use-patterns-state.js.map +1 -1
  56. package/build-module/components/inserter/reusable-block-rename-hint.js +48 -0
  57. package/build-module/components/inserter/reusable-block-rename-hint.js.map +1 -0
  58. package/build-module/components/inserter/reusable-blocks-tab.js +5 -2
  59. package/build-module/components/inserter/reusable-blocks-tab.js.map +1 -1
  60. package/build-module/components/list-view/use-list-view-client-ids.js +2 -2
  61. package/build-module/components/list-view/use-list-view-client-ids.js.map +1 -1
  62. package/build-module/store/private-selectors.js +3 -3
  63. package/build-module/store/private-selectors.js.map +1 -1
  64. package/build-module/store/selectors.js +33 -15
  65. package/build-module/store/selectors.js.map +1 -1
  66. package/build-style/content-rtl.css +3 -0
  67. package/build-style/content.css +3 -0
  68. package/build-style/style-rtl.css +72 -22
  69. package/build-style/style.css +72 -22
  70. package/package.json +9 -9
  71. package/src/components/block-edit/edit.js +26 -9
  72. package/src/components/block-edit/test/edit.js +1 -1
  73. package/src/components/block-mobile-toolbar/block-actions-menu.native.js +4 -8
  74. package/src/components/block-parent-selector/index.js +13 -8
  75. package/src/components/block-removal-warning-modal/index.js +7 -6
  76. package/src/components/block-tools/block-contextual-toolbar.js +5 -11
  77. package/src/components/block-tools/style.scss +69 -26
  78. package/src/components/default-block-appender/content.scss +11 -0
  79. package/src/components/global-styles/filters-panel.js +2 -2
  80. package/src/components/index.js +5 -0
  81. package/src/components/inserter/block-patterns-explorer/patterns-list.js +8 -2
  82. package/src/components/inserter/block-patterns-tab.js +8 -56
  83. package/src/components/inserter/hooks/use-block-types-state.js +3 -4
  84. package/src/components/inserter/hooks/use-patterns-state.js +35 -19
  85. package/src/components/inserter/reusable-block-rename-hint.js +52 -0
  86. package/src/components/inserter/reusable-blocks-tab.js +5 -1
  87. package/src/components/inserter/style.scss +28 -0
  88. package/src/components/list-view/style.scss +1 -2
  89. package/src/components/list-view/use-list-view-client-ids.js +2 -2
  90. package/src/store/private-selectors.js +3 -6
  91. package/src/store/selectors.js +54 -20
  92. package/src/store/test/private-selectors.js +5 -5
@@ -131,11 +131,11 @@
131
131
  @include break-medium() {
132
132
  &.is-fixed {
133
133
 
134
- // leave room for block inserter
135
- margin-left: $grid-unit-80;
134
+ // leave room for block inserter, undo and redo, list view
135
+ margin-left: $grid-unit-80 * 3 - 2 * $grid-unit + $grid-unit-05;
136
136
  // position on top of interface header
137
137
  position: fixed;
138
- top: $admin-bar-height + $grid-unit;
138
+ top: $admin-bar-height + $grid-unit - $border-width;
139
139
  // Don't fill up when empty
140
140
  min-height: initial;
141
141
  // remove the border
@@ -145,32 +145,63 @@
145
145
 
146
146
  &.is-collapsed {
147
147
  width: initial;
148
- margin-left: $grid-unit-80 * 3 + $grid-unit-30;
149
148
  }
150
149
 
151
150
  .is-fullscreen-mode & {
152
- // leave room for block inserter
153
- margin-left: $grid-unit-80 + $grid-unit-70;
154
- top: $grid-unit;
151
+ // leave room for block inserter, undo and redo, list view
152
+ // and some margin left
153
+ margin-left: $grid-unit-80 * 4 - 2 * $grid-unit;
154
+ top: $grid-unit - $border-width;
155
155
  &.is-collapsed {
156
156
  width: initial;
157
- margin-left: $grid-unit-80 * 4 + $grid-unit-30;
157
+ }
158
+ }
159
+
160
+ & > .block-editor-block-toolbar.is-showing-movers {
161
+ flex-grow: initial;
162
+ width: initial;
163
+
164
+ // Add a border as separator in the block toolbar.
165
+ &::before {
166
+ content: "";
167
+ width: $border-width;
168
+ height: 3 * $grid-unit;
169
+ margin-top: $grid-unit + $grid-unit-05;
170
+ margin-right: 0;
171
+ background-color: $gray-300;
172
+ position: relative;
173
+ left: math.div(-$grid-unit-05, 2);
174
+ top: -1px;
158
175
  }
159
176
  }
160
177
 
161
178
  & > .block-editor-block-toolbar__group-collapse-fixed-toolbar {
162
179
  border: none;
163
180
 
181
+ .show-icon-labels & {
182
+ .components-button.has-icon {
183
+ // Hide the button icons when labels are set to display...
184
+ svg {
185
+ display: none;
186
+ }
187
+ // ... and display labels.
188
+ &::after {
189
+ content: attr(aria-label);
190
+ font-size: $helptext-font-size;
191
+ }
192
+ }
193
+ }
194
+
164
195
  // Add a border as separator in the block toolbar.
165
- &::after {
196
+ &::before {
166
197
  content: "";
167
198
  width: $border-width;
168
- height: 24px;
199
+ height: 3 * $grid-unit;
169
200
  margin-top: $grid-unit + $grid-unit-05;
170
- margin-bottom: $grid-unit + $grid-unit-05;
201
+ margin-right: $grid-unit-10;
171
202
  background-color: $gray-300;
172
- position: absolute;
173
- left: 44px;
203
+ position: relative;
204
+ left: 0;
174
205
  top: -1px;
175
206
  }
176
207
  }
@@ -178,6 +209,21 @@
178
209
  & > .block-editor-block-toolbar__group-expand-fixed-toolbar {
179
210
  border: none;
180
211
 
212
+ .show-icon-labels & {
213
+ width: $grid-unit-80 * 4;
214
+ .components-button.has-icon {
215
+ // Hide the button icons when labels are set to display...
216
+ svg {
217
+ display: none;
218
+ }
219
+ // ... and display labels.
220
+ &::after {
221
+ content: attr(aria-label);
222
+ font-size: $helptext-font-size;
223
+ }
224
+ }
225
+ }
226
+
181
227
  // Add a border as separator in the block toolbar.
182
228
  &::before {
183
229
  content: "";
@@ -186,27 +232,20 @@
186
232
  margin-bottom: $grid-unit + $grid-unit-05;
187
233
  background-color: $gray-300;
188
234
  position: relative;
189
- left: -12px; //the padding of buttons
190
- height: 24px;
235
+ left: -8px;
236
+ height: 3 * $grid-unit;
237
+ top: -1px;
191
238
  }
192
239
  }
193
240
 
194
241
  .show-icon-labels & {
195
242
 
196
- margin-left: $grid-unit-80;
197
-
198
- &.is-collapsed {
199
- margin-left: $grid-unit-80 * 6;
200
- }
243
+ margin-left: $grid-unit-80 + 2 * $grid-unit; // inserter and margin ;
201
244
 
202
245
  .is-fullscreen-mode & {
203
- margin-left: $grid-unit-80 + $grid-unit-80;
204
- &.is-collapsed {
205
- margin-left: $grid-unit-80 * 7;
206
- }
246
+ margin-left: $grid-unit * 18; // site hub, inserter and margin
207
247
  }
208
248
 
209
-
210
249
  .block-editor-block-parent-selector .block-editor-block-parent-selector__button::after {
211
250
  left: 0;
212
251
  }
@@ -234,12 +273,14 @@
234
273
  }
235
274
 
236
275
  &.is-fixed .block-editor-block-parent-selector {
276
+
237
277
  .block-editor-block-parent-selector__button {
238
278
  position: relative;
239
279
  top: -1px;
240
280
  border: 0;
241
281
  padding-right: 6px;
242
282
  padding-left: 6px;
283
+
243
284
  &::after {
244
285
  content: "\00B7";
245
286
  font-size: 16px;
@@ -281,7 +322,9 @@
281
322
  // for the block inserter the publish button
282
323
  @include break-large() {
283
324
  &.is-fixed {
284
- width: initial;
325
+ // the combined with of the tools at the right of the header and the margin left
326
+ // of the toolbar which includes four buttons
327
+ width: calc(100% - 240px - #{4 * $grid-unit-80});
285
328
  }
286
329
  }
287
330
 
@@ -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
  >
@@ -164,3 +164,8 @@ export { default as __experimentalInspectorPopoverHeader } from './inspector-pop
164
164
 
165
165
  export { default as BlockEditorProvider } from './provider';
166
166
  export { default as useSetting } from './use-setting';
167
+
168
+ /*
169
+ * The following rename hint component can be removed in 6.4.
170
+ */
171
+ export { default as ReusableBlocksRenameHint } from './inserter/reusable-block-rename-hint';
@@ -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;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { Button } from '@wordpress/components';
5
+ import { useDispatch, useSelect } from '@wordpress/data';
6
+ import { focus } from '@wordpress/dom';
7
+ import { useRef } from '@wordpress/element';
8
+ import { __ } from '@wordpress/i18n';
9
+ import { close } from '@wordpress/icons';
10
+ import { store as preferencesStore } from '@wordpress/preferences';
11
+
12
+ const PREFERENCE_NAME = 'isResuableBlocksrRenameHintVisible';
13
+
14
+ export default function ReusableBlocksRenameHint() {
15
+ const isReusableBlocksRenameHint = useSelect(
16
+ ( select ) =>
17
+ select( preferencesStore ).get( 'core', PREFERENCE_NAME ) ?? true,
18
+ []
19
+ );
20
+
21
+ const ref = useRef();
22
+
23
+ const { set: setPreference } = useDispatch( preferencesStore );
24
+ if ( ! isReusableBlocksRenameHint ) {
25
+ return null;
26
+ }
27
+
28
+ return (
29
+ <div ref={ ref } className="reusable-blocks-menu-items__rename-hint">
30
+ <div className="reusable-blocks-menu-items__rename-hint-content">
31
+ { __(
32
+ 'Reusable blocks are now called patterns. A synced pattern will behave in exactly the same way as a reusable block.'
33
+ ) }
34
+ </div>
35
+ <Button
36
+ className="reusable-blocks-menu-items__rename-hint-dismiss"
37
+ icon={ close }
38
+ iconSize="16"
39
+ label={ __( 'Dismiss hint' ) }
40
+ onClick={ () => {
41
+ // Retain focus when dismissing the element.
42
+ const previousElement = focus.tabbable.findPrevious(
43
+ ref.current
44
+ );
45
+ previousElement?.focus();
46
+ setPreference( 'core', PREFERENCE_NAME, false );
47
+ } }
48
+ showTooltip={ false }
49
+ />
50
+ </div>
51
+ );
52
+ }
@@ -13,6 +13,7 @@ import BlockTypesList from '../block-types-list';
13
13
  import InserterPanel from './panel';
14
14
  import InserterNoResults from './no-results';
15
15
  import useBlockTypesState from './hooks/use-block-types-state';
16
+ import ReusableBlocksRenameHint from './reusable-block-rename-hint';
16
17
 
17
18
  function ReusableBlocksList( { onHover, onInsert, rootClientId } ) {
18
19
  const [ items, , , onSelectItem ] = useBlockTypesState(
@@ -54,6 +55,9 @@ function ReusableBlocksList( { onHover, onInsert, rootClientId } ) {
54
55
  export function ReusableBlocksTab( { rootClientId, onInsert, onHover } ) {
55
56
  return (
56
57
  <>
58
+ <div className="block-editor-inserter__hint">
59
+ <ReusableBlocksRenameHint />
60
+ </div>
57
61
  <ReusableBlocksList
58
62
  onHover={ onHover }
59
63
  onInsert={ onInsert }
@@ -67,7 +71,7 @@ export function ReusableBlocksTab( { rootClientId, onInsert, onHover } ) {
67
71
  post_type: 'wp_block',
68
72
  } ) }
69
73
  >
70
- { __( 'Manage custom patterns' ) }
74
+ { __( 'Manage my patterns' ) }
71
75
  </Button>
72
76
  </div>
73
77
  </>
@@ -711,3 +711,31 @@ $block-inserter-tabs-height: 44px;
711
711
  margin: 0;
712
712
  }
713
713
  }
714
+
715
+ .block-editor-inserter__hint {
716
+ margin: $grid-unit-20 $grid-unit-20 0;
717
+ }
718
+
719
+ .reusable-blocks-menu-items__rename-hint {
720
+ align-items: top;
721
+ background: $gray-100;
722
+ border-radius: $radius-block-ui;
723
+ color: $gray-900;
724
+ display: flex;
725
+ flex-direction: row;
726
+ max-width: 380px;
727
+ }
728
+
729
+ .reusable-blocks-menu-items__rename-hint-content {
730
+ margin: $grid-unit-15 0 $grid-unit-15 $grid-unit-15;
731
+ }
732
+
733
+ .reusable-blocks-menu-items__rename-hint-dismiss {
734
+ // The dismiss button has a lot of empty space through its padding.
735
+ // Apply margin to visually align the icon with the top of the text to its left.
736
+ margin: $grid-unit-05 $grid-unit-05 $grid-unit-05 0;
737
+ }
738
+
739
+ .components-menu-group .reusable-blocks-menu-items__rename-hint {
740
+ margin: 0;
741
+ }
@@ -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
  }
@@ -16,14 +16,14 @@ export default function useListViewClientIds( { blocks, rootClientId } ) {
16
16
  const {
17
17
  getDraggedBlockClientIds,
18
18
  getSelectedBlockClientIds,
19
- getListViewClientIdsTree,
19
+ getEnabledClientIdsTree,
20
20
  } = unlock( select( blockEditorStore ) );
21
21
 
22
22
  return {
23
23
  selectedClientIds: getSelectedBlockClientIds(),
24
24
  draggedClientIds: getDraggedBlockClientIds(),
25
25
  clientIdsTree:
26
- blocks ?? getListViewClientIdsTree( rootClientId ),
26
+ blocks ?? getEnabledClientIdsTree( rootClientId ),
27
27
  };
28
28
  },
29
29
  [ blocks, rootClientId ]
@@ -136,21 +136,18 @@ export const isBlockSubtreeDisabled = createSelector(
136
136
  *
137
137
  * @return {Object[]} Tree of block objects with only clientID and innerBlocks set.
138
138
  */
139
- export const getListViewClientIdsTree = createSelector(
139
+ export const getEnabledClientIdsTree = createSelector(
140
140
  ( state, rootClientId = '' ) => {
141
141
  return getBlockOrder( state, rootClientId ).flatMap( ( clientId ) => {
142
142
  if ( getBlockEditingMode( state, clientId ) !== 'disabled' ) {
143
143
  return [
144
144
  {
145
145
  clientId,
146
- innerBlocks: getListViewClientIdsTree(
147
- state,
148
- clientId
149
- ),
146
+ innerBlocks: getEnabledClientIdsTree( state, clientId ),
150
147
  },
151
148
  ];
152
149
  }
153
- return getListViewClientIdsTree( state, clientId );
150
+ return getEnabledClientIdsTree( state, clientId );
154
151
  } );
155
152
  },
156
153
  ( state ) => [