@wordpress/block-editor 12.8.1 → 12.9.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 (106) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +5 -12
  3. package/build/components/block-list/block-outline.native.js +4 -3
  4. package/build/components/block-list/block-outline.native.js.map +1 -1
  5. package/build/components/block-list/index.js +4 -3
  6. package/build/components/block-list/index.js.map +1 -1
  7. package/build/components/block-popover/inbetween.js +4 -5
  8. package/build/components/block-popover/inbetween.js.map +1 -1
  9. package/build/components/block-popover/index.js +3 -2
  10. package/build/components/block-popover/index.js.map +1 -1
  11. package/build/components/color-style-selector/index.js +1 -1
  12. package/build/components/color-style-selector/index.js.map +1 -1
  13. package/build/components/inserter/reusable-blocks-tab.native.js +7 -4
  14. package/build/components/inserter/reusable-blocks-tab.native.js.map +1 -1
  15. package/build/components/inserter/search-results.native.js +10 -8
  16. package/build/components/inserter/search-results.native.js.map +1 -1
  17. package/build/components/link-control/index.js +1 -7
  18. package/build/components/link-control/index.js.map +1 -1
  19. package/build/components/list-view/block-select-button.js +48 -7
  20. package/build/components/list-view/block-select-button.js.map +1 -1
  21. package/build/components/list-view/drop-indicator.js +3 -3
  22. package/build/components/list-view/drop-indicator.js.map +1 -1
  23. package/build/components/list-view/index.js +14 -8
  24. package/build/components/list-view/index.js.map +1 -1
  25. package/build/components/list-view/use-list-view-images.js +5 -4
  26. package/build/components/list-view/use-list-view-images.js.map +1 -1
  27. package/build/components/preview-options/index.js +3 -1
  28. package/build/components/preview-options/index.js.map +1 -1
  29. package/build/components/provider/index.js +3 -1
  30. package/build/components/provider/index.js.map +1 -1
  31. package/build/components/use-block-commands/index.js +74 -63
  32. package/build/components/use-block-commands/index.js.map +1 -1
  33. package/build/components/warning/index.js +1 -1
  34. package/build/components/warning/index.js.map +1 -1
  35. package/build/hooks/auto-inserting-blocks.js +174 -0
  36. package/build/hooks/auto-inserting-blocks.js.map +1 -0
  37. package/build/hooks/index.js +1 -0
  38. package/build/hooks/index.js.map +1 -1
  39. package/build-module/components/block-list/block-outline.native.js +4 -3
  40. package/build-module/components/block-list/block-outline.native.js.map +1 -1
  41. package/build-module/components/block-list/index.js +4 -3
  42. package/build-module/components/block-list/index.js.map +1 -1
  43. package/build-module/components/block-popover/inbetween.js +4 -5
  44. package/build-module/components/block-popover/inbetween.js.map +1 -1
  45. package/build-module/components/block-popover/index.js +3 -2
  46. package/build-module/components/block-popover/index.js.map +1 -1
  47. package/build-module/components/color-style-selector/index.js +1 -1
  48. package/build-module/components/color-style-selector/index.js.map +1 -1
  49. package/build-module/components/inserter/reusable-blocks-tab.native.js +8 -4
  50. package/build-module/components/inserter/reusable-blocks-tab.native.js.map +1 -1
  51. package/build-module/components/inserter/search-results.native.js +11 -8
  52. package/build-module/components/inserter/search-results.native.js.map +1 -1
  53. package/build-module/components/link-control/index.js +1 -7
  54. package/build-module/components/link-control/index.js.map +1 -1
  55. package/build-module/components/list-view/block-select-button.js +48 -7
  56. package/build-module/components/list-view/block-select-button.js.map +1 -1
  57. package/build-module/components/list-view/drop-indicator.js +3 -3
  58. package/build-module/components/list-view/drop-indicator.js.map +1 -1
  59. package/build-module/components/list-view/index.js +14 -8
  60. package/build-module/components/list-view/index.js.map +1 -1
  61. package/build-module/components/list-view/use-list-view-images.js +5 -4
  62. package/build-module/components/list-view/use-list-view-images.js.map +1 -1
  63. package/build-module/components/preview-options/index.js +3 -1
  64. package/build-module/components/preview-options/index.js.map +1 -1
  65. package/build-module/components/provider/index.js +3 -1
  66. package/build-module/components/provider/index.js.map +1 -1
  67. package/build-module/components/use-block-commands/index.js +74 -63
  68. package/build-module/components/use-block-commands/index.js.map +1 -1
  69. package/build-module/components/warning/index.js +2 -2
  70. package/build-module/components/warning/index.js.map +1 -1
  71. package/build-module/hooks/auto-inserting-blocks.js +167 -0
  72. package/build-module/hooks/auto-inserting-blocks.js.map +1 -0
  73. package/build-module/hooks/index.js +1 -0
  74. package/build-module/hooks/index.js.map +1 -1
  75. package/build-style/content-rtl.css +8 -7
  76. package/build-style/content.css +8 -7
  77. package/package.json +32 -32
  78. package/src/components/block-list/block-outline.native.js +5 -2
  79. package/src/components/block-list/content.scss +2 -3
  80. package/src/components/block-list/index.js +4 -3
  81. package/src/components/block-popover/inbetween.js +4 -3
  82. package/src/components/block-popover/index.js +3 -2
  83. package/src/components/button-block-appender/content.scss +8 -0
  84. package/src/components/color-style-selector/index.js +1 -1
  85. package/src/components/inserter/reusable-blocks-tab.native.js +7 -2
  86. package/src/components/inserter/search-results.native.js +13 -9
  87. package/src/components/link-control/index.js +1 -5
  88. package/src/components/link-control/test/index.js +1 -0
  89. package/src/components/list-view/block-select-button.js +67 -15
  90. package/src/components/list-view/drop-indicator.js +4 -5
  91. package/src/components/list-view/index.js +19 -13
  92. package/src/components/list-view/use-list-view-images.js +8 -4
  93. package/src/components/observe-typing/README.md +2 -2
  94. package/src/components/preview-options/index.js +2 -0
  95. package/src/components/provider/index.js +8 -1
  96. package/src/components/use-block-commands/index.js +92 -88
  97. package/src/components/warning/index.js +2 -2
  98. package/src/hooks/auto-inserting-blocks.js +232 -0
  99. package/src/hooks/index.js +1 -0
  100. package/build/utils/pre-parse-patterns.js +0 -68
  101. package/build/utils/pre-parse-patterns.js.map +0 -1
  102. package/build-module/utils/pre-parse-patterns.js +0 -61
  103. package/build-module/utils/pre-parse-patterns.js.map +0 -1
  104. package/src/components/url-popover/test/__snapshots__/index.js.snap +0 -133
  105. package/src/components/url-popover/test/index.js +0 -75
  106. package/src/utils/pre-parse-patterns.js +0 -69
