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: Fix Slot/Fill Emotion StyleProvider #38237

Merged
merged 5 commits into from
Jan 28, 2022

Conversation

ciampo
Copy link
Contributor

@ciampo ciampo commented Jan 26, 2022

Description

This PR contains a fix proposed by @youknowriad in #37551 (comment) which fixes an issue related to Emotion's StyleProvider when used in combination with Slot/Fill. In Riad's words:

The idea is that when you use a Fill, the children will be rendered in the document of the Slot meaning we need to wrap in another StyleProvider otherwise we'll be using the context of the parent of the Fill which can be any document/iframe and not necessarily the right one.

This PR also updated the useCx Storybook examples to include a couple of examples that wouldn't work before the fix in this PR. The main thing there was to use the IFrame element from @wordpress/block-editor, instead of a local replica.

We also tried to add a unit test but didn't manage due to the complexity introduced of the aforementioned IFrame component.

Testing Instructions

Screenshots

Types of changes

Fix

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • N/A I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).
  • N/A I've updated related schemas if appropriate.

@ciampo ciampo force-pushed the fix/components-style-provider-slot-fill branch from 82e7b62 to 2879634 Compare January 26, 2022 11:02
@github-actions
Copy link

github-actions bot commented Jan 26, 2022

Size Change: -2 B (0%)

Total Size: 1.14 MB

Filename Size Change
build/components/index.min.js 215 kB -2 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 960 B
build/admin-manifest/index.min.js 1.1 kB
build/annotations/index.min.js 2.75 kB
build/api-fetch/index.min.js 2.22 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.28 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
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 141 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 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 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 470 B
build/block-library/blocks/button/editor.css 470 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 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 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 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-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 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-query-loop/editor-rtl.css 95 B
build/block-library/blocks/comments-query-loop/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.22 kB
build/block-library/blocks/cover/style.css 1.22 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 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 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 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 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 965 B
build/block-library/blocks/gallery/editor.css 967 B
build/block-library/blocks/gallery/style-rtl.css 1.61 kB
build/block-library/blocks/gallery/style.css 1.61 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 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 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 810 B
build/block-library/blocks/image/editor.css 809 B
build/block-library/blocks/image/style-rtl.css 507 B
build/block-library/blocks/image/style.css 511 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 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 447 B
build/block-library/blocks/latest-posts/style.css 446 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 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 649 B
build/block-library/blocks/navigation-link/editor.css 650 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/view.min.js 343 B
build/block-library/blocks/navigation/editor-rtl.css 1.99 kB
build/block-library/blocks/navigation/editor.css 2 kB
build/block-library/blocks/navigation/style-rtl.css 1.85 kB
build/block-library/blocks/navigation/style.css 1.84 kB
build/block-library/blocks/navigation/view.min.js 2.81 kB
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 401 B
build/block-library/blocks/page-list/editor.css 402 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 273 B
build/block-library/blocks/paragraph/style.css 273 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/style-rtl.css 446 B
build/block-library/blocks/post-comments-form/style.css 446 B
build/block-library/blocks/post-comments/style-rtl.css 521 B
build/block-library/blocks/post-comments/style.css 521 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 721 B
build/block-library/blocks/post-featured-image/editor.css 721 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 323 B
build/block-library/blocks/post-template/style.css 323 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 389 B
build/block-library/blocks/pullquote/style.css 388 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 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 201 B
build/block-library/blocks/quote/style.css 201 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 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 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 245 B
build/block-library/blocks/separator/style.css 245 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 744 B
build/block-library/blocks/site-logo/editor.css 744 B
build/block-library/blocks/site-logo/style-rtl.css 181 B
build/block-library/blocks/site-logo/style.css 181 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.37 kB
build/block-library/blocks/social-links/style.css 1.36 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 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 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 214 B
build/block-library/blocks/tag-cloud/style.css 215 B
build/block-library/blocks/template-part/editor-rtl.css 560 B
build/block-library/blocks/template-part/editor.css 559 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 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 908 B
build/block-library/common.css 905 B
build/block-library/editor-rtl.css 10.1 kB
build/block-library/editor.css 10.1 kB
build/block-library/index.min.js 166 kB
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 10.8 kB
build/block-library/style.css 10.8 kB
build/block-library/theme-rtl.css 672 B
build/block-library/theme.css 676 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/blocks/index.min.js 46.4 kB
build/components/style-rtl.css 15.5 kB
build/components/style.css 15.5 kB
build/compose/index.min.js 11.2 kB
build/core-data/index.min.js 13.4 kB
build/customize-widgets/index.min.js 11.4 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 631 B
build/data/index.min.js 7.49 kB
build/date/index.min.js 31.9 kB
build/deprecated/index.min.js 485 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.5 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 3.76 kB
build/edit-navigation/style.css 3.76 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 29.6 kB
build/edit-post/style-rtl.css 7.15 kB
build/edit-post/style.css 7.14 kB
build/edit-site/index.min.js 41.5 kB
build/edit-site/style-rtl.css 7.22 kB
build/edit-site/style.css 7.21 kB
build/edit-widgets/index.min.js 16.5 kB
build/edit-widgets/style-rtl.css 4.17 kB
build/edit-widgets/style.css 4.17 kB
build/editor/index.min.js 38.4 kB
build/editor/style-rtl.css 3.71 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 3.29 kB
build/escape-html/index.min.js 517 B
build/format-library/index.min.js 6.58 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.63 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.75 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.8 kB
build/keycodes/index.min.js 1.39 kB
build/list-reusable-blocks/index.min.js 1.72 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.92 kB
build/notices/index.min.js 925 B
build/nux/index.min.js 2.08 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.84 kB
build/primitives/index.min.js 924 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 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.65 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 kB
build/server-side-render/index.min.js 1.58 kB
build/shortcode/index.min.js 1.49 kB
build/token-list/index.min.js 639 B
build/url/index.min.js 1.9 kB
build/viewport/index.min.js 1.05 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 7.15 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@ciampo
Copy link
Contributor Author

ciampo commented Jan 26, 2022

I also spent some time trying to create a Storybook example illustrating the issue that is PR aims to fix, but I couldn't come up with a good example — can someone else also help here?

While doing so, I added one of the examples that @sarayourfriend described in #37551 (comment), which still appears broken (the black text is supposed to be blue):

Screenshot 2022-01-26 at 12 15 03

Could this be related to a separate problem with IFrame and StyleProvider, with a potential solution being what proposed by @sarayourfriend in #37551 (comment) ?

@ciampo ciampo added [Feature] Component System WordPress component system [Package] Components /packages/components [Type] Bug An existing feature does not function as intended labels Jan 26, 2022
<Slot name="test-slot" />
</StyleProvider>
</IFrame>
<Slot name="outside-frame" />
Copy link
Contributor

Choose a reason for hiding this comment

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

can you try bubblesVirtually prop here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tried, but it doesn't seem to make a difference

Screenshot 2022-01-26 at 12 26 48

Copy link
Contributor

Choose a reason for hiding this comment

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

My fix for sure is specific to "bubblesVirtually" implementation which is the one we prefer in Gutenberg in general. (the other is more "historic"). I don't know why it's not working though in storybook, the blue text is the exact same use case as spinner it seems 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

This is slightly different though as in the story we've wrapped the Slot in a StyleProvider as well. Are we doing that in usage in Gutenberg?

This is why I was confused because I was actually able to solve the problem with the <StyleProvider><Slot /></StyleProvider> with the context based code that @ciampo and I came up with that I shared here: #37551 (comment)

But it didn't work to fix the spinner.

Which makes me thing that this story, as constructed currently, while it raises an edge case that we need to cover, is actually a red herring when compared to the spinner case (and probably the preview iframe issue you were having before @youknowriad).

In short: I don't believe we've been able to actually reproduce the issue that was being found in Gutenberg in the story yet.

If I'm understanding the fix for the GB issue correctly, the minimal reproduction would just be:

<Iframe>
  <Fill name="test"><Example /></Fill>
</Iframe>
<Slot name="test" />

And indeed, that is what appears to happen in Gutenberg. But in the story, when you try this, it worked perfectly fine.

It's just occurred to me that potentially it could be because the story is running in an iframe? I didn't get around to trying that minimal reproduction story popped out into it's own document so maybe that would make it possible to reproduce (though should theoretically not matter if we consider that any iframe can just be the "root" document of the page, it doesn't have to be the root document of the window).

Who knows!

Copy link
Contributor Author

@ciampo ciampo Jan 26, 2022

Choose a reason for hiding this comment

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

I think I managed to work out a Storybook example which breaks before this fix, and works after this fix.

In an effort to replicate as closely as possible the issue that we're trying to reproduce:

  • I replaced the local IFrame component with the Iframe component from @wordpress/block-editor
  • I added bubblesVirtually to both <Slot>s
without the fix in this PR with the fix in this PR, but without bubblesVirtually with the fix in this PR, and with bubblesVirtually
Screenshot 2022-01-26 at 18 48 18 Screenshot 2022-01-26 at 18 55 54 Screenshot 2022-01-26 at 18 50 32

A couple more notes:

  • changing the iframe component seems to be what "allowed the example to be broken"
  • adding bubblesVirtually allowed the slot to receive the fix from this PR

I guess an interesting thing would be to understand what was the difference between the two IFrame components?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I managed to get around the IFrame loading with a bit of a hacky approach as nothing else seemed to work me, but the problem seems to be related to the contents of createPortal not being rendered (or maybe simply "seen"?) by Jest / RTL.

