-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Update the block styles registration to avoid timing issues #11532
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
Conversation
jorgefilipecosta
left a 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.
This PR seems to work correctly. I left some improvements I think should be made before the merge.
I understand the reason for this change and it works well 👍 But I would prefer if blockStyles appeared under blockTypes.[blockName].blockStyles instead of blockStyles[blockName] in the state structure.
Would force the addBlockStyles call to be made after the block being registered to be an option?
If not would the concept of temporaryBlockType be an option? When calling addBlockStyles in a non-existing block it would add the style part in temporaryBlockType a sibling blockTypes of when registering the block if the block contains properties in temporaryBlockType these properties would be moved. This would be a totally generic solution, and in the future, if we have other need to dynamically manage or add block properties this system would work.
This last part is just a personal option regarding the state structure, it is a non-blocker at all.
| */ | ||
| export function blockStyles( state = {}, action ) { | ||
| switch ( action.type ) { | ||
| case 'ADD_BLOCK_TYPES': |
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 also should handle the REMOVE_BLOCK_TYPES action.
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 didn't explicitly because the registration of styles can happen even before the block exists or after, that's one of the main ideas of this PR. You can register your styles and your block whenever you want, the styles will always be there.
For example, a plugin author could unregister a block type, register it back slightly modified and the styles will still be there.
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.
Interesting way of thinking. The issue I see here is that you could add styles with block X and then remove it but its styles will be still there.
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.
Is this really an issue? I mean aside some state being there and not really useful.
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 an issue if you reuse the same block name to register your own version of the block, it would have also styles from the old block. Not a big deal in my opinion, but it raises a flag if you would scale the pattern for other parts of the block settings. I'm thinking how to turn block.registerBlockType hook into a self-dispatching action which does the same what you did here :)
| return state; | ||
| } | ||
|
|
||
| /** |
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 also need to change blockTypes to remove styles from the blockTypes, right now they are duplicated in blockTypes and blockStyes.
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 thought about it. I actually even had it implemented, but decided to revert. The idea is that, this could serve as a way to differentiate which styles are custom and which are defined in the block settings. But I don't have strong opinions though, I'm fine omitting them.
That's not an option, the idea of this PR is to allow plugins to register styles whenever they want regardless of existance of blocks or not. Because the loading order of JS scripts is very fragile if we can avoid it being an issue, then it's better for everyone. |
I don't have strong opinion on the state shape, it's just implementation detail for me as the most important part is the selectors. Changing as you suggest means I have to also refactor the block types to be something like |
2c98e23 to
c89b880
Compare
jorgefilipecosta
left a 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.
This seems to work correctly on my tests. Thank @youknowriad for clarifying my questions. I understood the rationale behind the decisions taken here and this looks ready to go 👍
| onHoverClassName = noop, | ||
| } ) { | ||
| if ( ! styles ) { | ||
| if ( ! styles || styles.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.
Even if the block has no styles at all, it contains an empty array of styles. Should we continue to check for the length?
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, the idea is that we don't show this panel at all if there's no styles.
|
Seems like one still has to use |
|
@swissspidy Yes probably because if you unregister a style and then a code runs later and register it back, it will be there. |
Registering custom styles works fine for me. Unregistering core/block styles is another story. |
| ...state, | ||
| ...keyBy( action.blockTypes, 'name' ), | ||
| ...keyBy( | ||
| map( action.blockTypes, ( blockType ) => omit( blockType, 'styles ' ) ), |
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.
@youknowriad This looks like a typo, should 'styles ' be 'styles'?
It's present in current releases:
| omit( blockType, 'styles ' ) |
It looks like this was intended to exclude the styles property in blockTypes state (it's moved to blockStyles), but it's present:
wp.data.select('core/blocks').getBlockType("core/image").styles.length
// 2There 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.
definitely looks like a typo yes, do you know what concrete impact this has?
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 noticed it when inspecting some code, I don't have much idea of the impact it has.
It does appear to duplicate the state stored in blockStyles:
wp.data.select('core/blocks').getBlockType("core/image").styles
// [{"name":"default","label":"Default","isDefault":true},{"name":"rounded","label":"Rounded"}]
// Gives same result
wp.data.select('core/blocks').getBlockStyles("core/image")
// [{"name":"default","label":"Default","isDefault":true},{"name":"rounded","label":"Rounded"}]
// But not referential equality
wp.data.select('core/blocks').getBlockType("core/image").styles === wp.data.select('core/blocks').getBlockStyles("core/image")
// false
closes #11392
At the moment, registering blockStyle variations is very fragile because you have to register it before the block registers itself and at the same time the block registers itself before the dom is ready which makes it very hard to do properly.
In this PR, I'm updating the block styles registration:
getBlockTypeto fetch the styles, rely on a selector (reactive)This way we can register/unregister block styles at any moment.
I'd also argue that we should stop using
getBlockTypeandgetBlockTypesentirely and try to refactor our code to use the selectors instead. So any change that would happen to the block settings after the initial registration would be taken into consideration in the UI.Testing instructions
wp.blocks.registerBlockStyle( 'core/image', { name: 'fancy' } )