diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index bf14e516719958..97011bcce91059 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -160,22 +160,16 @@ _Returns_ # **getBlockInsertionPoint** -Returns the insertion point. This will be: - -1. The insertion point manually set using setInsertionPoint() or - showInsertionPoint(); or -2. The point after the current block selection, if there is a selection; or -3. The point at the end of the block list. - -Components like will default to inserting blocks at this point. +Returns the insertion point, the index at which the new inserted block would +be placed. Defaults to the last index. _Parameters_ -- _state_ `Object`: Global application state. +- _state_ `Object`: Editor state. _Returns_ -- `Object`: Insertion point object with `rootClientId` and `index`. +- `Object`: Insertion point object with `rootClientId`, `index`. # **getBlockListSettings** @@ -853,8 +847,7 @@ _Returns_ # **isBlockInsertionPointVisible** -Whether or not the insertion point should be shown to users. This is set -using showInsertionPoint() or hideInsertionPoint(). +Returns true if we should show the block insertion point. _Parameters_ @@ -862,7 +855,7 @@ _Parameters_ _Returns_ -- `?boolean`: Whether the insertion point should be shown. +- `?boolean`: Whether the insertion point is visible or not. # **isBlockMultiSelected** @@ -1090,7 +1083,7 @@ _Parameters_ # **hideInsertionPoint** -Hides the insertion point for users. +Returns an action object hiding the insertion point. _Returns_ @@ -1406,14 +1399,13 @@ _Returns_ # **showInsertionPoint** -Sets the insertion point and shows it to users. - -Components like will default to inserting blocks at this point. +Returns an action object used in signalling that the insertion point should +be shown. _Parameters_ -- _rootClientId_ `?string`: Root client ID of block list in which to insert. Use `undefined` for the root block list. -- _index_ `number`: Index at which block should be inserted. +- _rootClientId_ `?string`: Optional root client ID of block list on which to insert. +- _index_ `?number`: Index at which block should be inserted. _Returns_ diff --git a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js index 02ef1c0571107b..fec66c1ef0913d 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js +++ b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js @@ -38,7 +38,7 @@ import { store as blockEditorStore } from '../../../store'; * @return {Array} Insertion Point State (rootClientID, onInsertBlocks and onToggle). */ function useInsertionPoint( { - rootClientId, + rootClientId = '', insertionIndex, clientId, isAppender, @@ -49,40 +49,38 @@ function useInsertionPoint( { const { destinationRootClientId, destinationIndex } = useSelect( ( select ) => { const { + getSelectedBlockClientId, + getBlockRootClientId, getBlockIndex, getBlockOrder, - getBlockInsertionPoint, } = select( blockEditorStore ); - - let _destinationRootClientId, _destinationIndex; - - if ( rootClientId || insertionIndex || clientId || isAppender ) { - // If any of these arguments are set, we're in "manual mode" - // meaning the insertion point is set by the caller. - - _destinationRootClientId = rootClientId; - - if ( insertionIndex ) { - // Insert into a specific index. - _destinationIndex = insertionIndex; - } else if ( clientId ) { - // Insert after a specific client ID. - _destinationIndex = getBlockIndex( - clientId, - _destinationRootClientId - ); - } else { - // Insert at the end of the list. - _destinationIndex = getBlockOrder( + const selectedBlockClientId = getSelectedBlockClientId(); + + let _destinationRootClientId = rootClientId; + let _destinationIndex; + + if ( insertionIndex ) { + // Insert into a specific index. + _destinationIndex = insertionIndex; + } else if ( clientId ) { + // Insert after a specific client ID. + _destinationIndex = getBlockIndex( + clientId, + _destinationRootClientId + ); + } else if ( ! isAppender && selectedBlockClientId ) { + _destinationRootClientId = getBlockRootClientId( + selectedBlockClientId + ); + _destinationIndex = + getBlockIndex( + selectedBlockClientId, _destinationRootClientId - ).length; - } + ) + 1; } else { - // Otherwise, we're in "auto mode" where the insertion point is - // decided by getBlockInsertionPoint(). - const insertionPoint = getBlockInsertionPoint(); - _destinationRootClientId = insertionPoint.rootClientId; - _destinationIndex = insertionPoint.index; + // Insert at the end of the list. + _destinationIndex = getBlockOrder( _destinationRootClientId ) + .length; } return { diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js index d18973d1d37dbb..13dda883f5b94a 100644 --- a/packages/block-editor/src/components/inserter/menu.js +++ b/packages/block-editor/src/components/inserter/menu.js @@ -190,6 +190,9 @@ function InserterMenu( { rootClientId={ rootClientId } clientId={ clientId } isAppender={ isAppender } + __experimentalInsertionIndex={ + __experimentalInsertionIndex + } showBlockDirectory shouldFocusBlock={ shouldFocusBlock } /> diff --git a/packages/block-editor/src/components/inserter/quick-inserter.js b/packages/block-editor/src/components/inserter/quick-inserter.js index d880b2b4480673..ca4ff4c2fa2743 100644 --- a/packages/block-editor/src/components/inserter/quick-inserter.js +++ b/packages/block-editor/src/components/inserter/quick-inserter.js @@ -9,7 +9,7 @@ import classnames from 'classnames'; import { useState, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Button } from '@wordpress/components'; -import { useSelect, useDispatch } from '@wordpress/data'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies @@ -52,13 +52,16 @@ export default function QuickInserter( { ( showPatterns && patterns.length > SEARCH_THRESHOLD ) || blockTypes.length > SEARCH_THRESHOLD; - const { setInserterIsOpened, blockIndex } = useSelect( + const { setInserterIsOpened, insertionIndex } = useSelect( ( select ) => { - const { getSettings, getBlockIndex } = select( blockEditorStore ); + const { getSettings, getBlockIndex, getBlockCount } = select( + blockEditorStore + ); + const index = getBlockIndex( clientId, rootClientId ); return { setInserterIsOpened: getSettings() .__experimentalSetIsInserterOpened, - blockIndex: getBlockIndex( clientId, rootClientId ), + insertionIndex: index === -1 ? getBlockCount() : index, }; }, [ clientId, rootClientId ] @@ -70,13 +73,10 @@ export default function QuickInserter( { } }, [ setInserterIsOpened ] ); - const { __unstableSetInsertionPoint } = useDispatch( blockEditorStore ); - // When clicking Browse All select the appropriate block so as // the insertion point can work as expected const onBrowseAll = () => { - __unstableSetInsertionPoint( rootClientId, blockIndex ); - setInserterIsOpened( true ); + setInserterIsOpened( { rootClientId, insertionIndex } ); }; return ( diff --git a/packages/block-editor/src/components/inserter/search-results.js b/packages/block-editor/src/components/inserter/search-results.js index 03bf7b7c2da998..b29015ee763dc2 100644 --- a/packages/block-editor/src/components/inserter/search-results.js +++ b/packages/block-editor/src/components/inserter/search-results.js @@ -33,6 +33,7 @@ function InserterSearchResults( { rootClientId, clientId, isAppender, + __experimentalInsertionIndex, maxBlockPatterns, maxBlockTypes, showBlockDirectory = false, @@ -46,6 +47,7 @@ function InserterSearchResults( { rootClientId, clientId, isAppender, + insertionIndex: __experimentalInsertionIndex, shouldFocusBlock, } ); const [ diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index b0144c19e4f476..823d1f6ba5c61b 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -620,34 +620,12 @@ export function* insertBlocks( } /** - * Sets the insertion point without showing it to users. + * Returns an action object used in signalling that the insertion point should + * be shown. * - * Components like will default to inserting blocks at this point. - * - * @param {?string} rootClientId Root client ID of block list in which to - * insert. Use `undefined` for the root block - * list. - * @param {number} index Index at which block should be inserted. - * - * @return {Object} Action object. - */ -export function __unstableSetInsertionPoint( rootClientId, index ) { - return { - type: 'SET_INSERTION_POINT', - rootClientId, - index, - }; -} - -/** - * Sets the insertion point and shows it to users. - * - * Components like will default to inserting blocks at this point. - * - * @param {?string} rootClientId Root client ID of block list in which to - * insert. Use `undefined` for the root block - * list. - * @param {number} index Index at which block should be inserted. + * @param {?string} rootClientId Optional root client ID of block list on + * which to insert. + * @param {?number} index Index at which block should be inserted. * * @return {Object} Action object. */ @@ -660,7 +638,7 @@ export function showInsertionPoint( rootClientId, index ) { } /** - * Hides the insertion point for users. + * Returns an action object hiding the insertion point. * * @return {Object} Action object. */ diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index b4349d621f7764..488272c145b277 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1393,32 +1393,9 @@ export function blocksMode( state = {}, action ) { } /** - * A helper for resetting the insertion point state. - * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. - * @param {*} defaultValue The default value for the reducer. - * - * @return {*} Either the default value if a reset is required, or the state. - */ -function resetInsertionPoint( state, action, defaultValue ) { - switch ( action.type ) { - case 'CLEAR_SELECTED_BLOCK': - case 'SELECT_BLOCK': - case 'SELECTION_CHANGE': - case 'REPLACE_INNER_BLOCKS': - case 'INSERT_BLOCKS': - case 'REMOVE_BLOCKS': - case 'REPLACE_BLOCKS': - return defaultValue; - } - - return state; -} - -/** - * Reducer returning the insertion point position, consisting of the - * rootClientId and an index. + * Reducer returning the block insertion point visibility, either null if there + * is not an explicit insertion point assigned, or an object of its `index` and + * `rootClientId`. * * @param {Object} state Current state. * @param {Object} action Dispatched action. @@ -1427,33 +1404,15 @@ function resetInsertionPoint( state, action, defaultValue ) { */ export function insertionPoint( state = null, action ) { switch ( action.type ) { - case 'SET_INSERTION_POINT': - case 'SHOW_INSERTION_POINT': { + case 'SHOW_INSERTION_POINT': const { rootClientId, index } = action; return { rootClientId, index }; - } - } - - return resetInsertionPoint( state, action, null ); -} -/** - * Reducer returning the visibility of the insertion point. - * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. - * - * @return {Object} Updated state. - */ -export function insertionPointVisibility( state = false, action ) { - switch ( action.type ) { - case 'SHOW_INSERTION_POINT': - return true; case 'HIDE_INSERTION_POINT': - return false; + return null; } - return resetInsertionPoint( state, action, false ); + return state; } /** @@ -1764,7 +1723,6 @@ export default combineReducers( { blocksMode, blockListSettings, insertionPoint, - insertionPointVisibility, template, settings, preferences, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 7d8b9d0b4cca80..564f6bd1a89709 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1177,18 +1177,12 @@ export function isCaretWithinFormattedText( state ) { } /** - * Returns the insertion point. This will be: + * Returns the insertion point, the index at which the new inserted block would + * be placed. Defaults to the last index. * - * 1) The insertion point manually set using setInsertionPoint() or - * showInsertionPoint(); or - * 2) The point after the current block selection, if there is a selection; or - * 3) The point at the end of the block list. - * - * Components like will default to inserting blocks at this point. - * - * @param {Object} state Global application state. + * @param {Object} state Editor state. * - * @return {Object} Insertion point object with `rootClientId` and `index`. + * @return {Object} Insertion point object with `rootClientId`, `index`. */ export function getBlockInsertionPoint( state ) { let rootClientId, index; @@ -1214,15 +1208,14 @@ export function getBlockInsertionPoint( state ) { } /** - * Whether or not the insertion point should be shown to users. This is set - * using showInsertionPoint() or hideInsertionPoint(). + * Returns true if we should show the block insertion point. * * @param {Object} state Global application state. * - * @return {?boolean} Whether the insertion point should be shown. + * @return {?boolean} Whether the insertion point is visible or not. */ export function isBlockInsertionPointVisible( state ) { - return state.insertionPointVisibility; + return state.insertionPoint !== null; } /** diff --git a/packages/block-editor/src/store/test/actions.js b/packages/block-editor/src/store/test/actions.js index bbb47619ac28c8..6433f15e6523e7 100644 --- a/packages/block-editor/src/store/test/actions.js +++ b/packages/block-editor/src/store/test/actions.js @@ -42,7 +42,6 @@ const { resetBlocks, selectBlock, selectPreviousBlock, - __unstableSetInsertionPoint, showInsertionPoint, startMultiSelect, startTyping, @@ -741,31 +740,11 @@ describe( 'actions', () => { } ); } ); - describe( '__unstableSetInsertionPoint', () => { - it( 'should return the SET_INSERTION_POINT action', () => { - expect( __unstableSetInsertionPoint() ).toEqual( { - type: 'SET_INSERTION_POINT', - } ); - expect( __unstableSetInsertionPoint( 'rootClientId', 2 ) ).toEqual( - { - type: 'SET_INSERTION_POINT', - rootClientId: 'rootClientId', - index: 2, - } - ); - } ); - } ); - describe( 'showInsertionPoint', () => { it( 'should return the SHOW_INSERTION_POINT action', () => { expect( showInsertionPoint() ).toEqual( { type: 'SHOW_INSERTION_POINT', } ); - expect( showInsertionPoint( 'rootClientId', 2 ) ).toEqual( { - type: 'SHOW_INSERTION_POINT', - rootClientId: 'rootClientId', - index: 2, - } ); } ); } ); diff --git a/packages/block-editor/src/store/test/reducer.js b/packages/block-editor/src/store/test/reducer.js index 13e6fe57ae9809..b4ad1c12ec1980 100644 --- a/packages/block-editor/src/store/test/reducer.js +++ b/packages/block-editor/src/store/test/reducer.js @@ -29,7 +29,6 @@ import { preferences, blocksMode, insertionPoint, - insertionPointVisibility, template, blockListSettings, lastBlockAttributesChange, @@ -2041,82 +2040,35 @@ describe( 'state', () => { } ); describe( 'insertionPoint', () => { - it( 'defaults to `null`', () => { + it( 'should default to null', () => { const state = insertionPoint( undefined, {} ); - expect( state ).toEqual( null ); + expect( state ).toBe( null ); } ); - it.each( [ 'SET_INSERTION_POINT', 'SHOW_INSERTION_POINT' ] )( - 'sets the insertion point on %s', - ( type ) => { - const original = deepFreeze( { - rootClientId: 'clientId1', - index: 0, - } ); - - const expectedNewState = { - rootClientId: 'clientId2', - index: 1, - }; - - const state = insertionPoint( original, { - type, - ...expectedNewState, - } ); - - expect( state ).toEqual( expectedNewState ); - } - ); - - it.each( [ - 'CLEAR_SELECTED_BLOCK', - 'SELECT_BLOCK', - 'REPLACE_INNER_BLOCKS', - 'INSERT_BLOCKS', - 'REMOVE_BLOCKS', - 'REPLACE_BLOCKS', - ] )( 'resets the insertion point to `null` on %s', ( type ) => { - const original = deepFreeze( { + it( 'should set insertion point', () => { + const state = insertionPoint( null, { + type: 'SHOW_INSERTION_POINT', rootClientId: 'clientId1', index: 0, } ); - const state = insertionPoint( original, { - type, - } ); - - expect( state ).toEqual( null ); - } ); - } ); - - describe( 'insertionPointVisibility', () => { - it( 'defaults to `false`', () => { - const state = insertionPointVisibility( undefined, {} ); - expect( state ).toBe( false ); - } ); - it( 'shows the insertion point', () => { - const state = insertionPointVisibility( false, { - type: 'SHOW_INSERTION_POINT', + expect( state ).toEqual( { + rootClientId: 'clientId1', + index: 0, } ); - - expect( state ).toBe( true ); } ); - it.each( [ - 'HIDE_INSERTION_POINT', - 'CLEAR_SELECTED_BLOCK', - 'SELECT_BLOCK', - 'REPLACE_INNER_BLOCKS', - 'INSERT_BLOCKS', - 'REMOVE_BLOCKS', - 'REPLACE_BLOCKS', - ] )( 'sets the insertion point on %s to `false`', ( type ) => { - const state = insertionPointVisibility( true, { - type, + it( 'should clear the insertion point', () => { + const original = deepFreeze( { + rootClientId: 'clientId1', + index: 0, + } ); + const state = insertionPoint( original, { + type: 'HIDE_INSERTION_POINT', } ); - expect( state ).toBe( false ); + expect( state ).toBe( null ); } ); } ); diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index 78f1342fa4ce64..5339ffb49943c2 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -2246,17 +2246,20 @@ describe( 'selectors', () => { } ); describe( 'isBlockInsertionPointVisible', () => { - it( 'should return false if insertion point is set to not show', () => { + it( 'should return false if no assigned insertion point', () => { const state = { - insertionPointVisibility: false, + insertionPoint: null, }; expect( isBlockInsertionPointVisible( state ) ).toBe( false ); } ); - it( 'should return true if insertion point is set to show', () => { + it( 'should return true if assigned insertion point', () => { const state = { - insertionPointVisibility: true, + insertionPoint: { + rootClientId: undefined, + index: 5, + }, }; expect( isBlockInsertionPointVisible( state ) ).toBe( true ); diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index 3bbee2c99851bf..e83613fccb0a29 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -86,6 +86,7 @@ function Layout( { styles } ) { hasBlockSelected, showMostUsedBlocks, isInserterOpened, + insertionPoint, showIconLabels, hasReducedUI, showBlockBreadcrumbs, @@ -107,6 +108,9 @@ function Layout( { styles } ) { 'mostUsedBlocks' ), isInserterOpened: select( editPostStore ).isInserterOpened(), + insertionPoint: select( + editPostStore + ).__experimentalGetInsertionPoint(), mode: select( editPostStore ).getEditorMode(), isRichEditingEnabled: editorSettings.richEditingEnabled, hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), @@ -212,6 +216,10 @@ function Layout( { styles } ) { showMostUsedBlocks={ showMostUsedBlocks } showInserterHelpPanel shouldFocusBlock={ isMobileViewport } + rootClientId={ insertionPoint.rootClientId } + __experimentalInsertionIndex={ + insertionPoint.insertionIndex + } /> diff --git a/packages/edit-post/src/store/actions.js b/packages/edit-post/src/store/actions.js index e8f4d1ab12d515..a7a55f7c352c8b 100644 --- a/packages/edit-post/src/store/actions.js +++ b/packages/edit-post/src/store/actions.js @@ -416,7 +416,13 @@ export function __experimentalSetPreviewDeviceType( deviceType ) { /** * Returns an action object used to open/close the inserter. * - * @param {boolean} value A boolean representing whether the inserter should be opened or closed. + * @param {boolean|Object} value Whether the inserter should be + * opened (true) or closed (false). + * To specify an insertion point, + * use an object. + * @param {string} value.rootClientId The root client ID to insert at. + * @param {number} value.insertionIndex The index to insert at. + * * @return {Object} Action object. */ export function setIsInserterOpened( value ) { diff --git a/packages/edit-post/src/store/reducer.js b/packages/edit-post/src/store/reducer.js index 1f1e762f728135..318dcf4c53b1c8 100644 --- a/packages/edit-post/src/store/reducer.js +++ b/packages/edit-post/src/store/reducer.js @@ -241,10 +241,10 @@ export function deviceType( state = 'Desktop', action ) { /** * Reducer tracking whether the inserter is open. * - * @param {boolean} state - * @param {Object} action + * @param {boolean|Object} state + * @param {Object} action */ -function isInserterOpened( state = false, action ) { +function blockInserterPanel( state = false, action ) { switch ( action.type ) { case 'SET_IS_INSERTER_OPENED': return action.value; @@ -278,6 +278,6 @@ export default combineReducers( { publishSidebarActive, removedPanels, deviceType, - isInserterOpened, + blockInserterPanel, isEditingTemplate, } ); diff --git a/packages/edit-post/src/store/selectors.js b/packages/edit-post/src/store/selectors.js index b734484b213953..eece40da2f56c0 100644 --- a/packages/edit-post/src/store/selectors.js +++ b/packages/edit-post/src/store/selectors.js @@ -324,7 +324,19 @@ export function __experimentalGetPreviewDeviceType( state ) { * @return {boolean} Whether the inserter is opened. */ export function isInserterOpened( state ) { - return state.isInserterOpened; + return !! state.blockInserterPanel; +} + +/** + * Get the insertion point for the inserter. + * + * @param {Object} state Global application state. + * + * @return {Object} The root client ID and index to insert at. + */ +export function __experimentalGetInsertionPoint( state ) { + const { rootClientId, insertionIndex } = state.blockInserterPanel; + return { rootClientId, insertionIndex }; } /** diff --git a/packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js b/packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js index 92381ff805983c..792a16bcb1aa93 100644 --- a/packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js +++ b/packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { useDispatch } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; import { Button } from '@wordpress/components'; import { __experimentalLibrary as Library } from '@wordpress/block-editor'; import { close } from '@wordpress/icons'; @@ -17,6 +17,10 @@ import { store as editSiteStore } from '../../store'; export default function InserterSidebar() { const { setIsInserterOpened } = useDispatch( editSiteStore ); + const insertionPoint = useSelect( + ( select ) => select( editSiteStore ).__experimentalGetInsertionPoint(), + [] + ); const isMobile = useViewportMatch( 'medium', '<' ); const [ inserterDialogRef, inserterDialogProps ] = useDialog( { @@ -36,7 +40,14 @@ export default function InserterSidebar() { />
- +
); diff --git a/packages/edit-site/src/store/actions.js b/packages/edit-site/src/store/actions.js index 4bad708c4f9131..17a0965ee7a53b 100644 --- a/packages/edit-site/src/store/actions.js +++ b/packages/edit-site/src/store/actions.js @@ -264,15 +264,21 @@ export function setIsNavigationPanelOpened( isOpen ) { } /** - * Sets whether the block inserter panel should be open. + * Returns an action object used to open/close the inserter. * - * @param {boolean} isOpen If true, opens the inserter. If false, closes it. It - * does not toggle the state, but sets it directly. + * @param {boolean|Object} value Whether the inserter should be + * opened (true) or closed (false). + * To specify an insertion point, + * use an object. + * @param {string} value.rootClientId The root client ID to insert at. + * @param {number} value.insertionIndex The index to insert at. + * + * @return {Object} Action object. */ -export function setIsInserterOpened( isOpen ) { +export function setIsInserterOpened( value ) { return { type: 'SET_IS_INSERTER_OPENED', - isOpen, + value, }; } diff --git a/packages/edit-site/src/store/reducer.js b/packages/edit-site/src/store/reducer.js index 0e6c44f7bea240..01423f4f082d2b 100644 --- a/packages/edit-site/src/store/reducer.js +++ b/packages/edit-site/src/store/reducer.js @@ -145,13 +145,18 @@ export function navigationPanel( menu: ! action.isOpen ? MENU_ROOT : state.menu, // Set menu to root when closing panel. isOpen: action.isOpen, }; - case 'SET_IS_INSERTER_OPENED': case 'SET_IS_LIST_VIEW_OPENED': return { ...state, menu: state.isOpen && action.isOpen ? MENU_ROOT : state.menu, // Set menu to root when closing panel. isOpen: action.isOpen ? false : state.isOpen, }; + case 'SET_IS_INSERTER_OPENED': + return { + ...state, + menu: state.isOpen && action.value ? MENU_ROOT : state.menu, // Set menu to root when closing panel. + isOpen: action.value ? false : state.isOpen, + }; } return state; } @@ -162,8 +167,8 @@ export function navigationPanel( * Note: this reducer interacts with the navigation and list view panels reducers * to make sure that only one of the three panels is open at the same time. * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. + * @param {boolean|Object} state Current state. + * @param {Object} action Dispatched action. */ export function blockInserterPanel( state = false, action ) { switch ( action.type ) { @@ -173,7 +178,7 @@ export function blockInserterPanel( state = false, action ) { case 'SET_IS_LIST_VIEW_OPENED': return action.isOpen ? false : state; case 'SET_IS_INSERTER_OPENED': - return action.isOpen; + return action.value; } return state; } @@ -192,8 +197,9 @@ export function listViewPanel( state = false, action ) { case 'OPEN_NAVIGATION_PANEL_TO_MENU': return false; case 'SET_IS_NAVIGATION_PANEL_OPENED': - case 'SET_IS_INSERTER_OPENED': return action.isOpen ? false : state; + case 'SET_IS_INSERTER_OPENED': + return action.value ? false : state; case 'SET_IS_LIST_VIEW_OPENED': return action.isOpen; } diff --git a/packages/edit-site/src/store/selectors.js b/packages/edit-site/src/store/selectors.js index 8543eb233fe035..16f1a711cd2331 100644 --- a/packages/edit-site/src/store/selectors.js +++ b/packages/edit-site/src/store/selectors.js @@ -231,7 +231,19 @@ export function isNavigationOpened( state ) { * @return {boolean} True if the inserter panel should be open; false if closed. */ export function isInserterOpened( state ) { - return state.blockInserterPanel; + return !! state.blockInserterPanel; +} + +/** + * Get the insertion point for the inserter. + * + * @param {Object} state Global application state. + * + * @return {Object} The root client ID and index to insert at. + */ +export function __experimentalGetInsertionPoint( state ) { + const { rootClientId, insertionIndex } = state.blockInserterPanel; + return { rootClientId, insertionIndex }; } /** diff --git a/packages/edit-widgets/src/store/actions.js b/packages/edit-widgets/src/store/actions.js index 9c5b86924e2908..5a9d7d25e2ebc4 100644 --- a/packages/edit-widgets/src/store/actions.js +++ b/packages/edit-widgets/src/store/actions.js @@ -299,7 +299,13 @@ export function setIsWidgetAreaOpen( clientId, isOpen ) { /** * Returns an action object used to open/close the inserter. * - * @param {boolean} value A boolean representing whether the inserter should be opened or closed. + * @param {boolean|Object} value Whether the inserter should be + * opened (true) or closed (false). + * To specify an insertion point, + * use an object. + * @param {string} value.rootClientId The root client ID to insert at. + * @param {number} value.insertionIndex The index to insert at. + * * @return {Object} Action object. */ export function setIsInserterOpened( value ) { diff --git a/packages/edit-widgets/src/store/reducer.js b/packages/edit-widgets/src/store/reducer.js index 93e650c88769f9..d6af45e6112091 100644 --- a/packages/edit-widgets/src/store/reducer.js +++ b/packages/edit-widgets/src/store/reducer.js @@ -32,10 +32,10 @@ export function widgetAreasOpenState( state = {}, action ) { /** * Reducer tracking whether the inserter is open. * - * @param {boolean} state - * @param {Object} action + * @param {boolean|Object} state + * @param {Object} action */ -function isInserterOpened( state = false, action ) { +function blockInserterPanel( state = false, action ) { switch ( action.type ) { case 'SET_IS_INSERTER_OPENED': return action.value; @@ -44,6 +44,6 @@ function isInserterOpened( state = false, action ) { } export default combineReducers( { - isInserterOpened, + blockInserterPanel, widgetAreasOpenState, } ); diff --git a/packages/edit-widgets/src/store/selectors.js b/packages/edit-widgets/src/store/selectors.js index 44d0f4614f7f99..1d8cc005148f2f 100644 --- a/packages/edit-widgets/src/store/selectors.js +++ b/packages/edit-widgets/src/store/selectors.js @@ -193,5 +193,5 @@ export const getIsWidgetAreaOpen = ( state, clientId ) => { * @return {boolean} Whether the inserter is opened. */ export function isInserterOpened( state ) { - return state.isInserterOpened; + return !! state.blockInserterPanel; }