Block: split out toolbar rendering#19564
Conversation
e592896 to
aa9195a
Compare
d9b41e1 to
43227f6
Compare
9d5ac15 to
8f7eb28
Compare
| 'is-focused': isFocusMode && ( isSelected || isAncestorOfSelectedBlock ), | ||
| 'is-focus-mode': isFocusMode, | ||
| 'has-child-selected': isAncestorOfSelectedBlock, | ||
| 'has-toolbar-captured': hasAncestorCapturingToolbars, |
There was a problem hiding this comment.
Removing this class since it was used only for one broken CSS rule. Additionally it's a lot of selectors running for each block.
|
|
||
| // Toolbar is captured | ||
| &.has-toolbar-captured::before { | ||
| left: 0; // place "selected" indicator closer to block due to no toolbar |
There was a problem hiding this comment.
This rule is targeting .block-editor-block-list__layout, but .has-toolbar-captured is only added to blocks, so it's broken. I don't see any issues with the block border without this rule. Everything is looking good. Additionally there are plans to get rid of the border altogether anyway.
|
Performance test: |
In general we avoid using complex objects (DOM elements) in state. Any particular reason to avoid block DOM utils. |
| isSelected, | ||
| isAncestorOfSelectedBlock, | ||
| isCapturingDescendantToolbars, | ||
| hasAncestorCapturingToolbars, |
There was a problem hiding this comment.
I don't expect the removed props from this component to have been used by plugins (blockedit filter), that said, we need to communicate this with a dev note.
There was a problem hiding this comment.
It was added recently, so it won't be in any WP release. #18440
Yes, we need the component to rerender when the block DOM node is mounted, but I can simplify it by only saving the client ID and then getting the element by ID. I'll adjust it. |
881b5d3 to
35745da
Compare
35745da to
dcd76e2
Compare
|
Let's merge and iterate as this is a good separation to have and it has clear performance benefits. |
| * | ||
| * @return {boolean} Updated state. | ||
| */ | ||
| export function selectedMountedBlock( state, action ) { |
There was a problem hiding this comment.
How is this different from the block selection state?
There was a problem hiding this comment.
It's only set when the block node is mounted. This is useful when you have to render a popover at the position of this node. We can't render the popover before the node is mounted.
There was a problem hiding this comment.
I honestly feel this is entirely useless. If the selected block is in the store, it's already mounted right? at worst it's mounted after a useEffect
There was a problem hiding this comment.
I don't think it's useless, but we can try alternative ways for sure. Being a selected block in the store doesn't mean that the block is mounted. React first has to render the block. This is similar to the block node not being available at the time of rendering. You have to use useEffect.
There was a problem hiding this comment.
I'm open to alternatives though.
There was a problem hiding this comment.
I feel having a state just to say "something is mounted" is not great. ideally, something in the state should make the block mount, in the case of blocks, blocks are mounted as soon as they are in the state, which for me suggests that it should be treated at the component level.
I guess the main issue here is that the rendering of the block and the rendering of the toolbar arae separate in two separate React trees so for the first render of the blocks, we're not certain which one will render first.
I'm not sure what's the perfect solution here other than just using an interval/useEffect or something like that.
There was a problem hiding this comment.
Right, the only dependency on BlockListBlock is the position of the DOM node. I totally agree with you that it's not ideal and that's why I marked it unstable. I'll explore an alternative idea in a separate PR.
There was a problem hiding this comment.
We could try to provide Popover with a selector for the anchor. Popover already repositions at an interval, so this could work. Additionally, we also already use a selector for multi selected block (to enable sticking the toolbar).
Description
Offers a 7% performance gain.
This PR moves the toolbar popover out of the block tree. Eventually, the goal is to be able to remove the special popover slot and maybe unify it with the fixed toolbar and/or mobile toolbar. I suspect it may improve performance a bit too.
This step is very important in simplifying the React tree of the block and further performance improvements.
Worth noting is that I rewrote the way toolbar capturing works. Since toolbars are in popovers, toolbar capturing is a matter of attaching the popover to the right parent block node. There's no need to use slots.
Also worth noting is that block nodes are added to the block-editor state. This is very useful for any components that need to render based on wether or not a block node in actually mounted in the DOM. I marked this API unstable for now.
How has this been tested?
Everything should work as before. Test toolbar rendering.
Screenshots
Types of changes
Refactoring.
Checklist: