Skip to content

Commit

Permalink
Move insertionPoint state to block-editor store/rename existing inser…
Browse files Browse the repository at this point in the history
…tionPoint to insertionCue (WordPress#65098)

* Renames state.insertionPoint to state.insertionCue in the block editor store and related action/reducers.
*  Adds state.insertionPoint to store when an insertion point is manually passed.
*  Dispatching the block editor setInsertionPoint from editor action setIsInserterOpened.
* Clear insertionPoint state on SELECT_BLOCK
  • Loading branch information
jeryj authored Sep 26, 2024
1 parent c75d114 commit 0ed82ae
Show file tree
Hide file tree
Showing 20 changed files with 277 additions and 85 deletions.
4 changes: 2 additions & 2 deletions docs/reference-guides/data/data-core-block-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ _Returns_

### getBlockInsertionPoint

Returns the insertion point, the index at which the new inserted block would be placed. Defaults to the last index.
Returns the location of the insertion cue. Defaults to the last index.

_Parameters_

Expand Down Expand Up @@ -982,7 +982,7 @@ _Returns_

### isBlockInsertionPointVisible

Returns true if we should show the block insertion point.
Returns true if the block insertion point is visible.

_Parameters_

Expand Down
4 changes: 4 additions & 0 deletions docs/reference-guides/data/data-core-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,10 @@ _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.filterValue_ `string`: A query to filter the inserter results.
- _value.onSelect_ `Function`: A callback when an item is selected.
- _value.tab_ `string`: The tab to open in the inserter.
- _value.category_ `string`: The category to initialize in the inserter.

_Returns_

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@ export function ZoomOutSeparator( {
const {
sectionRootClientId,
sectionClientIds,
blockInsertionPoint,
insertionPoint,
blockInsertionPointVisible,
blockInsertionPoint,
} = useSelect( ( select ) => {
const {
getBlockInsertionPoint,
getInsertionPoint,
getBlockOrder,
isBlockInsertionPointVisible,
getSectionRootClientId,
isBlockInsertionPointVisible,
getBlockInsertionPoint,
} = unlock( select( blockEditorStore ) );

const root = getSectionRootClientId();
Expand All @@ -45,6 +47,7 @@ export function ZoomOutSeparator( {
sectionRootClientId: root,
sectionClientIds: sectionRootClientIds,
blockOrder: getBlockOrder( root ),
insertionPoint: getInsertionPoint(),
blockInsertionPoint: getBlockInsertionPoint(),
blockInsertionPointVisible: isBlockInsertionPointVisible(),
};
Expand All @@ -67,17 +70,30 @@ export function ZoomOutSeparator( {
return null;
}

const hasTopInsertionPoint =
insertionPoint?.index === 0 &&
clientId === sectionClientIds[ insertionPoint.index ];
const hasBottomInsertionPoint =
insertionPoint &&
insertionPoint.hasOwnProperty( 'index' ) &&
clientId === sectionClientIds[ insertionPoint.index - 1 ];
// We want to show the zoom out separator in either of these conditions:
// 1. If the inserter has an insertion index set
// 2. We are dragging a pattern over an insertion point
if ( position === 'top' ) {
isVisible =
blockInsertionPointVisible &&
blockInsertionPoint.index === 0 &&
clientId === sectionClientIds[ blockInsertionPoint.index ];
hasTopInsertionPoint ||
( blockInsertionPointVisible &&
blockInsertionPoint.index === 0 &&
clientId === sectionClientIds[ blockInsertionPoint.index ] );
}

if ( position === 'bottom' ) {
isVisible =
blockInsertionPointVisible &&
clientId === sectionClientIds[ blockInsertionPoint.index - 1 ];
hasBottomInsertionPoint ||
( blockInsertionPointVisible &&
clientId ===
sectionClientIds[ blockInsertionPoint.index - 1 ] );
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function ZoomOutModeInserters() {
const [ isReady, setIsReady ] = useState( false );
const {
hasSelection,
blockInsertionPoint,
insertionPoint,
blockOrder,
blockInsertionPointVisible,
setInserterIsOpened,
Expand All @@ -26,20 +26,20 @@ function ZoomOutModeInserters() {
} = useSelect( ( select ) => {
const {
getSettings,
getBlockInsertionPoint,
getInsertionPoint,
getBlockOrder,
getSelectionStart,
getSelectedBlockClientId,
getHoveredBlockClientId,
isBlockInsertionPointVisible,
getSectionRootClientId,
isBlockInsertionPointVisible,
} = unlock( select( blockEditorStore ) );

const root = getSectionRootClientId();

return {
hasSelection: !! getSelectionStart().clientId,
blockInsertionPoint: getBlockInsertionPoint(),
insertionPoint: getInsertionPoint(),
blockOrder: getBlockOrder( root ),
blockInsertionPointVisible: isBlockInsertionPointVisible(),
sectionRootClientId: root,
Expand All @@ -50,7 +50,8 @@ function ZoomOutModeInserters() {
};
}, [] );

const { showInsertionPoint } = useDispatch( blockEditorStore );
// eslint-disable-next-line @wordpress/no-unused-vars-before-return
const { showInsertionPoint } = unlock( useDispatch( blockEditorStore ) );

// Defer the initial rendering to avoid the jumps due to the animation.
useEffect( () => {
Expand All @@ -68,7 +69,7 @@ function ZoomOutModeInserters() {

return [ undefined, ...blockOrder ].map( ( clientId, index ) => {
const shouldRenderInsertionPoint =
blockInsertionPointVisible && blockInsertionPoint.index === index;
blockInsertionPointVisible && insertionPoint?.index === index;

const previousClientId = clientId;
const nextClientId = blockOrder[ index ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,24 @@ function useInsertionPoint( {
getBlockRootClientId,
getBlockIndex,
getBlockOrder,
} = select( blockEditorStore );
getInsertionPoint,
} = unlock( select( blockEditorStore ) );
const selectedBlockClientId = getSelectedBlockClientId();

let _destinationRootClientId = rootClientId;
let _destinationIndex;
const insertionPoint = getInsertionPoint();

if ( insertionIndex !== undefined ) {
// Insert into a specific index.
_destinationIndex = insertionIndex;
} else if (
insertionPoint &&
insertionPoint.hasOwnProperty( 'index' )
) {
_destinationRootClientId = insertionPoint?.rootClientId
? insertionPoint.rootClientId
: rootClientId;
_destinationIndex = insertionPoint.index;
} else if ( clientId ) {
// Insert after a specific client ID.
_destinationIndex = getBlockIndex( clientId );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ export default function QuickInserter( {
// the insertion point can work as expected.
const onBrowseAll = () => {
setInserterIsOpened( {
rootClientId,
insertionIndex,
filterValue,
onSelect,
rootClientId,
insertionIndex,
} );
};

Expand Down
14 changes: 14 additions & 0 deletions packages/block-editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,20 @@ export function expandBlock( clientId ) {
};
}

/**
* @param {Object} value
* @param {string} value.rootClientId The root client ID to insert at.
* @param {number} value.index The index to insert at.
*
* @return {Object} Action object.
*/
export function setInsertionPoint( value ) {
return {
type: 'SET_INSERTION_POINT',
value,
};
}

/**
* Temporarily modify/unlock the content-only block for editions.
*
Expand Down
10 changes: 10 additions & 0 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -674,3 +674,13 @@ export function getClosestAllowedInsertionPointForPattern(
const names = getGrammar( pattern ).map( ( { blockName: name } ) => name );
return getClosestAllowedInsertionPoint( state, names, clientId );
}

/**
* Where the point where the next block will be inserted into.
*
* @param {Object} state
* @return {Object} where the insertion point in the block editor is or null if none is set.
*/
export function getInsertionPoint( state ) {
return state.insertionPoint;
}
24 changes: 22 additions & 2 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,7 @@ export function blocksMode( state = {}, action ) {
*
* @return {Object} Updated state.
*/
export function insertionPoint( state = null, action ) {
export function insertionCue( state = null, action ) {
switch ( action.type ) {
case 'SHOW_INSERTION_POINT': {
const {
Expand Down Expand Up @@ -2066,7 +2066,7 @@ export function hoveredBlockClientId( state = false, action ) {
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
* @return {number} Updated state.
*/
export function zoomLevel( state = 100, action ) {
switch ( action.type ) {
Expand All @@ -2079,6 +2079,25 @@ export function zoomLevel( state = 100, action ) {
return state;
}

/**
* Reducer setting the insertion point
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
export function insertionPoint( state = null, action ) {
switch ( action.type ) {
case 'SET_INSERTION_POINT':
return action.value;
case 'SELECT_BLOCK':
return null;
}

return state;
}

const combinedReducers = combineReducers( {
blocks,
isDragging,
Expand All @@ -2092,6 +2111,7 @@ const combinedReducers = combineReducers( {
blocksMode,
blockListSettings,
insertionPoint,
insertionCue,
template,
settings,
preferences,
Expand Down
15 changes: 7 additions & 8 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1454,8 +1454,7 @@ export function isCaretWithinFormattedText() {
}

/**
* Returns the insertion point, the index at which the new inserted block would
* be placed. Defaults to the last index.
* Returns the location of the insertion cue. Defaults to the last index.
*
* @param {Object} state Editor state.
*
Expand All @@ -1466,11 +1465,11 @@ export const getBlockInsertionPoint = createSelector(
let rootClientId, index;

const {
insertionPoint,
insertionCue,
selection: { selectionEnd },
} = state;
if ( insertionPoint !== null ) {
return insertionPoint;
if ( insertionCue !== null ) {
return insertionCue;
}

const { clientId } = selectionEnd;
Expand All @@ -1485,22 +1484,22 @@ export const getBlockInsertionPoint = createSelector(
return { rootClientId, index };
},
( state ) => [
state.insertionPoint,
state.insertionCue,
state.selection.selectionEnd.clientId,
state.blocks.parents,
state.blocks.order,
]
);

/**
* Returns true if we should show the block insertion point.
* Returns true if the block insertion point is visible.
*
* @param {Object} state Global application state.
*
* @return {?boolean} Whether the insertion point is visible or not.
*/
export function isBlockInsertionPointVisible( state ) {
return state.insertionPoint !== null;
return state.insertionCue !== null;
}

/**
Expand Down
15 changes: 15 additions & 0 deletions packages/block-editor/src/store/test/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
showBlockInterface,
expandBlock,
__experimentalUpdateSettings,
setInsertionPoint,
setOpenedBlockSettingsMenu,
startDragging,
stopDragging,
Expand Down Expand Up @@ -123,4 +124,18 @@ describe( 'private actions', () => {
} );
} );
} );

describe( 'setInsertionPoint', () => {
it( 'should return the SET_INSERTION_POINT action', () => {
expect(
setInsertionPoint( {
rootClientId: '',
index: '123',
} )
).toEqual( {
type: 'SET_INSERTION_POINT',
value: { rootClientId: '', index: '123' },
} );
} );
} );
} );
Loading

0 comments on commit 0ed82ae

Please sign in to comment.