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

ToggleGroupControl: rewrite backdrop animation with framer-motion's shared layout animations #40276

Closed

Conversation

ciampo
Copy link
Contributor

@ciampo ciampo commented Apr 12, 2022

What?

Completely rewrite the ToggleGroupControl 's animated backdrop using framer-motion's shared layout animations.

Supersedes #40107

Fixes #37506

Why?

Current implementation is complex, difficult to read, imperative (based off arbitrary timeouts), and buggy.

How?

Main changes are:

  • deleted the ToggleGroupControlBackdrop, and the imperative logic that came with it
  • re-implemented the backdrop using framer-motion's shared layout animations:
    • the main way this works is by using the same value for the layoutId attribute to tag the components that participate to the same shared layout animation
    • each ToggleGroupControl also defines its own "namespace" for the shared layout animations via the LayoutGroup component, in order to avoid conflicts between different instances of the component
  • cleanup up some styles and removed some unused variables
  • memoized some classnames

Testing Instructions

Make sure that the backdrop animation works as expected:

Screenshots or screencast

toggle-group-control-backdrop-shared-layout-animation-storybook.mp4

@ciampo ciampo self-assigned this Apr 12, 2022
@ciampo ciampo changed the title Feat/toggle group control backdrop animation framer motion ToggleGroupControl: rewrite backdrop animation with framer-motion's shared layout animations Apr 12, 2022
@github-actions
Copy link

github-actions bot commented Apr 12, 2022

Size Change: +180 B (0%)

Total Size: 1.27 MB

Filename Size Change
build/components/index.min.js 202 kB +120 B (0%)
build/edit-site/index.min.js 57.8 kB +60 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 7.09 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 168 kB
build/block-editor/style-rtl.css 15.5 kB
build/block-editor/style.css 15.5 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 90 B
build/block-library/blocks/archives/style.css 90 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 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 126 B
build/block-library/blocks/audio/theme.css 126 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 84 B
build/block-library/blocks/avatar/style.css 84 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 482 B
build/block-library/blocks/button/editor.css 482 B
build/block-library/blocks/button/style-rtl.css 523 B
build/block-library/blocks/button/style.css 523 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 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 100 B
build/block-library/blocks/categories/style.css 100 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 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 612 B
build/block-library/blocks/cover/editor.css 613 B
build/block-library/blocks/cover/style-rtl.css 1.57 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 126 B
build/block-library/blocks/embed/theme.css 126 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 394 B
build/block-library/blocks/group/editor.css 394 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 884 B
build/block-library/blocks/image/editor.css 882 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 126 B
build/block-library/blocks/image/theme.css 126 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 213 B
build/block-library/blocks/latest-posts/editor.css 212 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 507 B
build/block-library/blocks/media-text/style.css 505 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/editor-rtl.css 2.02 kB
build/block-library/blocks/navigation/editor.css 2.03 kB
build/block-library/blocks/navigation/style-rtl.css 2.17 kB
build/block-library/blocks/navigation/style.css 2.16 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 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 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-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 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 586 B
build/block-library/blocks/post-featured-image/editor.css 584 B
build/block-library/blocks/post-featured-image/style-rtl.css 315 B
build/block-library/blocks/post-featured-image/style.css 315 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/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 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 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 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 326 B
build/block-library/blocks/pullquote/style.css 325 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 282 B
build/block-library/blocks/query-pagination/style.css 278 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 439 B
build/block-library/blocks/query/editor.css 439 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 409 B
build/block-library/blocks/search/style.css 406 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 234 B
build/block-library/blocks/separator/style.css 234 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 490 B
build/block-library/blocks/site-logo/editor.css 490 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 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 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 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.4 kB
build/block-library/blocks/social-links/style.css 1.39 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 190 B
build/block-library/blocks/table/theme.css 190 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 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 691 B
build/block-library/blocks/video/editor.css 694 B
build/block-library/blocks/video/style-rtl.css 174 B
build/block-library/blocks/video/style.css 174 B
build/block-library/blocks/video/theme-rtl.css 126 B
build/block-library/blocks/video/theme.css 126 B
build/block-library/classic-rtl.css 162 B
build/block-library/classic.css 162 B
build/block-library/common-rtl.css 1.02 kB
build/block-library/common.css 1.02 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11.2 kB
build/block-library/editor.css 11.2 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 191 kB
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 12.3 kB
build/block-library/style.css 12.3 kB
build/block-library/theme-rtl.css 719 B
build/block-library/theme.css 722 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 49.8 kB
build/components/style-rtl.css 11.3 kB
build/components/style.css 11.3 kB
build/compose/index.min.js 12.2 kB
build/core-data/index.min.js 15.5 kB
build/customize-widgets/index.min.js 11.3 kB
build/customize-widgets/style-rtl.css 1.38 kB
build/customize-widgets/style.css 1.38 kB
build/data-controls/index.min.js 653 B
build/data/index.min.js 8.08 kB
build/date/index.min.js 32.1 kB
build/deprecated/index.min.js 507 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.7 kB
build/edit-navigation/index.min.js 16.1 kB
build/edit-navigation/style-rtl.css 3.99 kB
build/edit-navigation/style.css 4 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 31.8 kB
build/edit-post/style-rtl.css 7.13 kB
build/edit-post/style.css 7.13 kB
build/edit-site/style-rtl.css 8.37 kB
build/edit-site/style.css 8.35 kB
build/edit-widgets/index.min.js 16.7 kB
build/edit-widgets/style-rtl.css 4.34 kB
build/edit-widgets/style.css 4.34 kB
build/editor/index.min.js 41.7 kB
build/editor/style-rtl.css 3.62 kB
build/editor/style.css 3.61 kB
build/element/index.min.js 4.68 kB
build/escape-html/index.min.js 537 B
build/experiments/index.min.js 868 B
build/format-library/index.min.js 6.95 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.83 kB
build/list-reusable-blocks/index.min.js 2.13 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 963 B
build/nux/index.min.js 2.06 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.33 kB
build/primitives/index.min.js 933 B
build/priority-queue/index.min.js 1.58 kB
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.74 kB
build/reusable-blocks/index.min.js 2.21 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.6 kB
build/server-side-render/index.min.js 1.77 kB
build/shortcode/index.min.js 1.53 kB
build/style-engine/index.min.js 1.46 kB
build/token-list/index.min.js 644 B
build/url/index.min.js 3.61 kB
build/vendors/inert-polyfill.min.js 2.48 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.21 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.19 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@ciampo
Copy link
Contributor Author

ciampo commented Apr 12, 2022

For some reason, it looks like the new approach doesn't work in the block inspector controls:

togglegroucontrol-block-inspector.mp4

While it seems to work just fine in the Site editor:

togglegroupcontrol-site-editor.mp4

I wonder if the problem is related InspectorControls.Slot and more in general the slot-fill mechanism — I pushed a temporary change (9b63e86) to show how the same component works fine outside of the slot, but doesn't inside the slot.

@aaronrobertshaw maybe you could you help here? I'm not really knowledgeable about this part of the codebase

@stokesman
Copy link
Contributor

Awesome @ciampo! This was actually the first approach I tried and I ran into the same issue. I spent plenty of time trying to work around it and didn't find a solution that worked in every situation. I didn't realize it worked fine inside of Site Editor or outside of that slot so maybe that can lead the investigation somewhere more fruitful.

If we can figure out what is going on in this inspector slot it might help fix other issues. It's great that you've isolated it.

@aaronrobertshaw
Copy link
Contributor

aaronrobertshaw commented Apr 13, 2022

I wonder if the problem is related InspectorControls.Slot and more in general the slot-fill mechanism — I pushed a temporary change (9b63e86) to show how the same component works fine outside of the slot, but doesn't inside the slot.

We can probably narrow the investigation further to just the block editor's InspectorControls slot.

I created an extra storybook example rendering the ToggleGroupControl via a slot (with and without virtual bubbling) and it appears to work OK.

ToggleGroupControl SlotFill Example
diff --git a/packages/components/src/toggle-group-control/stories/index.js b/packages/components/src/toggle-group-control/stories/index.js
index d56541974d..9cbb82a84f 100644
--- a/packages/components/src/toggle-group-control/stories/index.js
+++ b/packages/components/src/toggle-group-control/stories/index.js
@@ -18,6 +18,7 @@ import {
 	ToggleGroupControlOptionIcon,
 } from '../index';
 import { View } from '../../view';
