@wordpress/block-editor 11.3.6 → 11.3.8

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 (55) hide show
  1. package/build/components/block-settings-menu/block-settings-dropdown.js +2 -2
  2. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  3. package/build/components/inserter/index.js +29 -17
  4. package/build/components/inserter/index.js.map +1 -1
  5. package/build/components/inserter/quick-inserter.js +4 -2
  6. package/build/components/inserter/quick-inserter.js.map +1 -1
  7. package/build/components/inserter/search-results.js +10 -3
  8. package/build/components/inserter/search-results.js.map +1 -1
  9. package/build/components/off-canvas-editor/appender.js +28 -3
  10. package/build/components/off-canvas-editor/appender.js.map +1 -1
  11. package/build/components/off-canvas-editor/block-contents.js +1 -1
  12. package/build/components/off-canvas-editor/block-contents.js.map +1 -1
  13. package/build/components/off-canvas-editor/branch.js +5 -3
  14. package/build/components/off-canvas-editor/branch.js.map +1 -1
  15. package/build/components/off-canvas-editor/index.js +7 -1
  16. package/build/components/off-canvas-editor/index.js.map +1 -1
  17. package/build/private-apis.js +4 -1
  18. package/build/private-apis.js.map +1 -1
  19. package/build/store/actions.js +28 -14
  20. package/build/store/actions.js.map +1 -1
  21. package/build-module/components/block-settings-menu/block-settings-dropdown.js +2 -2
  22. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  23. package/build-module/components/inserter/index.js +28 -16
  24. package/build-module/components/inserter/index.js.map +1 -1
  25. package/build-module/components/inserter/quick-inserter.js +4 -2
  26. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  27. package/build-module/components/inserter/search-results.js +10 -3
  28. package/build-module/components/inserter/search-results.js.map +1 -1
  29. package/build-module/components/off-canvas-editor/appender.js +28 -4
  30. package/build-module/components/off-canvas-editor/appender.js.map +1 -1
  31. package/build-module/components/off-canvas-editor/block-contents.js +1 -1
  32. package/build-module/components/off-canvas-editor/block-contents.js.map +1 -1
  33. package/build-module/components/off-canvas-editor/branch.js +5 -3
  34. package/build-module/components/off-canvas-editor/branch.js.map +1 -1
  35. package/build-module/components/off-canvas-editor/index.js +7 -1
  36. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  37. package/build-module/private-apis.js +3 -1
  38. package/build-module/private-apis.js.map +1 -1
  39. package/build-module/store/actions.js +28 -14
  40. package/build-module/store/actions.js.map +1 -1
  41. package/build-style/style-rtl.css +3 -0
  42. package/build-style/style.css +3 -0
  43. package/package.json +4 -4
  44. package/src/components/block-settings-menu/block-settings-dropdown.js +4 -1
  45. package/src/components/inserter/index.js +30 -11
  46. package/src/components/inserter/quick-inserter.js +2 -0
  47. package/src/components/inserter/search-results.js +7 -1
  48. package/src/components/inserter/style.scss +3 -0
  49. package/src/components/off-canvas-editor/appender.js +31 -5
  50. package/src/components/off-canvas-editor/block-contents.js +1 -1
  51. package/src/components/off-canvas-editor/branch.js +3 -1
  52. package/src/components/off-canvas-editor/index.js +6 -0
  53. package/src/private-apis.js +2 -0
  54. package/src/store/actions.js +16 -6
  55. package/src/store/test/actions.js +4 -2
@@ -9,7 +9,7 @@ import classnames from 'classnames';
9
9
  import { speak } from '@wordpress/a11y';
10
10
  import { __, _x, sprintf } from '@wordpress/i18n';
11
11
  import { Dropdown, Button } from '@wordpress/components';
12
- import { Component } from '@wordpress/element';
12
+ import { forwardRef, Component } from '@wordpress/element';
13
13
  import { withDispatch, withSelect } from '@wordpress/data';
14
14
  import { compose, ifCondition } from '@wordpress/compose';
15
15
  import { createBlock, store as blocksStore } from '@wordpress/blocks';