@@ -12,13 +12,17 @@ import { store as blockEditorStore } from '../../store';
12
12
  // Maximum number of images to display in a list view row.
13
13
  const MAX_IMAGES = 3;
14
14
 
15
- function getImageUrl( block ) {
15
+ function getImage( block ) {
16
16
  if ( block.name !== 'core/image' ) {
17
17
  return;
18
18
  }
19
19
 
20
20
  if ( block.attributes?.url ) {
21
- return { url: block.attributes.url, alt: block.attributes.alt };
21
+ return {
22
+ url: block.attributes.url,
23
+ alt: block.attributes.alt,
24
+ clientId: block.clientId,
25
+ };
22
26
  }
23
27
  }
24
28
 
@@ -30,7 +34,7 @@ function getImagesFromGallery( block ) {
30
34
  const images = [];
31
35
 
32
36
  for ( const innerBlock of block.innerBlocks ) {
33
- const img = getImageUrl( innerBlock );
37
+ const img = getImage( innerBlock );
34
38
  if ( img ) {
35
39
  images.push( img );
36
40
  }
@@ -43,7 +47,7 @@ function getImagesFromGallery( block ) {
43
47
  }
44
48
 
45
49
  function getImagesFromBlock( block, isExpanded ) {
46
- const img = getImageUrl( block );
50
+ const img = getImage( block );
47
51
  if ( img ) {
48
52
  return [ img ];
49
53
  }
@@ -1,6 +1,6 @@
1
1
  # Observe Typing
2
2
 
3
- `<ObserveTyping />` is a component used in managing the editor's internal typing flag. When used to wrap content — typically the top-level block list — it observes keyboard and mouse events to set and unset the typing flag. The typing flag is used in considering whether the block border and controls should be visible. While typing, these elements are hidden for a distraction-free experience.
3
+ `<ObserveTyping />` is a component used in managing the editor's internal typing flag. When used to wrap content, it observes keyboard and mouse events to set and unset the typing flag. The typing flag is used in considering whether the block border and controls should be visible. While typing, these elements are hidden for a distraction-free experience.
4
4
 
5
5
  ## Usage
6
6
 
@@ -10,7 +10,7 @@ Wrap the component where blocks are to be rendered with `<ObserveTyping />`:
10
10
  function VisualEditor() {
11
11
  return (
12
12
  <ObserveTyping>
13
- <BlockList />
13
+ <MyInput />
14
14
  </ObserveTyping>
15
15
  );
16
16
  }
@@ -33,6 +33,7 @@ export default function PreviewOptions( {
33
33
  const toggleProps = {
34
34
  className: 'block-editor-post-preview__button-toggle',
35
35
  disabled: ! isEnabled,
36
+ __experimentalIsFocusable: ! isEnabled,
36
37
  children: viewLabel,
37
38
  };
38
39
  const menuProps = {
@@ -53,6 +54,7 @@ export default function PreviewOptions( {
53
54
  menuProps={ menuProps }
54
55
  icon={ deviceIcons[ deviceType.toLowerCase() ] }
55
56
  label={ label || __( 'Preview' ) }
57
+ disableOpenOnArrowDown={ ! isEnabled }
56
58
  >
57
59
  { ( renderProps ) => (
58
60
  <>
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { useDispatch } from '@wordpress/data';
5
5
  import { useEffect } from '@wordpress/element';
6
+ import { SlotFillProvider } from '@wordpress/components';
6
7
 
7
8
  /**
8
9
  * Internal dependencies
@@ -12,6 +13,7 @@ import useBlockSync from './use-block-sync';
12
13
  import { store as blockEditorStore } from '../../store';
13
14
  import { BlockRefsProvider } from './block-refs-provider';
14
15
  import { unlock } from '../../lock-unlock';
16
+ import KeyboardShortcuts from '../keyboard-shortcuts';
15
17
 
16
18
  /** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */
17
19
 
@@ -42,7 +44,12 @@ export const ExperimentalBlockEditorProvider = withRegistryProvider(
42
44
  // Syncs the entity provider with changes in the block-editor store.
43
45
  useBlockSync( props );
44
46
 
45
- return <BlockRefsProvider>{ children }</BlockRefsProvider>;
47
+ return (
48
+ <SlotFillProvider>
49
+ <KeyboardShortcuts.Register />
50
+ <BlockRefsProvider>{ children }</BlockRefsProvider>
51
+ </SlotFillProvider>
52
+ );
46
53
  }
47
54
  );
48
55
 
@@ -126,28 +126,12 @@ const useActionsCommands = () => {
126
126
  getBlocksByClientId,
127
127
  canMoveBlocks,
128
128
  canRemoveBlocks,
129
+ getBlockCount,
129
130
  } = useSelect( blockEditorStore );
130
131
  const { getDefaultBlockName, getGroupingBlockName } =
131
132
  useSelect( blocksStore );
132
133
 
133
134
  const blocks = getBlocksByClientId( clientIds );
134
- const rootClientId = getBlockRootClientId( clientIds[ 0 ] );
135
-
136
- const canDuplicate = blocks.every( ( block ) => {
137
- return (
138
- !! block &&
139
- hasBlockSupport( block.name, 'multiple', true ) &&
140
- canInsertBlockType( block.name, rootClientId )
141
- );
142
- } );
143
-
144
- const canInsertDefaultBlock = canInsertBlockType(
145
- getDefaultBlockName(),
146
- rootClientId
147
- );
148
-
149
- const canMove = canMoveBlocks( clientIds, rootClientId );
150
- const canRemove = canRemoveBlocks( clientIds, rootClientId );
151
135
 
152
136
  const {
153
137
  removeBlocks,
@@ -160,42 +144,6 @@ const useActionsCommands = () => {
160
144
  selectBlock,
161
145
  } = useDispatch( blockEditorStore );
162
146
 
163
- const onDuplicate = () => {
164
- if ( ! canDuplicate ) {
165
- return;
166
- }
167
- return duplicateBlocks( clientIds, true );
168
- };
169
- const onRemove = () => {
170
- if ( ! canRemove ) {
171
- return;
172
- }
173
- return removeBlocks( clientIds, true );
174
- };
175
- const onAddBefore = () => {
176
- if ( ! canInsertDefaultBlock ) {
177
- return;
178
- }
179
- const clientId = Array.isArray( clientIds ) ? clientIds[ 0 ] : clientId;
180
- insertBeforeBlock( clientId );
181
- };
182
- const onAddAfter = () => {
183
- if ( ! canInsertDefaultBlock ) {
184
- return;
185
- }
186
- const clientId = Array.isArray( clientIds )
187
- ? clientIds[ clientIds.length - 1 ]
188
- : clientId;
189
- insertAfterBlock( clientId );
190
- };
191
- const onMoveTo = () => {
192
- if ( ! canMove ) {
193
- return;
194
- }
195
- setNavigationMode( true );
196
- selectBlock( clientIds[ 0 ] );
197
- setBlockMovingClientId( clientIds[ 0 ] );
198
- };
199
147
  const onGroup = () => {
200
148
  if ( ! blocks.length ) {
201
149
  return;
@@ -229,47 +177,103 @@ const useActionsCommands = () => {
229
177
  return { isLoading: false, commands: [] };
230
178
  }
231
179
 
232
- const icons = {
233
- ungroup,
234
- group,
235
- move,
236
- add,
237
- remove,
238
- duplicate: copy,
239
- };
180
+ const rootClientId = getBlockRootClientId( clientIds[ 0 ] );
181
+ const canInsertDefaultBlock = canInsertBlockType(
182
+ getDefaultBlockName(),
183
+ rootClientId
184
+ );
185
+ const canDuplicate = blocks.every( ( block ) => {
186
+ return (
187
+ !! block &&
188
+ hasBlockSupport( block.name, 'multiple', true ) &&
189
+ canInsertBlockType( block.name, rootClientId )
190
+ );
191
+ } );
192
+ const canRemove = canRemoveBlocks( clientIds, rootClientId );
193
+ const canMove =
194
+ canMoveBlocks( clientIds, rootClientId ) &&
195
+ getBlockCount( rootClientId ) !== 1;
240
196
 
241
197
  const commands = [
242
- onUngroup,
243
- onGroup,
244
- onMoveTo,
245
- onAddAfter,
246
- onAddBefore,
247
- onRemove,
248
- onDuplicate,
249
- ].map( ( callback ) => {
250
- const action = callback.name
251
- .replace( 'on', '' )
252
- .replace( /([a-z])([A-Z])/g, '$1 $2' );
198
+ {
199
+ name: 'ungroup',
200
+ label: __( 'Ungroup' ),
201
+ callback: onUngroup,
202
+ icon: ungroup,
203
+ },
204
+ {
205
+ name: 'Group',
206
+ label: __( 'Group' ),
207
+ callback: onGroup,
208
+ icon: group,
209
+ },
210
+ ];
211
+ if ( canInsertDefaultBlock ) {
212
+ commands.push(
213
+ {
214
+ name: 'add-after',
215
+ label: __( 'Add after' ),
216
+ callback: () => {
217
+ const clientId = Array.isArray( clientIds )
218
+ ? clientIds[ clientIds.length - 1 ]
219
+ : clientId;
220
+ insertAfterBlock( clientId );
221
+ },
222
+ icon: add,
223
+ },
224
+ {
225
+ name: 'add-before',
226
+ label: __( 'Add before' ),
227
+ callback: () => {
228
+ const clientId = Array.isArray( clientIds )
229
+ ? clientIds[ 0 ]
230
+ : clientId;
231
+ insertBeforeBlock( clientId );
232
+ },
233
+ icon: add,
234
+ }
235
+ );
236
+ }
237
+ if ( canRemove ) {
238
+ commands.push( {
239
+ name: 'remove',
240
+ label: __( 'Remove' ),
241
+ callback: () => removeBlocks( clientIds, true ),
242
+ icon: remove,
243
+ } );
244
+ }
245
+ if ( canDuplicate ) {
246
+ commands.push( {
247
+ name: 'duplicate',
248
+ label: __( 'Duplicate' ),
249
+ callback: () => duplicateBlocks( clientIds, true ),
250
+ icon: copy,
251
+ } );
252
+ }
253
+ if ( canMove ) {
254
+ commands.push( {
255
+ name: 'move-to',
256
+ label: __( 'Move to' ),
257
+ callback: () => {
258
+ setNavigationMode( true );
259
+ selectBlock( clientIds[ 0 ] );
260
+ setBlockMovingClientId( clientIds[ 0 ] );
261
+ },
262
+ icon: move,
263
+ } );
264
+ }
253
265
 
254
- return {
255
- name: 'core/block-editor/action-' + callback.name,
256
- // translators: %s: type of the command.
257
- label: action,
258
- icon: icons[
259
- callback.name
260
- .replace( 'on', '' )
261
- .match( /[A-Z]{1}[a-z]*/ )
262
- .toString()
263
- .toLowerCase()
264
- ],
266
+ return {
267
+ isLoading: false,
268
+ commands: commands.map( ( command ) => ( {
269
+ ...command,
270
+ name: 'core/block-editor/action-' + command.name,
265
271
  callback: ( { close } ) => {
266
- callback();
272
+ command.callback();
267
273
  close();
268
274
  },
269
- };
270
- } );
271
-
272
- return { isLoading: false, commands };
275
+ } ) ),
276
+ };
273
277
  };
274
278
 
275
279
  export const useBlockCommands = () => {
@@ -9,7 +9,7 @@ import classnames from 'classnames';
9
9
  import { Children } from '@wordpress/element';
10
10
  import { DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components';
11
11
  import { __ } from '@wordpress/i18n';
12
- import { moreHorizontal } from '@wordpress/icons';
12
+ import { moreVertical } from '@wordpress/icons';
13
13
 
14
14
  function Warning( { className, actions, children, secondaryActions } ) {
15
15
  return (
@@ -34,7 +34,7 @@ function Warning( { className, actions, children, secondaryActions } ) {
34
34
  { secondaryActions && (
35
35
  <DropdownMenu
36
36
  className="block-editor-warning__secondary"
37
- icon={ moreHorizontal }
37
+ icon={ moreVertical }
38
38
  label={ __( 'More options' ) }
39
39
  popoverProps={ {
40
40
  position: 'bottom left',
@@ -0,0 +1,232 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import { addFilter } from '@wordpress/hooks';
6
+ import { Fragment } from '@wordpress/element';
7
+ import { PanelBody, ToggleControl } from '@wordpress/components';
8
+ import { createHigherOrderComponent } from '@wordpress/compose';
9
+ import { createBlock, store as blocksStore } from '@wordpress/blocks';
10
+ import { useDispatch, useSelect } from '@wordpress/data';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import { InspectorControls } from '../components';
16
+ import { store as blockEditorStore } from '../store';
17
+
18
+ function AutoInsertingBlocksControl( props ) {
19
+ const { autoInsertedBlocksForCurrentBlock, groupedAutoInsertedBlocks } =
20
+ useSelect(
21
+ ( select ) => {
22
+ const { getBlockTypes } = select( blocksStore );
23
+ const _autoInsertedBlocksForCurrentBlock =
24
+ getBlockTypes()?.filter(
25
+ ( { autoInsert } ) =>
26
+ autoInsert && props.blockName in autoInsert
27
+ );
28
+
29
+ // Group by block namespace (i.e. prefix before the slash).
30
+ const _groupedAutoInsertedBlocks =
31
+ _autoInsertedBlocksForCurrentBlock?.reduce(
32
+ ( groups, block ) => {
33
+ const [ namespace ] = block.name.split( '/' );
34
+ if ( ! groups[ namespace ] ) {
35
+ groups[ namespace ] = [];
36
+ }
37
+ groups[ namespace ].push( block );
38
+ return groups;
39
+ },
40
+ {}
41
+ );
42
+
43
+ return {
44
+ autoInsertedBlocksForCurrentBlock:
45
+ _autoInsertedBlocksForCurrentBlock,
46
+ groupedAutoInsertedBlocks: _groupedAutoInsertedBlocks,
47
+ };
48
+ },
49
+ [ props.blockName ]
50
+ );
51
+
52
+ const {
53
+ autoInsertedBlockClientIds,
54
+ blockIndex,
55
+ rootClientId,
56
+ innerBlocksLength,
57
+ } = useSelect(
58
+ ( select ) => {
59
+ const { getBlock, getBlockIndex, getBlockRootClientId } =
60
+ select( blockEditorStore );
61
+ const _rootClientId = getBlockRootClientId( props.clientId );
62
+
63
+ const _autoInsertedBlockClientIds =
64
+ autoInsertedBlocksForCurrentBlock.reduce(
65
+ ( clientIds, block ) => {
66
+ const relativePosition =
67
+ block?.autoInsert?.[ props.blockName ];
68
+ let candidates;
69
+
70
+ switch ( relativePosition ) {
71
+ case 'before':
72
+ case 'after':
73
+ // Any of the current block's siblings (with the right block type) qualifies
74
+ // as an auto-inserted block (inserted `before` or `after` the current one),
75
+ // as the block might've been auto-inserted and then moved around a bit by the user.
76
+ candidates =
77
+ getBlock( _rootClientId )?.innerBlocks;
78
+ break;
79
+
80
+ case 'first_child':
81
+ case 'last_child':
82
+ // Any of the current block's child blocks (with the right block type) qualifies
83
+ // as an auto-inserted first or last child block, as the block might've been
84
+ // auto-inserted and then moved around a bit by the user.
85
+ candidates = getBlock(
86
+ props.clientId
87
+ ).innerBlocks;
88
+ break;
89
+ }
90
+
91
+ const autoInsertedBlock = candidates?.find(
92
+ ( { name } ) => name === block.name
93
+ );
94
+
95
+ if ( autoInsertedBlock ) {
96
+ clientIds[ block.name ] =
97
+ autoInsertedBlock.clientId;
98
+ }
99
+
100
+ // TOOD: If no auto-inserted block was found in any of its designated locations,
101
+ // we want to check if it's present elsewhere in the block tree.
102
+ // If it is, we'd consider it manually inserted and would want to remove the
103
+ // corresponding toggle from the block inspector panel.
104
+
105
+ return clientIds;
106
+ },
107
+ {}
108
+ );
109
+
110
+ return {
111
+ blockIndex: getBlockIndex( props.clientId ),
112
+ innerBlocksLength: getBlock( props.clientId )?.innerBlocks
113
+ ?.length,
114
+ rootClientId: _rootClientId,
115
+ autoInsertedBlockClientIds: _autoInsertedBlockClientIds,
116
+ };
117
+ },
118
+ [ autoInsertedBlocksForCurrentBlock, props.blockName, props.clientId ]
119
+ );
120
+
121
+ const { insertBlock, removeBlock } = useDispatch( blockEditorStore );
122
+
123
+ if ( ! autoInsertedBlocksForCurrentBlock.length ) {
124
+ return null;
125
+ }
126
+
127
+ const insertBlockIntoDesignatedLocation = ( block, relativePosition ) => {
128
+ switch ( relativePosition ) {
129
+ case 'before':
130
+ case 'after':
131
+ insertBlock(
132
+ block,
133
+ relativePosition === 'after' ? blockIndex + 1 : blockIndex,
134
+ rootClientId, // Insert as a child of the current block's parent
135
+ false
136
+ );
137
+ break;
138
+
139
+ case 'first_child':
140
+ case 'last_child':
141
+ insertBlock(
142
+ block,
143
+ // TODO: It'd be great if insertBlock() would accept negative indices for insertion.
144
+ relativePosition === 'first_child' ? 0 : innerBlocksLength,
145
+ props.clientId, // Insert as a child of the current block.
146
+ false
147
+ );
148
+ break;
149
+ }
150
+ };
151
+
152
+ return (
153
+ <InspectorControls>
154
+ <PanelBody title={ __( 'Plugins' ) } initialOpen={ true }>
155
+ { Object.keys( groupedAutoInsertedBlocks ).map( ( vendor ) => {
156
+ return (
157
+ <Fragment key={ vendor }>
158
+ <h3>{ vendor }</h3>
159
+ { groupedAutoInsertedBlocks[ vendor ].map(
160
+ ( block ) => {
161
+ // TODO: Display block icon.
162
+ // <BlockIcon icon={ block.icon } />
163
+
164
+ const checked =
165
+ block.name in
166
+ autoInsertedBlockClientIds;
167
+
168
+ return (
169
+ <ToggleControl
170
+ checked={ checked }
171
+ key={ block.title }
172
+ label={ block.title }
173
+ onChange={ () => {
174
+ if ( ! checked ) {
175
+ // Create and insert block.
176
+ const relativePosition =
177
+ block.autoInsert[
178
+ props.blockName
179
+ ];
180
+ insertBlockIntoDesignatedLocation(
181
+ createBlock(
182
+ block.name
183
+ ),
184
+ relativePosition
185
+ );
186
+ return;
187
+ }
188
+
189
+ // Remove block.
190
+ const clientId =
191
+ autoInsertedBlockClientIds[
192
+ block.name
193
+ ];
194
+ removeBlock( clientId, false );
195
+ } }
196
+ />
197
+ );
198
+ }
199
+ ) }
200
+ </Fragment>
201
+ );
202
+ } ) }
203
+ </PanelBody>
204
+ </InspectorControls>
205
+ );
206
+ }
207
+
208
+ export const withAutoInsertingBlocks = createHigherOrderComponent(
209
+ ( BlockEdit ) => {
210
+ return ( props ) => {
211
+ const blockEdit = <BlockEdit key="edit" { ...props } />;
212
+ return (
213
+ <>
214
+ { blockEdit }
215
+ <AutoInsertingBlocksControl
216
+ blockName={ props.name }
217
+ clientId={ props.clientId }
218
+ />
219
+ </>
220
+ );
221
+ };
222
+ },
223
+ 'withAutoInsertingBlocks'
224
+ );
225
+
226
+ if ( window?.__experimentalAutoInsertingBlocks ) {
227
+ addFilter(
228
+ 'editor.BlockEdit',
229
+ 'core/auto-inserting-blocks/with-inspector-control',
230
+ withAutoInsertingBlocks
231
+ );
232
+ }
@@ -22,6 +22,7 @@ import './metadata';
22
22
  import './metadata-name';
23
23
  import './behaviors';
24
24
  import './custom-fields';
25
+ import './auto-inserting-blocks';
25
26
 
26
27
  export { useCustomSides } from './dimensions';
27
28
  export { useLayoutClasses, useLayoutStyles } from './layout';
@@ -1,68 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.usePreParsePatterns = usePreParsePatterns;
7
- var _data = require("@wordpress/data");
8
- var _element = require("@wordpress/element");
9
- var _store = require("../store");
10
- /**
11
- * WordPress dependencies
12
- */
13
-
14
- /**
15
- * Internal dependencies
16
- */
17
-
18
- const requestIdleCallback = (() => {
19
- if (typeof window === 'undefined') {
20
- return callback => {
21
- setTimeout(() => callback(Date.now()), 0);
22
- };
23
- }
24
- return window.requestIdleCallback || window.requestAnimationFrame;
25
- })();
26
- const cancelIdleCallback = (() => {
27
- if (typeof window === 'undefined') {
28
- return clearTimeout;
29
- }
30
- return window.cancelIdleCallback || window.cancelAnimationFrame;
31
- })();
32
- function usePreParsePatterns() {
33
- const {
34
- patterns,
35
- isPreviewMode
36
- } = (0, _data.useSelect)(_select => {
37
- const {
38
- __experimentalBlockPatterns,
39
- __unstableIsPreviewMode
40
- } = _select(_store.store).getSettings();
41
- return {
42
- patterns: __experimentalBlockPatterns,
43
- isPreviewMode: __unstableIsPreviewMode
44
- };
45
- }, []);
46
- (0, _element.useEffect)(() => {
47
- if (isPreviewMode) {
48
- return;
49
- }
50
- if (!patterns?.length) {
51
- return;
52
- }
53
- let handle;
54
- let index = -1;
55
- const callback = () => {
56
- index++;
57
- if (index >= patterns.length) {
58
- return;
59
- }
60
- (0, _data.select)(_store.store).__experimentalGetParsedPattern(patterns[index].name);
61
- handle = requestIdleCallback(callback);
62
- };
63
- handle = requestIdleCallback(callback);
64
- return () => cancelIdleCallback(handle);
65
- }, [patterns, isPreviewMode]);
66
- return null;
67
- }
68
- //# sourceMappingURL=pre-parse-patterns.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_data","require","_element","_store","requestIdleCallback","window","callback","setTimeout","Date","now","requestAnimationFrame","cancelIdleCallback","clearTimeout","cancelAnimationFrame","usePreParsePatterns","patterns","isPreviewMode","useSelect","_select","__experimentalBlockPatterns","__unstableIsPreviewMode","blockEditorStore","getSettings","useEffect","length","handle","index","select","__experimentalGetParsedPattern","name"],"sources":["@wordpress/block-editor/src/utils/pre-parse-patterns.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useSelect, select } from '@wordpress/data';\nimport { useEffect } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { store as blockEditorStore } from '../store';\n\nconst requestIdleCallback = ( () => {\n\tif ( typeof window === 'undefined' ) {\n\t\treturn ( callback ) => {\n\t\t\tsetTimeout( () => callback( Date.now() ), 0 );\n\t\t};\n\t}\n\n\treturn window.requestIdleCallback || window.requestAnimationFrame;\n} )();\n\nconst cancelIdleCallback = ( () => {\n\tif ( typeof window === 'undefined' ) {\n\t\treturn clearTimeout;\n\t}\n\n\treturn window.cancelIdleCallback || window.cancelAnimationFrame;\n} )();\n\nexport function usePreParsePatterns() {\n\tconst { patterns, isPreviewMode } = useSelect( ( _select ) => {\n\t\tconst { __experimentalBlockPatterns, __unstableIsPreviewMode } =\n\t\t\t_select( blockEditorStore ).getSettings();\n\t\treturn {\n\t\t\tpatterns: __experimentalBlockPatterns,\n\t\t\tisPreviewMode: __unstableIsPreviewMode,\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\tif ( isPreviewMode ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( ! patterns?.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet handle;\n\t\tlet index = -1;\n\n\t\tconst callback = () => {\n\t\t\tindex++;\n\t\t\tif ( index >= patterns.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tselect( blockEditorStore ).__experimentalGetParsedPattern(\n\t\t\t\tpatterns[ index ].name\n\t\t\t);\n\n\t\t\thandle = requestIdleCallback( callback );\n\t\t};\n\n\t\thandle = requestIdleCallback( callback );\n\t\treturn () => cancelIdleCallback( handle );\n\t}, [ patterns, isPreviewMode ] );\n\n\treturn null;\n}\n"],"mappings":";;;;;;AAGA,IAAAA,KAAA,GAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAKA,IAAAE,MAAA,GAAAF,OAAA;AATA;AACA;AACA;;AAIA;AACA;AACA;;AAGA,MAAMG,mBAAmB,GAAG,CAAE,MAAM;EACnC,IAAK,OAAOC,MAAM,KAAK,WAAW,EAAG;IACpC,OAASC,QAAQ,IAAM;MACtBC,UAAU,CAAE,MAAMD,QAAQ,CAAEE,IAAI,CAACC,GAAG,CAAC,CAAE,CAAC,EAAE,CAAE,CAAC;IAC9C,CAAC;EACF;EAEA,OAAOJ,MAAM,CAACD,mBAAmB,IAAIC,MAAM,CAACK,qBAAqB;AAClE,CAAC,EAAG,CAAC;AAEL,MAAMC,kBAAkB,GAAG,CAAE,MAAM;EAClC,IAAK,OAAON,MAAM,KAAK,WAAW,EAAG;IACpC,OAAOO,YAAY;EACpB;EAEA,OAAOP,MAAM,CAACM,kBAAkB,IAAIN,MAAM,CAACQ,oBAAoB;AAChE,CAAC,EAAG,CAAC;AAEE,SAASC,mBAAmBA,CAAA,EAAG;EACrC,MAAM;IAAEC,QAAQ;IAAEC;EAAc,CAAC,GAAG,IAAAC,eAAS,EAAIC,OAAO,IAAM;IAC7D,MAAM;MAAEC,2BAA2B;MAAEC;IAAwB,CAAC,GAC7DF,OAAO,CAAEG,YAAiB,CAAC,CAACC,WAAW,CAAC,CAAC;IAC1C,OAAO;MACNP,QAAQ,EAAEI,2BAA2B;MACrCH,aAAa,EAAEI;IAChB,CAAC;EACF,CAAC,EAAE,EAAG,CAAC;EAEP,IAAAG,kBAAS,EAAE,MAAM;IAChB,IAAKP,aAAa,EAAG;MACpB;IACD;IACA,IAAK,CAAED,QAAQ,EAAES,MAAM,EAAG;MACzB;IACD;IAEA,IAAIC,MAAM;IACV,IAAIC,KAAK,GAAG,CAAC,CAAC;IAEd,MAAMpB,QAAQ,GAAGA,CAAA,KAAM;MACtBoB,KAAK,EAAE;MACP,IAAKA,KAAK,IAAIX,QAAQ,CAACS,MAAM,EAAG;QAC/B;MACD;MAEA,IAAAG,YAAM,EAAEN,YAAiB,CAAC,CAACO,8BAA8B,CACxDb,QAAQ,CAAEW,KAAK,CAAE,CAACG,IACnB,CAAC;MAEDJ,MAAM,GAAGrB,mBAAmB,CAAEE,QAAS,CAAC;IACzC,CAAC;IAEDmB,MAAM,GAAGrB,mBAAmB,CAAEE,QAAS,CAAC;IACxC,OAAO,MAAMK,kBAAkB,CAAEc,MAAO,CAAC;EAC1C,CAAC,EAAE,CAAEV,QAAQ,EAAEC,aAAa,CAAG,CAAC;EAEhC,OAAO,IAAI;AACZ"}