Skip to content
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

Components: ToolsPanel: fix deregister/register on type #56770

Merged
merged 5 commits into from
Dec 6, 2023

Conversation

ellatrix
Copy link
Member

@ellatrix ellatrix commented Dec 4, 2023

What?

When logging all the callbacks in ToolsPanel, this is what happens on typing:

tools-panel

Panel items seem to be deregistered, then registered again.

Diving deeper, it seems to be caused by hasValueCallback triggering an effect. It seems a the dependency hasValue has been added in #45028, which is a new function on every render.

Why?

Note the re-rendering of the wrapping Panel:

Before After
before after

How?

Testing Instructions

Testing Instructions for Keyboard

Screenshots or screencast

@ellatrix ellatrix added [Type] Bug An existing feature does not function as intended [Package] Components /packages/components labels Dec 4, 2023
Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very promising, thanks for putting up the PR!

I ran into one issue while manually testing out the failing unit test for should render optional panel item when value is updated externally and panel has an ID. The behaviour that's being tested was introduced in #47864, and it appears the expectation in that PR is that when copying and pasting styles from one block to another, that the ToolsPanel state will be updated to reflect the change that happened from outside of the ToolsPanel.

Here's a screengrab of how it looks with this PR applied (if testing locally, you'll need to run a dev environment on localhost for pasting styles to work):

2023-12-05.11.02.01.mp4

In the above:

  • We start out with a Heading block with a few Typography rules set (font-size, appearance, letter case), and go to copy the styles
  • We then paste the styles on another Heading block, and the paste works visually, however the ToolsPanel state does not update to reflect the new changes, i.e. font-size toggle isn't active for the right font size, and appearance and letter case controls are not visible, nor marked as having a value within the dropdown (you'd need to click out of the block and back into it to see the reflected state change)

So, it seems that perhaps #47864 was implicitly relying on the values in this PR being changed too frequently? I'm not too sure how, but I imagine we'll need to adjust some other logic to get that working again with the changes to the dependency array here.

I'll just ping @aaronrobertshaw, @glendaviesnz, and @ciampo for visibility since I see they were involved in #47864 🙂

// eslint-disable-next-line react-hooks/exhaustive-deps
const hasValueCallback = useCallback( hasValue, [ panelId ] );
// eslint-disable-next-line react-hooks/exhaustive-deps
const resetAllFilterCallback = useCallback( resetAllFilter, [ panelId ] );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add some comments to explain why we're disable the eslint rule.

This is the perfect use-case for the useEvent hook they proposed in React. not sure what happened to that proposal.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't aware of useEvent, but we have lots of cases in rich text and elsewhere too where we have to put stuff in a ref to access it in callbacks later.

@ellatrix
Copy link
Member Author

ellatrix commented Dec 5, 2023

@andrewserong I just tried copy pasting styles, and the typography/size button doesn't become active in trunk either. And in both trunk and this PR the letter case button seems to appear. 🤔

@ellatrix
Copy link
Member Author

ellatrix commented Dec 5, 2023

@andrewserong Your intuition was good here, #47864 seems relevant. The component was somehow relying on excessive re-renders to get a different value for menuItems?.[ menuGroup ]?.[ label ]. I remove the condition around flagItemCustomization and all tests seem to pass now, but I don't really understand what is happening much because I'm not familiar with these components.

@ellatrix ellatrix marked this pull request as ready for review December 5, 2023 09:31
@ellatrix ellatrix added [Type] Performance Related to performance efforts and removed [Type] Bug An existing feature does not function as intended labels Dec 5, 2023
Copy link

github-actions bot commented Dec 5, 2023

Flaky tests detected in c601a63.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/7111030661
📝 Reported issues:

@ellatrix ellatrix force-pushed the try/fix-tools-panel-re-renders branch from 46c5bde to a010c66 Compare December 5, 2023 19:41
Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work getting to the bottom of this @ellatrix! This is all testing well for me:

✅ Default and optional items are behaving correctly within the ToolsPanel and its menu
✅ Copy / pasting styles from one block to one or more other blocks behaves as on trunk
✅ Smoke tested many ToolsPanel instances (color, typography, dimensions, border) at the block level and within global styles, and all appears to be behaving as on trunk

The changes to when flagItemCustomization is called sound good to me, and appears to match the intended behaviour in #47864. The logic now means that whenever a new value is set, we update the item customization, which seems simpler, too 👍

I think this means we can also update the comment in the following line to remove the words when the panel ID is null:

// 2. For optional controls, when the panel ID is `null`, it allows the

But other than that, this LGTM! ✨

@ellatrix ellatrix enabled auto-merge (squash) December 6, 2023 06:45
@ellatrix ellatrix merged commit a82ae41 into trunk Dec 6, 2023
52 checks passed
@ellatrix ellatrix deleted the try/fix-tools-panel-re-renders branch December 6, 2023 07:00
@github-actions github-actions bot added this to the Gutenberg 17.3 milestone Dec 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Components /packages/components [Type] Performance Related to performance efforts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants