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

Tooltip: avoid unnecessary re-renders of <select> child elements #42483

Merged
merged 8 commits into from
Jul 23, 2022

Conversation

t-hamano
Copy link
Contributor

@t-hamano t-hamano commented Jul 17, 2022

Fix: #37856 / #38113 / #41845

What?

This PR prevents the Tooltip component from re-rendering child components when the children's select list is chosen.

Why?

Through I was investigating #41845, I found that the behavior of the onMouseDown event when a select list is chosen varies from browser to browser.

As mentioned in this comment, in Firefox, onMouseDown is also fired when a select list is selected.

Was just having a little poke at this. I believe @skiritsis is on the right track. There are two MouseDown events getting fired. First, a MouseDown fires when the select is initially interacted with and the browser shows the list of values. Second, a MouseDown again fires when any specific value is chosen from that modal list. If you throw a console.log into that handleMouseDown function to output the value of the select list, it will show the correct value prior to the setState() call.

This means that in Firefox, the onMouseDown event in Tooltip is also triggered when the children's select list is selected.

I'm not sure, but I would expect that the Tooltip's onMousedown firing would cause the child component to re-render and the select element's onChange event is triggered with the old value.

As far as I know, this problem occurs in the following cases in Firefox:

How?

I have made it so that the process is canceled only when the select list is selected in the onMouseDown event of the Tooltip component.
I think there is a smarter way to handle this.

Testing Instructions

  • Open Firefox.
  • Insert any block.
  • From the sidebar, view the item with the BoxControl and click "Unlink Sides".
  • Confirm that the units in either direction are changed correctly.

@github-actions
Copy link

github-actions bot commented Jul 17, 2022

Size Change: +14 B (0%)

Total Size: 1.26 MB

Filename Size Change
build/components/index.min.js 230 kB +14 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 982 B
build/annotations/index.min.js 2.76 kB
build/api-fetch/index.min.js 2.26 kB
build/autop/index.min.js 2.14 kB
build/blob/index.min.js 475 B
build/block-directory/index.min.js 6.58 kB
build/block-directory/style-rtl.css 990 B
build/block-directory/style.css 991 B
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/index.min.js 153 kB
build/block-editor/style-rtl.css 14.6 kB
build/block-editor/style.css 14.6 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 103 B
build/block-library/blocks/audio/style.css 103 B
build/block-library/blocks/audio/theme-rtl.css 110 B
build/block-library/blocks/audio/theme.css 110 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 59 B
build/block-library/blocks/avatar/style.css 59 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 441 B
build/block-library/blocks/button/editor.css 441 B
build/block-library/blocks/button/style-rtl.css 542 B
build/block-library/blocks/button/style.css 542 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 187 B
build/block-library/blocks/comment-template/style.css 185 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 834 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 630 B
build/block-library/blocks/cover/editor-rtl.css 615 B
build/block-library/blocks/cover/editor.css 616 B
build/block-library/blocks/cover/style-rtl.css 1.55 kB
build/block-library/blocks/cover/style.css 1.55 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 110 B
build/block-library/blocks/embed/theme.css 110 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 253 B
build/block-library/blocks/file/style.css 254 B
build/block-library/blocks/file/view.min.js 346 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 948 B
build/block-library/blocks/gallery/editor.css 950 B
build/block-library/blocks/gallery/style-rtl.css 1.53 kB
build/block-library/blocks/gallery/style.css 1.53 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 333 B
build/block-library/blocks/group/editor.css 333 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 327 B
build/block-library/blocks/html/editor.css 329 B
build/block-library/blocks/image/editor-rtl.css 736 B
build/block-library/blocks/image/editor.css 737 B
build/block-library/blocks/image/style-rtl.css 627 B
build/block-library/blocks/image/style.css 630 B
build/block-library/blocks/image/theme-rtl.css 110 B
build/block-library/blocks/image/theme.css 110 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 463 B
build/block-library/blocks/latest-posts/style.css 462 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 705 B
build/block-library/blocks/navigation-link/editor.css 703 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation-submenu/view.min.js 423 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.96 kB
build/block-library/blocks/navigation/style.css 1.95 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 443 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 363 B
build/block-library/blocks/page-list/editor.css 363 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 260 B
build/block-library/blocks/paragraph/style.css 260 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 493 B
build/block-library/blocks/post-comments-form/style.css 493 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 605 B
build/block-library/blocks/post-featured-image/editor.css 605 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 282 B
build/block-library/blocks/post-template/style.css 282 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 370 B
build/block-library/blocks/pullquote/style.css 370 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 365 B
build/block-library/blocks/query/editor.css 364 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 385 B
build/block-library/blocks/search/style.css 386 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 464 B
build/block-library/blocks/shortcode/editor.css 464 B
build/block-library/blocks/site-logo/editor-rtl.css 708 B
build/block-library/blocks/site-logo/editor.css 708 B
build/block-library/blocks/site-logo/style-rtl.css 192 B
build/block-library/blocks/site-logo/style.css 192 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.39 kB
build/block-library/blocks/social-links/style.css 1.38 kB
build/block-library/blocks/spacer/editor-rtl.css 322 B
build/block-library/blocks/spacer/editor.css 322 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 494 B
build/block-library/blocks/table/editor.css 494 B
build/block-library/blocks/table/style-rtl.css 611 B
build/block-library/blocks/table/style.css 609 B
build/block-library/blocks/table/theme-rtl.css 175 B
build/block-library/blocks/table/theme.css 175 B
build/block-library/blocks/tag-cloud/style-rtl.css 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 235 B
build/block-library/blocks/template-part/editor.css 235 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 561 B
build/block-library/blocks/video/editor.css 563 B
build/block-library/blocks/video/style-rtl.css 159 B
build/block-library/blocks/video/style.css 159 B
build/block-library/blocks/video/theme-rtl.css 110 B
build/block-library/blocks/video/theme.css 110 B
build/block-library/common-rtl.css 1.01 kB
build/block-library/common.css 1 kB
build/block-library/editor-rtl.css 10.8 kB
build/block-library/editor.css 10.8 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 184 kB
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 11.8 kB
build/block-library/style.css 11.8 kB
build/block-library/theme-rtl.css 695 B
build/block-library/theme.css 700 B
build/block-serialization-default-parser/index.min.js 1.11 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 47.2 kB
build/components/style-rtl.css 14 kB
build/components/style.css 14 kB
build/compose/index.min.js 11.7 kB
build/core-data/index.min.js 14.7 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.4 kB
build/customize-widgets/style.css 1.4 kB
build/data-controls/index.min.js 653 B
build/data/index.min.js 7.99 kB
build/date/index.min.js 32 kB
build/deprecated/index.min.js 507 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.69 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 4.02 kB
build/edit-navigation/style.css 4.03 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 30.5 kB
build/edit-post/style-rtl.css 6.94 kB
build/edit-post/style.css 6.94 kB
build/edit-site/index.min.js 54.2 kB
build/edit-site/style-rtl.css 8.18 kB
build/edit-site/style.css 8.16 kB
build/edit-widgets/index.min.js 16.5 kB
build/edit-widgets/style-rtl.css 4.35 kB
build/edit-widgets/style.css 4.35 kB
build/editor/index.min.js 41.3 kB
build/editor/style-rtl.css 3.66 kB
build/editor/style.css 3.65 kB
build/element/index.min.js 4.27 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 6.75 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.64 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.77 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.78 kB
build/keycodes/index.min.js 1.38 kB
build/list-reusable-blocks/index.min.js 1.74 kB
build/list-reusable-blocks/style-rtl.css 835 B
build/list-reusable-blocks/style.css 835 B
build/media-utils/index.min.js 2.93 kB
build/notices/index.min.js 953 B
build/nux/index.min.js 2.05 kB
build/nux/style-rtl.css 732 B
build/nux/style.css 728 B
build/plugins/index.min.js 1.94 kB
build/preferences-persistence/index.min.js 2.22 kB
build/preferences/index.min.js 1.3 kB
build/primitives/index.min.js 933 B
build/priority-queue/index.min.js 612 B
build/react-i18n/index.min.js 696 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.68 kB
build/reusable-blocks/index.min.js 2.22 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.1 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.53 kB
build/token-list/index.min.js 644 B
build/url/index.min.js 3.61 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 268 B
build/widgets/index.min.js 7.19 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@t-hamano t-hamano changed the title [WIP] Tooltip: Don't re-render child components when select list is chosen [Try] Tooltip: Don't re-render child components when select list is chosen Jul 17, 2022
@t-hamano t-hamano marked this pull request as ready for review July 17, 2022 15:40
@t-hamano t-hamano requested a review from ajitbohra as a code owner July 17, 2022 15:40
@t-hamano t-hamano added [Type] Bug An existing feature does not function as intended [Package] Components /packages/components labels Jul 17, 2022
@ciampo ciampo added the [Feature] UI Components Impacts or related to the UI component system label Jul 19, 2022
@ciampo ciampo self-requested a review July 19, 2022 13:29
Copy link
Contributor

@ciampo ciampo left a comment

Choose a reason for hiding this comment

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

I tried on my local machine, and I can still replicate the bug — maybe I'm doing something wrong in my testing?

Also, if the problem is caused by the select component, should we try to add a fix in select-related components directly? Maybe we could look at calling stopPropagation or something like that?

@t-hamano
Copy link
Contributor Author

t-hamano commented Jul 19, 2022

I have created a video to test the effectiveness of this PR.
I hope these steps prove useful.

(I have tested it on Windows, but since #41845 is reported on MacOS, so I think it isn't an OS issue.)

2d0ee6aa21c7e3163e22fa93f9b1a64a.mp4

Also, if the problem is caused by the select component, should we try to add a fix in select-related components directly? Maybe we could look at calling stopPropagation or something like that?

Tooltips may contain components that are not controlled by Gutenberg, such as pure select elements or select elements from third-party libraries.
Given that, I think the problem needs to be resolved on the Tooltip component side.

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.

What a fascinating problem, thanks for digging in @t-hamano! It looks like it might not just be us struggling with odd behaviour with select elements in Firefox, I found this bug report too, that seems tangentially related: https://bugzilla.mozilla.org/show_bug.cgi?id=1430892

Similar to @ciampo, in testing this PR, I found it a bit unreliable as to when it seemed to fix the issue and when it didn't. When I moved the mouse even slightly while interacting with the select component, it would still seem to be behave strangely sometimes resulting in the wrong unit being selected.

If I removed all of the eventHandlers from the Tooltip component that seemed to fare a little bit better 🤔

  • I think @ciampo makes a good point at seeing what we can do with the components in this repo that use select and see if there are fixes we need to implement there. But also:
  • The Tooltip component appears to add event handlers in order to emit events to its children — this behaviour seems to have been around a long time, but it also seems like it could be error-prone if it results in firing more events than it really should? Rather than just focusing on a single handler and element, do we need to revisit this behaviour across the eventHandlers in the component?
  • This might not be at all related, but I noticed that the SelectControl component provides a noop function for some of its on methods, e.g. here — could the presence of noop props be confusing the Tooltip component into emitting events when it shouldn't? (This is probably a long shot, but just thought I'd mention it, because I find the logic of the Tooltip component a little challenging to follow)

Not sure if any of that is helpful, but happy to do further testing of this PR tomorrow!

@aaronrobertshaw
Copy link
Contributor

Thanks for working on a fix for this @t-hamano 👍

While investigating #41845 earlier this afternoon, I found that the border radius control also has the same problem in Firefox that this PR attempts to resolve. A git bisect pointed to the addition of tooltips around the inner UnitControl components and, therefore, their unit selects as well. That appears to fit neatly with the other issues discussed here.

As @andrewserong and @ciampo mention, preventing the issue as close to the source as possible sounds good. I'm not sure how reliably we can count on that though if a simple <select> can be wrapped in a tooltip.

After checking out this PR I didn't have much success testing. The bug is still present for me.

Screen.Recording.2022-07-20.at.7.21.40.pm.mp4

@t-hamano
Copy link
Contributor Author

I have tested on Storybook to clarify the problems we are currently experiencing with trunk.

I believe the issue is a problem that occurs when a select element is wrapped in a Tooltip (In other words, BoxInputControls).
More interestingly, the units can be changed correctly by keyboard operation.

Therefore, I think we need to handle mousedown event correctly in Tooltip component.

8fb6386eb311714d0f4ae7c584112c56.mp4

@ciampo
Copy link
Contributor

ciampo commented Jul 21, 2022

I gave this PR another spin, and I think that the reason why the fix didn't work for me (or for Aaron and Andrew) is because the same early return added to the createMouseDown function, should be also added to the createMouseUp function

Suggested change
diff --git a/packages/components/src/tooltip/index.js b/packages/components/src/tooltip/index.js
index bbe410f50a..840232c248 100644
--- a/packages/components/src/tooltip/index.js
+++ b/packages/components/src/tooltip/index.js
@@ -133,6 +133,10 @@ function Tooltip( props ) {
 	};
 
 	const createMouseUp = ( event ) => {
+		if ( event.target.tagName === 'OPTION' ) {
+			return;
+		}
+
 		emitToChild( children, 'onMouseUp', event );
 		document.removeEventListener( 'mouseup', cancelIsMouseDown );
 		setIsMouseDown( false );

Having said that, I think it still makes sense to investigate a bit further what @andrewserong suggested

  • The Tooltip component appears to add event handlers in order to emit events to its children — this behaviour seems to have been around a long time, but it also seems like it could be error-prone if it results in firing more events than it really should? Rather than just focusing on a single handler and element, do we need to revisit this behaviour across the eventHandlers in the component?
  • This might not be at all related, but I noticed that the SelectControl component provides a noop function for some of its on methods, e.g. here — could the presence of noop props be confusing the Tooltip component into emitting events when it shouldn't? (This is probably a long shot, but just thought I'd mention it, because I find the logic of the Tooltip component a little challenging to follow)

With regards to where the fix should be applied:

A git bisect pointed to the #40983 and, therefore, their unit selects as well. That appears to fit neatly with the other issues discussed here.
...
Therefore, I think we need to handle mousedown event correctly in Tooltip component.

A fix to Tooltip could make sense too. As said earlier, in principle it would be good to fix this issue "at the source", although it may not be a perfect solution either, since the bug is related to the native select element in Firefox — and therefore, we could still replicate the bug if Tooltip was wrapped around a native <select>

@t-hamano
Copy link
Contributor Author

@ciampo

Thank you for the detailed explanation!

I gave this PR another spin, and I think that the reason why the fix didn't work for me (or for Aaron and Andrew) is because the same early return added to the createMouseDown function, should be also added to the createMouseUp function

May I commit the suggestion and test to see if it has been fully improved in other people's environments?

And I also couldn't think of an appropriate PR title to describe this issue.
If you have a good idea, could you rename the title?

@ciampo
Copy link
Contributor

ciampo commented Jul 22, 2022

May I commit the suggestion and test to see if it has been fully improved in other people's environments?

Of course! Feel free to commit and test :)

If this approach solves the issue, it would be interesting to understand if we can, as a follow-up, rewrite the Tooltip component in a less convoluted way (basically following @andrewserong's advice)

And I also couldn't think of an appropriate PR title to describe this issue. If you have a good idea, could you rename the title?

I'll see if I can come up with something!

@ciampo ciampo changed the title [Try] Tooltip: Don't re-render child components when select list is chosen Tooltip: avoid unnecessary re-renders of <select> child components Jul 22, 2022
@ciampo ciampo changed the title Tooltip: avoid unnecessary re-renders of <select> child components Tooltip: avoid unnecessary re-renders of <select> child elements Jul 22, 2022
@t-hamano
Copy link
Contributor Author

I have tested again #37856 / #38113 / #41845 which are the subjects of this resolution.
In my environment, they all appear to be resolved by this PR.

Copy link
Contributor

@ciampo ciampo left a comment

Choose a reason for hiding this comment

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

I have tested again #37856 / #38113 / #41845 which are the subjects of this resolution. In my environment, they all appear to be resolved by this PR.

Those issues seem to be fixed for me as well — thank you for working on this 🚀

It'd be great if you could work on a follow-up PR with the enhancements suggested in the previous messages.

@t-hamano
Copy link
Contributor Author

It'd be great if you could work on a follow-up PR with the enhancements suggested in the previous messages.

Is this what you are referring to?

  • The Tooltip component appears to add event handlers in order to emit events to its children — this behaviour seems to have been around a long time, but it also seems like it could be error-prone if it results in firing more events than it really should? Rather than just focusing on a single handler and element, do we need to revisit this behaviour across the eventHandlers in the component?
  • This might not be at all related, but I noticed that the SelectControl component provides a noop function for some of its on methods, e.g. here — could the presence of noop props be confusing the Tooltip component into emitting events when it shouldn't? (This is probably a long shot, but just thought I'd mention it, because I find the logic of the Tooltip component a little challenging to follow)

@ciampo
Copy link
Contributor

ciampo commented Jul 22, 2022

Is this what you are referring to?

  • The Tooltip component appears to add event handlers in order to emit events to its children — this behaviour seems to have been around a long time, but it also seems like it could be error-prone if it results in firing more events than it really should? Rather than just focusing on a single handler and element, do we need to revisit this behaviour across the eventHandlers in the component?
  • This might not be at all related, but I noticed that the SelectControl component provides a noop function for some of its on methods, e.g. here — could the presence of noop props be confusing the Tooltip component into emitting events when it shouldn't? (This is probably a long shot, but just thought I'd mention it, because I find the logic of the Tooltip component a little challenging to follow)

Yes. In particular, it looks like Tooltip is written in a very convoluted way, especially around event handlers. It would be good to understand if we can simplify its code!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Browser Issues Issues or PRs that are related to browser specific problems [Feature] UI Components Impacts or related to the UI component system [Package] Components /packages/components [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Changing the unit or value of dimension controls sometimes doesn't work in the site editor
4 participants