-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Block Bindings: Create utils to update or remove bindings #64102
Conversation
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Size Change: +36 B (0%) Total Size: 1.76 MB
ℹ️ View Unchanged
|
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.
Looks good to me!
@@ -286,7 +231,7 @@ export const BlockBindingsPanel = ( { name, metadata } ) => { | |||
} ); | |||
// Only add source if the list is not empty. | |||
if ( sourceList ) { | |||
fieldsList[ label ] = { ...sourceList }; | |||
fieldsList[ sourceName ] = { ...sourceList }; |
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.
Why were we using the label
here before? It seems like that was brittle. It appears that this change is unrelated to the adding of the utils in this PR, and is just an additional code cleanup, and it looks good. I'm just curious.
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.
It seems that we were just using the values of the registeredSources
object instead of their keys.
I'm not sure if if sources label were always the same as the registeredSources key, but this approach seems safer, as the label should allow whitespaces or uppercases.
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.
Why were we using the label here before?
I believe the name wasn't exposed before. But this seemed safer to me as well.
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.
const { metadata } = getBlockAttributes( clientId ); | ||
const newMetadata = { ...metadata }; | ||
delete newMetadata.bindings; |
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.
That could be a single line:
const { metadata: { bindings, ...metadata } } = getBlockAttributes( clientId );
export function useBlockBindingsUtils() { | ||
const { clientId } = useBlockEditContext(); | ||
const { updateBlockAttributes } = useDispatch( blockEditorStore ); | ||
const { getBlockAttributes } = useSelect( blockEditorStore ); |
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.
It would be more optimal to have:
const { getBlockAttributes } = useRegistry().select( blockEditorStore );
See more in this guide.
bindings: newBindings, | ||
}; | ||
|
||
if ( Object.keys( newMetadata.bindings ).length === 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.
Here and in other places it would increase the readability if the helper function was present:
function isObjectEmpty( object ) {
return ! object || Object.keys( object ).length === 0;
}
// later
if ( isObjectEmpty( newMetadata.bindings ) ) {
This could also be further refactored so it doesn't require the step to remove the undefined key:
const newMetadata = {
...metadata,
...( ! isObjectEmpty( newBindings ) && {
bindings: newBindings,
} ),
};
Nice refactoring. It looks like two methods allow to accomplish all necessary operations: const { updateBlockBindings, removeAllBlockBindings ) = useBlockBindingsUtils();
// Add or update a binding.
updateBlockBindings( { attributeName: { source: 'my/source' } );
// Remove a binding - that could also be included in the inline docs.
updateBlockBindings( { attributeName: undefined );
// Remove all block bindings for a block.
removeAllBlockBindings(); When opening this API to the public, it might also be worth considering allowing passing a different // Remove all block bindings for another block.
const { removeAllBlockBindings ) = useBlockBindingsUtils( anotherClientId );
removeAllBlockBindings(); |
…64102) * Add `useBlockBindingsUtils` * Use utils in custom fields UI * Use utils in pattern overrides * Properly populate custom fields * Add comments * Update wrong comment Co-authored-by: SantosGuillamot <santosguillamot@git.wordpress.org> Co-authored-by: artemiomorales <artemiosans@git.wordpress.org> Co-authored-by: cbravobernal <cbravobernal@git.wordpress.org>
@SantosGuillamot @gziolo @cbravobernal
Curious, was there some boilerplate code y'all used to test this? I wanted to test it, but did not see anything in the notes of this ticket. 🕵️ 🤔 |
When this was first added, it was still a private API used by You can find an example of how it could be used in the readme. However, trying to create a quick code snippet, I've realized that we didn't address passing a |
I've started this pull request to explore that possibility: #65818 It's hard to test manually because hooks need to run inside components or hooks, but I add some unit tests that should serve as reference and to give more confidence on the APIs. |
What?
This pull requests explores the idea of exposing two new block bindings utils to easily add/remove/update bindings in the editor:
updateBlockAttributes
. You pass an object with all the bindings to update, and to remove one users can passundefined
.Why?
The same code was used for the custom fields UI and pattern overrides. Additionally, it could be useful for external developers in case they want to create their own UIs.
How?
Creating a
useBlockBindingsUtils
hook that return the needed function. It is inspired by other hooks like useGradient.Testing Instructions
It doesn't add new functionalities. Automated tests should pass.