+import { createSlotFill, Provider as SlotFillProvider } from '../../slot-fill';
 import Button from '../../button';
 
 export default {
@@ -232,3 +233,38 @@ export const DoubleToggles = () => {
 		</View>
 	);
 };
+
+const { Fill: InspectorControls, Slot } = createSlotFill( 'InspectorControls' );
+InspectorControls.Slot = Slot;
+
+// TODO: Remove before merging as well.
+export const RenderViaSlot = () => {
+	const [ alignState, setAlignState ] = useState();
+	const aligns = [ 'Left', 'Center', 'Right' ];
+
+	return (
+		<SlotFillProvider>
+			<InspectorControls>
+				<ToggleGroupControl
+					onChange={ setAlignState }
+					value={ alignState }
+					label={ 'Pick an alignment option' }
+				>
+					{ aligns.map( ( key ) => (
+						<ToggleGroupControlOption
+							key={ key }
+							value={ key }
+							label={ key }
+						/>
+					) ) }
+				</ToggleGroupControl>
+			</InspectorControls>
+			<View>
+				<InspectorControls.Slot bubblesVirtually />
+				<Button onClick={ () => setAlignState( undefined ) } isTertiary>
+					Reset
+				</Button>
+			</View>
+		</SlotFillProvider>
+	);
+};
Screen.Recording.2022-04-13.at.4.23.31.pm.mp4

@ciampo
Copy link
Contributor Author

ciampo commented Apr 19, 2022

Alright, I spent the past couple of days looking into it until I found the cause of the issue:

basically, the ToggleGroupControl component that gets injected via Slot/Fill is initially rendered in another part of the React Tree — when the motion elements used for the backdrop animation are mounted, they initially take, as their parent motion element, the two motion.div elements defined in the VisualEditor, even if that wouldn't be true anymore after they get "teleported" via Slot/Fill to the block controls in the sidebar.

This mismatch causes some issues (which I haven't pinpointed exactly yet) in framer-motion's node projection logic, which basically prevents motion from calculating correctly the sizes and transformations to apply during the animation.

This can be verified by:

  • swapping motion.div with a simple div in the VisualEditor component , which should temporarily fix the issue in the sidebar
  • checking out the new Storybook example that I added in the last commit, where I took @aaronrobertshaw 's latest code snippet and simply wrapped the InspectorControls fill inside a motion.div — the animations in this story should not work (unless the motion.div is swapped with a regular div)

I'm not sure yet if there's a solution here that will fix this incompatibility between framer-motion and Slot/Fill (react portals), but at least now we have a way to reproduce the issue!

@ciampo
Copy link
Contributor Author

ciampo commented Apr 25, 2022

I spent some more time investigating the issue and I managed to reproduce it even more in isolation:

  • using a custom, simpler version of a Toggle component
  • using the same dependency versions as in this PR (react@17.0.2, framer-motion@6.2.8)
  • using both Slot/Fill from @wordpress/components, but also a vanilla React portal

You can see the little demo I built on CodeSandbox here.

As for the next steps, I'm a bit out of ideas — I'm probably going to open I opened an issue on the framer-motion repository (motiondivision/motion#1524), but I wonder if anyone else here has any ideas about how to potentially fix this on our end? (@youknowriad maybe you could take a look?)

@ciampo ciampo force-pushed the feat/toggle-group-control-backdrop-animation-framer-motion branch from 6234828 to 7d113e0 Compare October 17, 2022 15:46
@ciampo
Copy link
Contributor Author

ciampo commented Oct 17, 2022

Update:

following a piece of advice shared in motiondivision/motion#1524 (comment), I managed to get shared layout animations in ToggleGroupControl working also in Slot/Fills (i.e InspectorControls) (commit with the fix).

There's still one final issue left: somehow, when selecting a block that has an assigned font-size, the selected option animates down unexpectedly:

Kapture.2022-10-17.at.20.48.40.mp4

I haven't managed to isolate the cause yet, but it seems related to the block editor specifically (both post editor and site editor) — I haven't been able to reproduce it in Storybook for the FontSizePicker component.

Has anyone got any ideas on what could cause this animation glitch?

@ciampo
Copy link
Contributor Author

ciampo commented Oct 17, 2022

Update: in an effort to isolate the cause of the glitch, I experimented with:

  • tweaking FontSizeEdit so that the internal font size value is hardcoded (i.e it's not read/written dynamically from the settings)
  • rendering the same FontSizeEdit component in the sidebar without nesting it in ToolsPanel / SlotFill
See code diff
diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js
index 379d8806f2..37c37ae3c4 100644
--- a/packages/block-editor/src/components/block-inspector/index.js
+++ b/packages/block-editor/src/components/block-inspector/index.js
@@ -35,6 +35,7 @@ import BlockVariationTransforms from '../block-variation-transforms';
 import useBlockDisplayInformation from '../use-block-display-information';
 import { store as blockEditorStore } from '../../store';
 import BlockIcon from '../block-icon';
+import { FontSizeEdit } from '../../hooks/font-size';
 
 function useContentBlocks( blockTypes, block ) {
 	const contenBlocksObjectAux = useMemo( () => {
@@ -260,6 +261,8 @@ const BlockInspectorSingleBlock = ( { clientId, blockName } ) => {
 				label={ __( 'Color' ) }
 				className="color-block-support-panel__inner-wrapper"
 			/>
+
+			<FontSizeEdit />
 			<InspectorControls.Slot
 				__experimentalGroup="typography"
 				label={ __( 'Typography' ) }
diff --git a/packages/block-editor/src/hooks/font-size.js b/packages/block-editor/src/hooks/font-size.js
index f8fa94538f..0c8b5fcb33 100644
--- a/packages/block-editor/src/hooks/font-size.js
+++ b/packages/block-editor/src/hooks/font-size.js
@@ -114,41 +114,10 @@ function addEditProps( settings ) {
  *
  * @return {WPElement} Font size edit element.
  */
-export function FontSizeEdit( props ) {
-	const {
-		attributes: { fontSize, style },
-		setAttributes,
-	} = props;
-	const fontSizes = useSetting( 'typography.fontSizes' );
-
-	const onChange = ( value ) => {
-		const fontSizeSlug = getFontSizeObjectByValue( fontSizes, value ).slug;
-
-		setAttributes( {
-			style: cleanEmptyObject( {
-				...style,
-				typography: {
-					...style?.typography,
-					fontSize: fontSizeSlug ? undefined : value,
-				},
-			} ),
-			fontSize: fontSizeSlug,
-		} );
-	};
-
-	const fontSizeObject = getFontSize(
-		fontSizes,
-		fontSize,
-		style?.typography?.fontSize
-	);
-
-	const fontSizeValue =
-		fontSizeObject?.size || style?.typography?.fontSize || fontSize;
-
+export function FontSizeEdit() {
 	return (
 		<FontSizePicker
-			onChange={ onChange }
-			value={ fontSizeValue }
+			value={ '2.25rem' }
 			withReset={ false }
 			size="__unstable-large"
 			__nextHasNoMarginBottom
Kapture.2022-10-17.at.21.34.44.mp4

In my tests, the FontSizeEdit that is not rendered inside ToolsPanel / SlotFill does not suffer from the glitch — and so the issue could be related to either SlotFill or ToolsPanel.


I then tested this theory in this CodeSandbox, and it looks like wrapping the component in SlotFill causes the initial animation to glitch:

Kapture.2022-10-17.at.21.42.01.mp4

@youknowriad , this is not high priority, but it would be great if you could take a look at this. Also happy to pair on this issue together!

@youknowriad
Copy link
Contributor

@ciampo At this point, I admit I was not able to understand why this is happening. Do you know any wild guesses?

@ciampo
Copy link
Contributor Author

ciampo commented May 3, 2023

After the update to a more recent framer motion version, I wanted to test and see if the situation improved. I tried rebasing but ToggleGroupControl has changed a lot since this PR was opened, and so I decided to open a new PR: #50278

Going to close this PR, we can continue the conversation there.

@ciampo ciampo closed this May 3, 2023
@youknowriad youknowriad deleted the feat/toggle-group-control-backdrop-animation-framer-motion branch May 3, 2023 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] UI Components Impacts or related to the UI component system [Package] Components /packages/components [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Color select component backdrop render and animation opportunities
4 participants