@@ -31,21 +31,26 @@ const defaultRenderToggle = ( {
31
31
  toggleProps = {},
32
32
  prioritizePatterns,
33
33
  } ) => {
34
- let label;
35
- if ( hasSingleBlockType ) {
34
+ const {
35
+ as: Wrapper = Button,
36
+ label: labelProp,
37
+ onClick,
38
+ ...rest
39
+ } = toggleProps;
40
+
41
+ let label = labelProp;
42
+ if ( ! label && hasSingleBlockType ) {
36
43
  label = sprintf(
37
44
  // translators: %s: the name of the block when there is only one
38
45
  _x( 'Add %s', 'directly add the only allowed block' ),
39
46
  blockTitle
40
47
  );
41
- } else if ( prioritizePatterns ) {
48
+ } else if ( ! label && prioritizePatterns ) {
42
49
  label = __( 'Add pattern' );
43
- } else {
50
+ } else if ( ! label ) {
44
51
  label = _x( 'Add block', 'Generic label for block inserter button' );
45
52
  }
46
53
 
47
- const { onClick, ...rest } = toggleProps;
48
-
49
54
  // Handle both onClick functions from the toggle and the parent component.
50
55
  function handleClick( event ) {
51
56
  if ( onToggle ) {
@@ -57,7 +62,7 @@ const defaultRenderToggle = ( {
57
62
  }
58
63
 
59
64
  return (
60
- <Button
65
+ <Wrapper
61
66
  icon={ plus }
62
67
  label={ label }
63
68
  tooltipPosition="bottom"
@@ -71,7 +76,7 @@ const defaultRenderToggle = ( {
71
76
  );
72
77
  };
73
78
 
74
- class Inserter extends Component {
79
+ class PrivateInserter extends Component {
75
80
  constructor() {
76
81
  super( ...arguments );
77
82
 
@@ -145,6 +150,7 @@ class Inserter extends Component {
145
150
  prioritizePatterns,
146
151
  onSelectOrClose,
147
152
  selectBlockOnInsert,
153
+ orderInitialBlockItems,
148
154
  } = this.props;
149
155
 
150
156
  if ( isQuick ) {
@@ -168,6 +174,7 @@ class Inserter extends Component {
168
174
  isAppender={ isAppender }
169
175
  prioritizePatterns={ prioritizePatterns }
170
176
  selectBlockOnInsert={ selectBlockOnInsert }
177
+ orderInitialBlockItems={ orderInitialBlockItems }
171
178
  />
172
179
  );
173
180
  }
@@ -219,7 +226,7 @@ class Inserter extends Component {
219
226
  }
220
227
  }
221
228
 
222
- export default compose( [
229
+ export const ComposedPrivateInserter = compose( [
223
230
  withSelect(
224
231
  ( select, { clientId, rootClientId, shouldDirectInsert = true } ) => {
225
232
  const {
@@ -416,4 +423,16 @@ export default compose( [
416
423
  ( { hasItems, isAppender, rootClientId, clientId } ) =>
417
424
  hasItems || ( ! isAppender && ! rootClientId && ! clientId )
418
425
  ),
419
- ] )( Inserter );
426
+ ] )( PrivateInserter );
427
+
428
+ const Inserter = forwardRef( ( props, ref ) => {
429
+ return (
430
+ <ComposedPrivateInserter
431
+ ref={ ref }
432
+ { ...props }
433
+ orderInitialBlockItems={ undefined }
434
+ />
435
+ );
436
+ } );
437
+
438
+ export default Inserter;
@@ -32,6 +32,7 @@ export default function QuickInserter( {
32
32
  isAppender,
33
33
  prioritizePatterns,
34
34
  selectBlockOnInsert,
35
+ orderInitialBlockItems,
35
36
  } ) {
36
37
  const [ filterValue, setFilterValue ] = useState( '' );
37
38
  const [ destinationRootClientId, onInsertBlocks ] = useInsertionPoint( {
@@ -124,6 +125,7 @@ export default function QuickInserter( {
124
125
  isDraggable={ false }
125
126
  prioritizePatterns={ prioritizePatterns }
126
127
  selectBlockOnInsert={ selectBlockOnInsert }
128
+ orderInitialBlockItems={ orderInitialBlockItems }
127
129
  />
128
130
  </div>
129
131
 
@@ -46,6 +46,7 @@ function InserterSearchResults( {
46
46
  shouldFocusBlock = true,
47
47
  prioritizePatterns,
48
48
  selectBlockOnInsert,
49
+ orderInitialBlockItems,
49
50
  } ) {
50
51
  const debouncedSpeak = useDebounce( speak, 500 );
51
52
 
@@ -88,8 +89,12 @@ function InserterSearchResults( {
88
89
  if ( maxBlockTypesToShow === 0 ) {
89
90
  return [];
90
91
  }
92
+ let orderedItems = orderBy( blockTypes, 'frecency', 'desc' );
93
+ if ( ! filterValue && orderInitialBlockItems ) {
94
+ orderedItems = orderInitialBlockItems( orderedItems );
95
+ }
91
96
  const results = searchBlockItems(
92
- orderBy( blockTypes, 'frecency', 'desc' ),
97
+ orderedItems,
93
98
  blockTypeCategories,
94
99
  blockTypeCollections,
95
100
  filterValue
@@ -104,6 +109,7 @@ function InserterSearchResults( {
104
109
  blockTypeCategories,
105
110
  blockTypeCollections,
106
111
  maxBlockTypes,
112
+ orderInitialBlockItems,
107
113
  ] );
108
114
 
109
115
  // Announce search results on change.
@@ -35,6 +35,7 @@ $block-inserter-tabs-height: 44px;
35
35
  .components-popover__content {
36
36
  border: none;
37
37
  outline: none;
38
+ box-shadow: $shadow-popover;
38
39
 
39
40
  .block-editor-inserter__quick-inserter > * {
40
41
  border-left: $border-width solid $gray-400;
@@ -42,10 +43,12 @@ $block-inserter-tabs-height: 44px;
42
43
 
43
44
  &:first-child {
44
45
  border-top: $border-width solid $gray-400;
46
+ border-radius: $radius-block-ui $radius-block-ui 0 0;
45
47
  }
46
48
 
47
49
  &:last-child {
48
50
  border-bottom: $border-width solid $gray-400;
51
+ border-radius: 0 0 $radius-block-ui $radius-block-ui;
49
52
  }
50
53
 
51
54
  &.components-button {
@@ -4,7 +4,12 @@
4
4
  import { useInstanceId } from '@wordpress/compose';
5
5
  import { speak } from '@wordpress/a11y';
6
6
  import { useSelect } from '@wordpress/data';
7
- import { forwardRef, useState, useEffect } from '@wordpress/element';
7
+ import {
8
+ forwardRef,
9
+ useState,
10
+ useEffect,
11
+ useCallback,
12
+ } from '@wordpress/element';
8
13
  import { __, sprintf } from '@wordpress/i18n';
9
14
 
10
15
  /**
@@ -12,7 +17,14 @@ import { __, sprintf } from '@wordpress/i18n';
12
17
  */
13
18
  import { store as blockEditorStore } from '../../store';
14
19
  import useBlockDisplayTitle from '../block-title/use-block-display-title';
15
- import Inserter from '../inserter';
20
+
21
+ import { unlock } from '../../lock-unlock';
22
+ import { privateApis as blockEditorPrivateApis } from '../../private-apis';
23
+
24
+ const prioritizedInserterBlocks = [
25
+ 'core/navigation-link/page',
26
+ 'core/navigation-link',
27
+ ];
16
28
 
17
29
  export const Appender = forwardRef(
18
30
  ( { nestingLevel, blockCount, ...props }, ref ) => {
@@ -61,10 +73,23 @@ export const Appender = forwardRef(
61
73
  );
62
74
  }, [ insertedBlockTitle ] );
63
75
 
76
+ const orderInitialBlockItems = useCallback( ( items ) => {
77
+ items.sort( ( { id: aName }, { id: bName } ) => {
78
+ // Sort block items according to `prioritizedInserterBlocks`.
79
+ let aIndex = prioritizedInserterBlocks.indexOf( aName );
80
+ let bIndex = prioritizedInserterBlocks.indexOf( bName );
81
+ // All other block items should come after that.
82
+ if ( aIndex < 0 ) aIndex = prioritizedInserterBlocks.length;
83
+ if ( bIndex < 0 ) bIndex = prioritizedInserterBlocks.length;
84
+ return aIndex - bIndex;
85
+ } );
86
+ return items;
87
+ }, [] );
88
+
64
89
  if ( hideInserter ) {
65
90
  return null;
66
91
  }
67
-
92
+ const { PrivateInserter } = unlock( blockEditorPrivateApis );
68
93
  const descriptionId = `off-canvas-editor-appender__${ instanceId }`;
69
94
  const description = sprintf(
70
95
  /* translators: 1: The name of the block. 2: The numerical position of the block. 3: The level of nesting for the block. */
@@ -76,11 +101,11 @@ export const Appender = forwardRef(
76
101
 
77
102
  return (
78
103
  <div className="offcanvas-editor-appender">
79
- <Inserter
104
+ <PrivateInserter
80
105
  ref={ ref }
81
106
  rootClientId={ clientId }
82
107
  position="bottom right"
83
- isAppender={ true }
108
+ isAppender
84
109
  selectBlockOnInsert={ false }
85
110
  shouldDirectInsert={ false }
86
111
  __experimentalIsQuick
@@ -91,6 +116,7 @@ export const Appender = forwardRef(
91
116
  setInsertedBlock( maybeInsertedBlock );
92
117
  }
93
118
  } }
119
+ orderInitialBlockItems={ orderInitialBlockItems }
94
120
  />
95
121
  <div
96
122
  className="offcanvas-editor-appender__description"
@@ -73,7 +73,7 @@ const ListViewBlockContents = forwardRef(
73
73
  setInsertedBlockAttributes,
74
74
  } = useInsertedBlock( lastInsertedBlockClientId );
75
75
 
76
- const hasExistingLinkValue = insertedBlockAttributes?.id;
76
+ const hasExistingLinkValue = insertedBlockAttributes?.url;
77
77
 
78
78
  useEffect( () => {
79
79
  if (
@@ -97,6 +97,7 @@ function ListViewBranch( props ) {
97
97
  isExpanded,
98
98
  parentId,
99
99
  shouldShowInnerBlocks = true,
100
+ showAppender: showAppenderProp = true,
100
101
  } = props;
101
102
 
102
103
  const isContentLocked = useSelect(
@@ -117,7 +118,7 @@ function ListViewBranch( props ) {
117
118
  }
118
119
 
119
120
  // Only show the appender at the first level.
120
- const showAppender = level === 1;
121
+ const showAppender = showAppenderProp && level === 1;
121
122
 
122
123
  const filteredBlocks = blocks.filter( Boolean );
123
124
  const blockCount = filteredBlocks.length;
@@ -205,6 +206,7 @@ function ListViewBranch( props ) {
205
206
  isBranchSelected={ isSelectedBranch }
206
207
  selectedClientIds={ selectedClientIds }
207
208
  isExpanded={ isExpanded }
209
+ showAppender={ showAppenderProp }
208
210
  />
209
211
  ) }
210
212
  </AsyncModeProvider>
@@ -56,20 +56,24 @@ export const BLOCK_LIST_ITEM_HEIGHT = 36;
56
56
  *
57
57
  * @param {Object} props Components props.
58
58
  * @param {string} props.id An HTML element id for the root element of ListView.
59
+ * @param {string} props.parentClientId The client id of the parent block.
59
60
  * @param {Array} props.blocks Custom subset of block client IDs to be used instead of the default hierarchy.
60
61
  * @param {boolean} props.showBlockMovers Flag to enable block movers
61
62
  * @param {boolean} props.isExpanded Flag to determine whether nested levels are expanded by default.
62
63
  * @param {Object} props.LeafMoreMenu Optional more menu substitution.
63
64
  * @param {string} props.description Optional accessible description for the tree grid component.
64
65
  * @param {string} props.onSelect Optional callback to be invoked when a block is selected.
66
+ * @param {string} props.showAppender Flag to show or hide the block appender.
65
67
  * @param {Object} ref Forwarded ref
66
68
  */
67
69
  function OffCanvasEditor(
68
70
  {
69
71
  id,
72
+ parentClientId,
70
73
  blocks,
71
74
  showBlockMovers = false,
72
75
  isExpanded = false,
76
+ showAppender = true,
73
77
  LeafMoreMenu,
74
78
  description = __( 'Block navigation structure' ),
75
79
  onSelect,
@@ -227,6 +231,7 @@ function OffCanvasEditor(
227
231
  >
228
232
  <ListViewContext.Provider value={ contextValue }>
229
233
  <ListViewBranch
234
+ parentId={ parentClientId }
230
235
  blocks={ clientIdsTree }
231
236
  selectBlock={ selectEditorBlock }
232
237
  showBlockMovers={ showBlockMovers }
@@ -234,6 +239,7 @@ function OffCanvasEditor(
234
239
  selectedClientIds={ selectedClientIds }
235
240
  isExpanded={ isExpanded }
236
241
  shouldShowInnerBlocks={ shouldShowInnerBlocks }
242
+ showAppender={ showAppender }
237
243
  />
238
244
  <TreeGridRow
239
245
  level={ 1 }
@@ -6,6 +6,7 @@ import { ExperimentalBlockEditorProvider } from './components/provider';
6
6
  import { lock } from './lock-unlock';
7
7
  import OffCanvasEditor from './components/off-canvas-editor';
8
8
  import LeafMoreMenu from './components/off-canvas-editor/leaf-more-menu';
9
+ import { ComposedPrivateInserter as PrivateInserter } from './components/inserter';
9
10
 
10
11
  /**
11
12
  * Private @wordpress/block-editor APIs.
@@ -16,4 +17,5 @@ lock( privateApis, {
16
17
  ExperimentalBlockEditorProvider,
17
18
  LeafMoreMenu,
18
19
  OffCanvasEditor,
20
+ PrivateInserter,
19
21
  } );
@@ -232,17 +232,24 @@ export function selectBlock( clientId, initialPosition = 0 ) {
232
232
 
233
233
  /**
234
234
  * Yields action objects used in signalling that the block preceding the given
235
- * clientId should be selected.
235
+ * clientId (or optionally, its first parent from bottom to top)
236
+ * should be selected.
236
237
  *
237
- * @param {string} clientId Block client ID.
238
+ * @param {string} clientId Block client ID.
239
+ * @param {boolean} fallbackToParent If true, select the first parent if there is no previous block.
238
240
  */
239
241
  export const selectPreviousBlock =
240
- ( clientId ) =>
242
+ ( clientId, fallbackToParent = false ) =>
241
243
  ( { select, dispatch } ) => {
242
244
  const previousBlockClientId =
243
245
  select.getPreviousBlockClientId( clientId );
244
246
  if ( previousBlockClientId ) {
245
247
  dispatch.selectBlock( previousBlockClientId, -1 );
248
+ } else if ( fallbackToParent ) {
249
+ const firstParentClientId = select.getBlockRootClientId( clientId );
250
+ if ( firstParentClientId ) {
251
+ dispatch.selectBlock( firstParentClientId, -1 );
252
+ }
246
253
  }
247
254
  };
248
255
 
@@ -1175,8 +1182,11 @@ export const mergeBlocks =
1175
1182
  * the set of specified client IDs are to be removed.
1176
1183
  *
1177
1184
  * @param {string|string[]} clientIds Client IDs of blocks to remove.
1178
- * @param {boolean} selectPrevious True if the previous block should be
1179
- * selected when a block is removed.
1185
+ * @param {boolean} selectPrevious True if the previous block
1186
+ * or the immediate parent
1187
+ * (if no previous block exists)
1188
+ * should be selected
1189
+ * when a block is removed.
1180
1190
  */
1181
1191
  export const removeBlocks =
1182
1192
  ( clientIds, selectPrevious = true ) =>
@@ -1197,7 +1207,7 @@ export const removeBlocks =
1197
1207
  }
1198
1208
 
1199
1209
  if ( selectPrevious ) {
1200
- dispatch.selectPreviousBlock( clientIds[ 0 ] );
1210
+ dispatch.selectPreviousBlock( clientIds[ 0 ], selectPrevious );
1201
1211
  }
1202
1212
 
1203
1213
  dispatch( { type: 'REMOVE_BLOCKS', clientIds } );
@@ -625,7 +625,8 @@ describe( 'actions', () => {
625
625
  removeBlocks( clientIds )( { select, dispatch } );
626
626
 
627
627
  expect( dispatch.selectPreviousBlock ).toHaveBeenCalledWith(
628
- clientId
628
+ clientId,
629
+ true
629
630
  );
630
631
 
631
632
  expect( dispatch ).toHaveBeenCalledWith( {
@@ -734,7 +735,8 @@ describe( 'actions', () => {
734
735
  removeBlock( clientId )( { select, dispatch } );
735
736
 
736
737
  expect( dispatch.selectPreviousBlock ).toHaveBeenCalledWith(
737
- clientId
738
+ clientId,
739
+ true
738
740
  );
739
741
 
740
742
  expect( dispatch ).toHaveBeenCalledWith( {