diff --git a/docs/reference-guides/data/data-core-customize-widgets.md b/docs/reference-guides/data/data-core-customize-widgets.md
index 8796f4cfea5ddf..b0c0fc8818f327 100644
--- a/docs/reference-guides/data/data-core-customize-widgets.md
+++ b/docs/reference-guides/data/data-core-customize-widgets.md
@@ -78,6 +78,7 @@ _Parameters_
- _value_ `boolean|Object`: Whether the inserter should be opened (true) or closed (false). To specify an insertion point, use an object.
- _value.rootClientId_ `string`: The root client ID to insert at.
- _value.insertionIndex_ `number`: The index to insert at.
+- _value.initialTab_ `string`: The id of the tab to display first when the block editor inserter is opened. A category corresponds to one of the tab ids defined in packages/block-editor/src/components/inserter/tabs.js.
_Returns_
diff --git a/docs/reference-guides/data/data-core-edit-widgets.md b/docs/reference-guides/data/data-core-edit-widgets.md
index 2dde89bf69ad73..f5268963882bab 100644
--- a/docs/reference-guides/data/data-core-edit-widgets.md
+++ b/docs/reference-guides/data/data-core-edit-widgets.md
@@ -215,6 +215,7 @@ _Parameters_
- _value_ `boolean|Object`: Whether the inserter should be opened (true) or closed (false). To specify an insertion point, use an object.
- _value.rootClientId_ `string`: The root client ID to insert at.
- _value.insertionIndex_ `number`: The index to insert at.
+- _value.initialTab_ `string`: The id of the tab to display first when the block editor inserter is opened. A category corresponds to one of the tab ids defined in packages/block-editor/src/components/inserter/tabs.js.
_Returns_
diff --git a/docs/reference-guides/data/data-core-editor.md b/docs/reference-guides/data/data-core-editor.md
index be2276bbf03641..51126696942fad 100644
--- a/docs/reference-guides/data/data-core-editor.md
+++ b/docs/reference-guides/data/data-core-editor.md
@@ -1382,6 +1382,7 @@ _Parameters_
- _value_ `boolean|Object`: Whether the inserter should be opened (true) or closed (false). To specify an insertion point, use an object.
- _value.rootClientId_ `string`: The root client ID to insert at.
- _value.insertionIndex_ `number`: The index to insert at.
+- _value.initialTab_ `string`: The id of the tab to display first when the block editor inserter is opened. A category corresponds to one of the tab ids defined in packages/block-editor/src/components/inserter/tabs.js.
_Returns_
diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js
index 7690386764f6cc..f3cefd4741e9c4 100644
--- a/packages/block-editor/src/components/block-list/block.js
+++ b/packages/block-editor/src/components/block-list/block.js
@@ -616,6 +616,10 @@ function BlockListBlockProvider( props ) {
),
isEditingDisabled:
getBlockEditingMode( clientId ) === 'disabled',
+ hasEditableOutline:
+ getBlockEditingMode( clientId ) !== 'disabled' &&
+ getBlockEditingMode( getBlockRootClientId( clientId ) ) ===
+ 'disabled',
className: hasLightBlockWrapper
? attributes.className
: undefined,
@@ -660,6 +664,7 @@ function BlockListBlockProvider( props ) {
isBlockMovingMode,
canInsertMovingBlock,
isEditingDisabled,
+ hasEditableOutline,
className,
defaultClassName,
} = selectedProps;
@@ -695,6 +700,7 @@ function BlockListBlockProvider( props ) {
isBlockMovingMode,
canInsertMovingBlock,
isEditingDisabled,
+ hasEditableOutline,
isTemporarilyEditingAsBlocks,
defaultClassName,
mayDisplayControls,
diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss
index a650710bfb119a..d309340ecca30e 100644
--- a/packages/block-editor/src/components/block-list/content.scss
+++ b/packages/block-editor/src/components/block-list/content.scss
@@ -300,35 +300,30 @@ _::-webkit-full-page-media, _:future, :root .has-multi-selection .block-editor-b
}
}
-// Indicate which blocks are editable within a locked context.
-// 1. User must be hovering an editor with renderingMode = 'template-lock'; or...
-.is-template-locked:hover,
-// ...a container block.
-.block-editor-block-list__block:hover {
- // 2. Look for locked blocks; or...
- .block-editor-block-list__block.is-editing-disabled,
- // ...container blocks that have locked children.
- &:has(> .block-editor-block-list__block.is-editing-disabled) {
- // 3. Highlight any unlocked children of that locked block.
- & > .block-editor-block-list__block:not(.is-editing-disabled):not(.is-selected):not(.has-child-selected) {
- &::after {
- content: "";
- border-style: dotted;
- position: absolute;
- pointer-events: none;
- top: $border-width;
- left: $border-width;
- right: $border-width;
- bottom: $border-width;
- border: 1px dotted var(--wp-admin-theme-color);
- border-radius: $radius-block-ui - $border-width;
- }
+@keyframes block-editor-has-editable-outline__fade-out-animation {
+ from {
+ border-color: rgba(var(--wp-admin-theme-color--rgb), 1);
+ }
+ to {
+ border-color: rgba(var(--wp-admin-theme-color--rgb), 0);
+ }
+}
- &.is-hovered::after {
- background: rgba(var(--wp-admin-theme-color--rgb), 0.1);
- border: none;
- }
- }
+.is-root-container:not([inert]) .block-editor-block-list__block.has-editable-outline {
+ &::after {
+ content: "";
+ position: absolute;
+ pointer-events: none;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ border: 1px dotted rgba(var(--wp-admin-theme-color--rgb), 1);
+ border-radius: $radius-block-ui;
+ animation: block-editor-has-editable-outline__fade-out-animation 0.3s ease-out;
+ animation-delay: 3s;
+ animation-fill-mode: forwards;
+ @include reduce-motion("animation");
}
}
diff --git a/packages/block-editor/src/components/block-list/use-block-props/index.js b/packages/block-editor/src/components/block-list/use-block-props/index.js
index 9c7ae30b5997a5..7f3b9f1bb05e24 100644
--- a/packages/block-editor/src/components/block-list/use-block-props/index.js
+++ b/packages/block-editor/src/components/block-list/use-block-props/index.js
@@ -95,6 +95,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
isBlockMovingMode,
canInsertMovingBlock,
isEditingDisabled,
+ hasEditableOutline,
isTemporarilyEditingAsBlocks,
defaultClassName,
} = useContext( PrivateBlockContext );
@@ -152,6 +153,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
'is-block-moving-mode': isBlockMovingMode,
'can-insert-moving-block': canInsertMovingBlock,
'is-editing-disabled': isEditingDisabled,
+ 'has-editable-outline': hasEditableOutline,
'is-content-locked-temporarily-editing-as-blocks':
isTemporarilyEditingAsBlocks,
},
diff --git a/packages/block-editor/src/components/inserter/library.js b/packages/block-editor/src/components/inserter/library.js
index 7d462b343c310d..870bb7b91b29c3 100644
--- a/packages/block-editor/src/components/inserter/library.js
+++ b/packages/block-editor/src/components/inserter/library.js
@@ -21,6 +21,7 @@ function InserterLibrary(
showMostUsedBlocks = false,
__experimentalInsertionIndex,
__experimentalFilterValue,
+ initialInserterTab,
onSelect = noop,
shouldFocusBlock = false,
},
@@ -46,6 +47,7 @@ function InserterLibrary(
isAppender={ isAppender }
showInserterHelpPanel={ showInserterHelpPanel }
showMostUsedBlocks={ showMostUsedBlocks }
+ initialInserterTab={ initialInserterTab }
__experimentalInsertionIndex={ __experimentalInsertionIndex }
__experimentalFilterValue={ __experimentalFilterValue }
shouldFocusBlock={ shouldFocusBlock }
diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js
index 6a38e52cbffba1..4527318813a3da 100644
--- a/packages/block-editor/src/components/inserter/menu.js
+++ b/packages/block-editor/src/components/inserter/menu.js
@@ -45,6 +45,7 @@ function InserterMenu(
showMostUsedBlocks,
__experimentalFilterValue = '',
shouldFocusBlock = true,
+ initialInserterTab,
},
ref
) {
@@ -56,8 +57,9 @@ function InserterMenu(
const [ patternFilter, setPatternFilter ] = useState( 'all' );
const [ selectedMediaCategory, setSelectedMediaCategory ] =
useState( null );
- const [ selectedTab, setSelectedTab ] = useState( null );
-
+ const [ selectedTab, setSelectedTab ] = useState(
+ initialInserterTab || null
+ );
const [ destinationRootClientId, onInsertBlocks, onToggleInsertionPoint ] =
useInsertionPoint( {
rootClientId,
@@ -259,6 +261,7 @@ function InserterMenu(
showMedia={ showMedia }
onSelect={ handleSetSelectedTab }
tabsContents={ inserterTabsContents }
+ initialTabId={ initialInserterTab }
/>
) }
{ ! delayedFilterValue && ! showAsTabs && (
diff --git a/packages/block-editor/src/components/inserter/tabs.js b/packages/block-editor/src/components/inserter/tabs.js
index 4795c3ce4fdc24..1ea917596711ac 100644
--- a/packages/block-editor/src/components/inserter/tabs.js
+++ b/packages/block-editor/src/components/inserter/tabs.js
@@ -33,6 +33,7 @@ function InserterTabs( {
showMedia = false,
onSelect,
tabsContents,
+ initialTabId,
} ) {
const tabs = [
blocksTab,
@@ -40,9 +41,13 @@ function InserterTabs( {
showMedia && mediaTab,
].filter( Boolean );
+ initialTabId = !! tabs.find( ( { name } ) => initialTabId === name )
+ ? initialTabId
+ : 'blocks';
+
return (
-
+
{ tabs.map( ( tab ) => (
diff --git a/packages/block-editor/src/components/use-flash-editable-blocks/index.js b/packages/block-editor/src/components/use-flash-editable-blocks/index.js
new file mode 100644
index 00000000000000..56e4e64a17ec86
--- /dev/null
+++ b/packages/block-editor/src/components/use-flash-editable-blocks/index.js
@@ -0,0 +1,54 @@
+/**
+ * WordPress dependencies
+ */
+import { useRefEffect } from '@wordpress/compose';
+import { useSelect } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import { store as blockEditorStore } from '../../store';
+import { unlock } from '../../lock-unlock';
+
+export default function useFlashEditableBlocks( rootClientId = '' ) {
+ const { getEnabledClientIdsTree } = unlock( useSelect( blockEditorStore ) );
+
+ return useRefEffect( ( element ) => {
+ const flashEditableBlocks = () => {
+ getEnabledClientIdsTree( rootClientId ).forEach(
+ ( { clientId } ) => {
+ const blockElement = element.querySelector(
+ `[data-block="${ clientId }"]`
+ );
+ if ( ! blockElement ) {
+ return;
+ }
+ blockElement.classList.remove( 'has-editable-outline' );
+ // Force reflow to trigger the animation.
+ // eslint-disable-next-line no-unused-expressions
+ blockElement.offsetWidth;
+ blockElement.classList.add( 'has-editable-outline' );
+ }
+ );
+ };
+
+ const handleClick = ( event ) => {
+ const shouldFlash =
+ event.target === element ||
+ event.target.classList.contains( 'is-root-container' );
+ if ( ! shouldFlash ) {
+ return;
+ }
+ if ( event.defaultPrevented ) {
+ return;
+ }
+ event.preventDefault();
+ flashEditableBlocks();
+ };
+
+ element.addEventListener( 'click', handleClick );
+ return () => {
+ element.removeEventListener( 'click', handleClick );
+ };
+ } );
+}
diff --git a/packages/block-editor/src/private-apis.js b/packages/block-editor/src/private-apis.js
index 74bf4af421dfbb..555d0dd574fef7 100644
--- a/packages/block-editor/src/private-apis.js
+++ b/packages/block-editor/src/private-apis.js
@@ -24,6 +24,7 @@ import {
import { usesContextKey } from './components/rich-text/format-edit';
import { ExperimentalBlockCanvas } from './components/block-canvas';
import { getDuotoneFilter } from './components/duotone/utils';
+import useFlashEditableBlocks from './components/use-flash-editable-blocks';
/**
* Private @wordpress/block-editor APIs.
@@ -52,4 +53,5 @@ lock( privateApis, {
ReusableBlocksRenameHint,
useReusableBlocksRenameHint,
usesContextKey,
+ useFlashEditableBlocks,
} );
diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js
index cd04e09605ff40..8c2b70624ccf8f 100644
--- a/packages/block-library/src/block/edit.js
+++ b/packages/block-library/src/block/edit.js
@@ -35,7 +35,9 @@ import { parse, cloneBlock } from '@wordpress/blocks';
*/
import { unlock } from '../lock-unlock';
-const { useLayoutClasses } = unlock( blockEditorPrivateApis );
+const { useLayoutClasses, useFlashEditableBlocks } = unlock(
+ blockEditorPrivateApis
+);
const { PARTIAL_SYNCING_SUPPORTED_BLOCKS } = unlock( patternsPrivateApis );
function isPartiallySynced( block ) {
@@ -273,6 +275,7 @@ export default function ReusableBlockEdit( {
const layoutClasses = useLayoutClasses( { layout }, name );
const blockProps = useBlockProps( {
+ ref: useFlashEditableBlocks( patternClientId ),
className: classnames(
'block-library-block__reusable-block-container',
layout && layoutClasses,
diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss
index e3642868034a5a..7151051f545441 100644
--- a/packages/block-library/src/editor.scss
+++ b/packages/block-library/src/editor.scss
@@ -54,6 +54,7 @@
@import "./query-pagination-numbers/editor.scss";
@import "./post-featured-image/editor.scss";
@import "./post-comments-form/editor.scss";
+@import "./post-content/editor.scss";
@import "./editor-elements.scss";
diff --git a/packages/block-library/src/post-content/edit.js b/packages/block-library/src/post-content/edit.js
index 041a3b4fa02f61..ba3e8241c0cf57 100644
--- a/packages/block-library/src/post-content/edit.js
+++ b/packages/block-library/src/post-content/edit.js
@@ -8,13 +8,15 @@ import {
RecursionProvider,
useHasRecursion,
Warning,
+ InnerBlocks,
+ store as blockEditorStore,
} from '@wordpress/block-editor';
-import {
- useEntityProp,
- useEntityBlockEditor,
- store as coreStore,
-} from '@wordpress/core-data';
+import { useEntityProp, useEntityBlockEditor } from '@wordpress/core-data';
+import { Button } from '@wordpress/components';
+import { isUnmodifiedDefaultBlock } from '@wordpress/blocks';
+import { useMemo } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
+
/**
* Internal dependencies
*/
@@ -45,7 +47,31 @@ function ReadOnlyContent( {
);
}
-function EditableContent( { context = {} } ) {
+function InsertPatternButton( { rootClientId } ) {
+ const setIsInserterOpened = useSelect(
+ ( select ) =>
+ select( blockEditorStore ).getSettings()
+ .__experimentalSetIsInserterOpened,
+ []
+ );
+ return (
+
+ );
+}
+
+function EditableContent( { context = {}, clientId } ) {
const { postType, postId } = context;
const [ blocks, onInput, onChange ] = useEntityBlockEditor(
@@ -54,20 +80,20 @@ function EditableContent( { context = {} } ) {
{ id: postId }
);
- const entityRecord = useSelect(
- ( select ) => {
- return select( coreStore ).getEntityRecord(
- 'postType',
- postType,
- postId
- );
- },
- [ postType, postId ]
- );
+ const hasBlocks = !! blocks?.length;
+ const isDefaultBlock =
+ blocks?.length === 1 && isUnmodifiedDefaultBlock( blocks[ 0 ] );
+ const hasContent = hasBlocks && ! isDefaultBlock;
- const hasInnerBlocks = !! entityRecord?.content?.raw || blocks?.length;
-
- const initialInnerBlocks = [ [ 'core/paragraph' ] ];
+ const Appender = useMemo(
+ () => () => (
+ <>
+ { ! isDefaultBlock && }
+
+ >
+ ),
+ [ isDefaultBlock, clientId ]
+ );
const props = useInnerBlocksProps(
useBlockProps( { className: 'entry-content' } ),
@@ -75,7 +101,7 @@ function EditableContent( { context = {} } ) {
value: blocks,
onInput,
onChange,
- template: ! hasInnerBlocks ? initialInnerBlocks : undefined,
+ renderAppender: hasContent ? undefined : Appender,
}
);
return ;
@@ -141,6 +167,7 @@ function RecursionError() {
export default function PostContentEdit( {
context,
__unstableLayoutClassNames: layoutClassNames,
+ clientId,
} ) {
const { postId: contextPostId, postType: contextPostType } = context;
const hasAlreadyRendered = useHasRecursion( contextPostId );
@@ -155,6 +182,7 @@ export default function PostContentEdit( {
) : (
diff --git a/packages/block-library/src/post-content/editor.scss b/packages/block-library/src/post-content/editor.scss
new file mode 100644
index 00000000000000..98dc51093c9f49
--- /dev/null
+++ b/packages/block-library/src/post-content/editor.scss
@@ -0,0 +1,13 @@
+.wp-block-post-content {
+ .block-list-appender {
+ position: relative;
+ }
+
+ .block-editor-default-block-appender:not(.is-selected):not(.has-child-selected) {
+ display: block;
+ }
+}
+
+.wp-block-post-content__insert-pattern {
+ font-size: $editor-font-size;
+}
diff --git a/packages/customize-widgets/src/store/actions.js b/packages/customize-widgets/src/store/actions.js
index 8656ef8854c9f5..528f2c395d57e6 100644
--- a/packages/customize-widgets/src/store/actions.js
+++ b/packages/customize-widgets/src/store/actions.js
@@ -7,6 +7,8 @@
* use an object.
* @param {string} value.rootClientId The root client ID to insert at.
* @param {number} value.insertionIndex The index to insert at.
+ * @param {string} value.initialTab The id of the tab to display first when the block editor inserter is opened.
+ * A category corresponds to one of the tab ids defined in packages/block-editor/src/components/inserter/tabs.js.
*
* @example
* ```js
diff --git a/packages/edit-widgets/src/store/actions.js b/packages/edit-widgets/src/store/actions.js
index 8124ace66bdb3a..40d48bd85fab25 100644
--- a/packages/edit-widgets/src/store/actions.js
+++ b/packages/edit-widgets/src/store/actions.js
@@ -348,6 +348,8 @@ export function setIsWidgetAreaOpen( clientId, isOpen ) {
* use an object.
* @param {string} value.rootClientId The root client ID to insert at.
* @param {number} value.insertionIndex The index to insert at.
+ * @param {string} value.initialTab The id of the tab to display first when the block editor inserter is opened.
+ * A category corresponds to one of the tab ids defined in packages/block-editor/src/components/inserter/tabs.js.
*
* @return {Object} Action object.
*/
diff --git a/packages/editor/src/components/editor-canvas/edit-template-blocks-notification.js b/packages/editor/src/components/editor-canvas/edit-template-blocks-notification.js
index 566311e20cadc2..c4ac494ba3dbda 100644
--- a/packages/editor/src/components/editor-canvas/edit-template-blocks-notification.js
+++ b/packages/editor/src/components/editor-canvas/edit-template-blocks-notification.js
@@ -27,10 +27,6 @@ import { store as editorStore } from '../../store';
* editor iframe canvas.
*/
export default function EditTemplateBlocksNotification( { contentRef } ) {
- const renderingMode = useSelect(
- ( select ) => select( editorStore ).getRenderingMode(),
- []
- );
const { getNotices } = useSelect( noticesStore );
const { createInfoNotice, removeNotice } = useDispatch( noticesStore );
@@ -42,18 +38,17 @@ export default function EditTemplateBlocksNotification( { contentRef } ) {
useEffect( () => {
const handleClick = async ( event ) => {
- if ( renderingMode !== 'template-locked' ) {
- return;
- }
if ( ! event.target.classList.contains( 'is-root-container' ) ) {
return;
}
+
const isNoticeAlreadyShowing = getNotices().some(
( notice ) => notice.id === lastNoticeId.current
);
if ( isNoticeAlreadyShowing ) {
return;
}
+
const { notice } = await createInfoNotice(
__( 'Edit your template to edit this block.' ),
{
@@ -71,9 +66,6 @@ export default function EditTemplateBlocksNotification( { contentRef } ) {
};
const handleDblClick = ( event ) => {
- if ( renderingMode !== 'template-locked' ) {
- return;
- }
if ( ! event.target.classList.contains( 'is-root-container' ) ) {
return;
}
@@ -90,7 +82,7 @@ export default function EditTemplateBlocksNotification( { contentRef } ) {
canvas?.removeEventListener( 'click', handleClick );
canvas?.removeEventListener( 'dblclick', handleDblClick );
};
- }, [ lastNoticeId, renderingMode, contentRef.current ] );
+ }, [ lastNoticeId, contentRef.current ] );
return (
{};
@@ -287,9 +288,11 @@ function EditorCanvas( {
const localRef = useRef();
const typewriterRef = useTypewriter();
+ const flashEditableBlocksRef = useFlashEditableBlocks();
const contentRef = useMergeRefs( [
localRef,
renderingMode === 'post-only' ? typewriterRef : noop,
+ renderingMode === 'template-locked' ? flashEditableBlocksRef : noop,
] );
return (
@@ -364,8 +367,7 @@ function EditorCanvas( {
'is-' + deviceType.toLowerCase() + '-preview',
renderingMode !== 'post-only'
? 'wp-site-blocks'
- : `${ blockListLayoutClass } wp-block-post-content`, // Ensure root level blocks receive default/flow blockGap styling rules.
- renderingMode !== 'all' && 'is-' + renderingMode
+ : `${ blockListLayoutClass } wp-block-post-content` // Ensure root level blocks receive default/flow blockGap styling rules.
) }
layout={ blockListLayout }
dropZoneElement={
@@ -377,7 +379,9 @@ function EditorCanvas( {
}
renderAppender={ renderAppender }
/>
-
+ { renderingMode === 'template-locked' && (
+
+ ) }
{ children }
diff --git a/packages/editor/src/components/inserter-sidebar/index.js b/packages/editor/src/components/inserter-sidebar/index.js
index 7db4335309935a..783294dddee7d1 100644
--- a/packages/editor/src/components/inserter-sidebar/index.js
+++ b/packages/editor/src/components/inserter-sidebar/index.js
@@ -20,14 +20,18 @@ import { unlock } from '../../lock-unlock';
import { store as editorStore } from '../../store';
export default function InserterSidebar() {
- const { insertionPoint, showMostUsedBlocks } = useSelect( ( select ) => {
- const { getInsertionPoint } = unlock( select( editorStore ) );
- const { get } = select( preferencesStore );
- return {
- insertionPoint: getInsertionPoint(),
- showMostUsedBlocks: get( 'core', 'mostUsedBlocks' ),
- };
- }, [] );
+ const { insertionPoint, initialInserterTab, showMostUsedBlocks } =
+ useSelect( ( select ) => {
+ const { getInsertionPoint, getInserterInitialTab } = unlock(
+ select( editorStore )
+ );
+ const { get } = select( preferencesStore );
+ return {
+ insertionPoint: getInsertionPoint(),
+ initialInserterTab: getInserterInitialTab(),
+ showMostUsedBlocks: get( 'core', 'mostUsedBlocks' ),
+ };
+ }, [] );
const { setIsInserterOpened } = useDispatch( editorStore );
const isMobileViewport = useViewportMatch( 'medium', '<' );
@@ -64,6 +68,7 @@ export default function InserterSidebar() {
__experimentalInsertionIndex={
insertionPoint.insertionIndex
}
+ initialInserterTab={ initialInserterTab }
__experimentalFilterValue={ insertionPoint.filterValue }
ref={ libraryRef }
/>
diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js
index a0330321bac8f7..9f0bf4700c4715 100644
--- a/packages/editor/src/store/actions.js
+++ b/packages/editor/src/store/actions.js
@@ -697,6 +697,8 @@ export function removeEditorPanel( panelName ) {
* use an object.
* @param {string} value.rootClientId The root client ID to insert at.
* @param {number} value.insertionIndex The index to insert at.
+ * @param {string} value.initialTab The id of the tab to display first when the block editor inserter is opened.
+ * A category corresponds to one of the tab ids defined in packages/block-editor/src/components/inserter/tabs.js.
*
* @return {Object} Action object.
*/
diff --git a/packages/editor/src/store/private-selectors.js b/packages/editor/src/store/private-selectors.js
index e276859f884038..f3dd3f4404e24e 100644
--- a/packages/editor/src/store/private-selectors.js
+++ b/packages/editor/src/store/private-selectors.js
@@ -25,7 +25,11 @@ const EMPTY_INSERTION_POINT = {
export const getInsertionPoint = createRegistrySelector(
( select ) => ( state ) => {
if ( typeof state.blockInserterPanel === 'object' ) {
- return state.blockInserterPanel;
+ return {
+ rootClientId: state.blockInserterPanel?.rootClientId,
+ insertionIndex: state.blockInserterPanel?.insertionIndex,
+ filterValue: state.blockInserterPanel?.filterValue,
+ };
}
if ( getRenderingMode( state ) === 'template-locked' ) {
@@ -46,6 +50,21 @@ export const getInsertionPoint = createRegistrySelector(
}
);
+/**
+ * Get the initial tab id for the inserter.
+ * A category corresponds to one of the tab ids defined in packages/block-editor/src/components/inserter/tabs.js.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {string} The initial tab category to open when the inserter is opened.
+ */
+export const getInserterInitialTab = createRegistrySelector(
+ () => ( state ) =>
+ typeof state.blockInserterPanel === 'object'
+ ? state.blockInserterPanel?.initialTab
+ : null
+);
+
export function getListViewToggleRef( state ) {
return state.listViewToggleRef;
}