These are the changes that I made so far (I've also added some "debugging" spans to the Iframe component to help with troubleshooting):

Click to see diff
diff --git a/packages/block-editor/src/components/iframe/index.js b/packages/block-editor/src/components/iframe/index.js
index b4e1e44f65..d9cc27a1be 100644
--- a/packages/block-editor/src/components/iframe/index.js
+++ b/packages/block-editor/src/components/iframe/index.js
@@ -267,23 +267,33 @@ function Iframe(
 				title={ __( 'Editor canvas' ) }
 			>
 				{ iframeDocument &&
-					createPortal(
-						<>
-							<head ref={ headRef }>{ head }</head>
-							<body
-								ref={ bodyRef }
-								className={ classnames(
-									BODY_CLASS_NAME,
-									...bodyClasses
+					( () => {
+						return (
+							<>
+								<span>Outside the portal</span>
+								{ createPortal(
+									<>
+										<head ref={ headRef }>{ head }</head>
+										<body
+											ref={ bodyRef }
+											className={ classnames(
+												BODY_CLASS_NAME,
+												...bodyClasses
+											) }
+										>
+											<StyleProvider
+												document={ iframeDocument }
+											>
+												<span>Inside the portal!</span>
+												{ children }
+											</StyleProvider>
+										</body>
+									</>,
+									iframeDocument.documentElement
 								) }
-							>
-								<StyleProvider document={ iframeDocument }>
-									{ children }
-								</StyleProvider>
-							</body>
-						</>,
-						iframeDocument.documentElement
-					) }
+							</>
+						);
+					} )() }
 			</iframe>
 			{ tabIndex >= 0 && after }
 		</>
diff --git a/packages/components/src/utils/hooks/test/use-cx.js b/packages/components/src/utils/hooks/test/use-cx.js
index 181e0beeca..947158f0ad 100644
--- a/packages/components/src/utils/hooks/test/use-cx.js
+++ b/packages/components/src/utils/hooks/test/use-cx.js
@@ -4,14 +4,29 @@
 // eslint-disable-next-line no-restricted-imports
 import { cx as innerCx } from '@emotion/css';
 import { insertStyles } from '@emotion/utils';
-import { render } from '@testing-library/react';
+import {
+	screen,
+	render,
+	waitFor,
+	waitForElementToBeRemoved,
+} from '@testing-library/react';
 import { css, CacheProvider } from '@emotion/react';
 import createCache from '@emotion/cache';
 
+/**
+ * WordPress dependencies
+ */
+import { __unstableIframe as Iframe } from '@wordpress/block-editor';
+import { useState } from '@wordpress/element';
+
 /**
  * Internal dependencies
  */
 import { useCx } from '..';
+import {
+	createSlotFill,
+	Provider as SlotFillProvider,
+} from '../../../slot-fill';
 
 jest.mock( '@emotion/css', () => ( {
 	cx: jest.fn(),
@@ -61,4 +76,65 @@ describe( 'useCx', () => {
 			false
 		);
 	} );
+
+	it( 'should work correctly when using slot/fill in combination with an IFrame', async () => {
+		// const { Fill, Slot } = createSlotFill( 'UseCxTest' );
+
+		// const redText = css`
+		// 	color: red;
+		// `;
+
+		// const TestComponent = () => {
+		// 	const [ iframeIsLoading, setIframeIsLoading ] = useState( true );
+
+		// 	return (
+		// 		<SlotFillProvider>
+		// 			{ iframeIsLoading && (
+		// 				<span data-testid="iframe-loading">Loading</span>
+		// 			) }
+		// 			<Iframe onLoad={ () => setIframeIsLoading( false ) }>
+		// 				<span data-testid="iframe-simple-content">
+		// 					Iframe Content
+		// 				</span>
+		// 				<Fill name="test-slot">
+		// 					<Example args={ [ redText ] }>
+		// 						This text should be red
+		// 					</Example>
+		// 				</Fill>
+		// 			</Iframe>
+		// 			<Slot bubblesVirtually name="test-slot" />
+		// 		</SlotFillProvider>
+		// 	);
+		// };
+
+		const SimplifiedTestComponent = () => {
+			const [ iframeIsLoading, setIframeIsLoading ] = useState( true );
+			return (
+				<div>
+					{ iframeIsLoading && (
+						<span data-testid="iframe-loading">Loading</span>
+					) }
+					<Iframe onLoad={ () => setIframeIsLoading( false ) }>
+						<span data-testid="iframe-simple-content">
+							Iframe Content
+						</span>
+					</Iframe>
+				</div>
+			);
+		};
+
+		const { debug } = render( <SimplifiedTestComponent /> );
+
+		let loadingSpy;
+		await waitFor( () => {
+			loadingSpy = screen.getByTestId( 'iframe-loading' );
+			expect( loadingSpy ).toBeInTheDocument();
+		} );
+
+		await waitFor( () => expect( loadingSpy ).not.toBeInTheDocument() );
+
+		// <span>Outside the portal</span> is printed out
+		// <span>Inside the portal!</span> is NOT printed out (together with the rest of the children)
+		debug();
+	} );
 } );

If anyone has the time to take a look as well it'd be great! Otherwise I plan on spending a little bit more time on it tomorrow.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just checking if you tried the suggestion in this issue? testing-library/react-testing-library#62

I never really ran into any problems testing portals as far as I can remember but I might have just gotten lucky and avoided testing them directly so far!

Seems like the trick is to pass an extra container: document.body argument to render.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately adding { container: document.body } as an additional argument to render triggers a warning, and the renderIntoDocument method (also mentioned in that issue) is deprecated.

I've tried to get inspiration from this example but as soon as the portal doesn't render in the iframeDocument.documentElement, more errors appear (for example, ownerNode here becomes undefined).

Since I've almost spent 2 days on this without managing to get a working unit test, I'm going to merge this PR as-is in order to unblock #37551

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have a feeling that the fix from #37551 (comment) might be relevant to #35619 (comment) in a way that the fix in this current PR doesn't seem to be. I will try that out tomorrow.

Did you manage to have a look at this at all? If not, I can try to also look into it later today / on Monday.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was away from my computer yesterday so I didn't get to, but if I have time to look into it today I will!

Copy link
Contributor

@sarayourfriend sarayourfriend left a comment

Choose a reason for hiding this comment

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

LGTM. Nice find y'all!

@ciampo ciampo force-pushed the fix/components-style-provider-slot-fill branch from 686e848 to e15e9de Compare January 27, 2022 14:56
@ciampo ciampo merged commit d8ab9a1 into trunk Jan 28, 2022
@ciampo ciampo deleted the fix/components-style-provider-slot-fill branch January 28, 2022 13:20
@github-actions github-actions bot added this to the Gutenberg 12.6 milestone Jan 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Component System WordPress 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.

3 participants