-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update last inserted block state to track multiple blocks #46885
Update last inserted block state to track multiple blocks #46885
Conversation
@@ -2647,7 +2647,7 @@ export const __experimentalGetActiveBlockIdByBlockNames = createSelector( | |||
export function wasBlockJustInserted( state, clientId, source ) { | |||
const { lastBlockInserted } = state; | |||
return ( | |||
lastBlockInserted.clientId === clientId && | |||
lastBlockInserted.clientIds?.includes( clientId ) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea here is to preserve the intent of the existing selector as if the block has just been inserted then it will stil be a valid result.
export function __experimentalGetLastInsertedBlockClientId( state ) { | ||
return ( | ||
state?.lastBlockInserted?.clientIds?.length && | ||
state?.lastBlockInserted?.clientIds[ 0 ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could update this selector to return all the clientIds and allow the user to deal with which one they want to count as the "last" or "latest".
So if there is a single block you'd then consume it thus
const lastInsertedBlockClientId = __experimentalGetLastInsertedBlockClientIds()[0]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should return the array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, picking the first one is very arbitrary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent. We have a consensus. So I assume we:
- rename the selector to
__experimentalGetLastInsertedBlockClientIds
(plural) - deprecate the original selector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to follow the guidance and advice in the docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I have now:
- deprecated the original selector (this is why it should have been experimental 🤦 )
- add a new selector which returns an array
I still don't know if the new selector should be experimental. @draganescu felt there was no need as it was in use by the offcanvas. But that itself is an experiment so ... 🤷♂️ Opinions appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I vote we keep it experimental for now.
Size Change: +263 B (0%) Total Size: 1.32 MB
ℹ️ View Unchanged
|
I think these updates make sense. I don't think the selector should be experimental since it will be used by the Link UI. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the updates here make sense. The lastBlockInserted
reducer is surprising now by selecting the "first" from a list of inserted blocks which could be very well not the last inserted.
My one nit is getLastInsertedBlockClientId
should not be experimental because it is very simple and it will be used by Link UI right away.
I think you mean the selector? The reducer now tracks all blocks not just the first one. I kept the selector "as is" but we could easily change it to return all blocks. What do you think @draganescu? |
I pushed a fix to rename getLastInsertedBlockClientId to __experimentalGetLastInsertedBlockClientId as I was getting a JS error. |
} = select( blockEditorStore ); | ||
return { | ||
blockMovingClientId: hasBlockMovingClientId(), | ||
selectedBlockInBlockEditor: getSelectedBlockClientId(), | ||
lastInsertedBlockClientId: getLastInsertedBlockClientId(), | ||
lastInsertedBlockClientId: | ||
__experimentalGetLastInsertedBlockClientId(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we merge the "@wordpress/experiments" PR yet, in which case prefixing is considered like an outdated approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe @adamziel would know the best approach to introduce an experimental selector right now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's a good point. It might be worth a separate PR to make it experimental and then rebase this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to the flux in the API since introduced, I've followed up and made this a private selector
export function __experimentalGetLastInsertedBlockClientId( state ) { | ||
return ( | ||
state?.lastBlockInserted?.clientIds?.length && | ||
state?.lastBlockInserted?.clientIds[ 0 ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, picking the first one is very arbitrary
deprecated( | ||
'wp.data.select( "core/block-editor" ).getLastInsertedBlockClientId', | ||
{ | ||
since: '15.0', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I get a confidence check that this is the correct release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
14.9 was the last release so I believe so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
As per @youknowriad advice in #46885 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're still uncertain about this selector, it would be cool to mark it experimental once the experiments package lands.
Added the "Needs Dev Note" label to put in our our radar for WordPress 6.2 Fieldguide
... should it make it into this release. |
@getdave to make this selector experimental with the new lock()/unlock() API you'll need to:
// The `lock` function is exported from the internal experiments.js file where
// the opt-in function was called.
import { unlock } from './experiments';
import { getLastInsertedBlocksClientIds, ...selectors } from './selectors';
export const store = registerStore(/* ... */);
// Attach a private action to the exported store:
unlock( store ).registerPrivateSelector({
getLastInsertedBlocksClientIds
} );
import { unlock } from '../../experiments';
const {
hasBlockMovingClientId,
getSelectedBlockClientId,
getLastInsertedBlockClientId,
getLastInsertedBlocksClientIds,
} = unlock( select( blockEditorStore ) ); |
This selector will be private #47638 |
What?
Companion/sub PR to #46857.
Currently the last inserted block is tracked in state as a single clientId. However this only accounts for the scenario where a single block has been inserted.
This PR updates and addresses this concern by changing the state to track all inserted blocks and also providing new selectors to access this new state shape (whilst deprecating existing ones).
Why?
Currently the state only handle single blocks. It does not account for situations such as:
REPLACE_
type actions which may still "insert" new blocks but may provide multiple blocks.INSERT_BLOCKS
action which may also provide multiple blocksThis is important as sometimes it's important to know when
REPLACE_
type actions have caused new blocks to be inserted.By altering the reducer state we can track this whilst still preserving the behaviour of the original selectors.
How?
This PR:
getLastInsertedBlockClientId
selector which returned a single block only and is thus no longer suitable for accessing the state in an non-arbitrary way.getLastInsertedBlocksClientIds
which returns an array of block clientIds.REPLACE_
actions in the reducer to ensure these are also tracked as potential "insertions" of blocksTesting Instructions
Tests:
npm run test:unit packages/block-editor/src/store/test/selectors.js
npm run test:unit packages/block-editor/src/store/test/reducer.js
You can also add some blocks in a new Post and then run:
...and check that you see an array of blocks.
Also try adding some blocks, transforming into a quote and then unwrapping the quote back to individual blocks. Then run the selector above. You should see multiple blocks returned.
#### Check Depreciation Notice
Run
Check that the deprecation notice in console is correct.
Testing Instructions for Keyboard
Screenshots or screencast