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

Injecting styles into new windows opened via window.open #1229

Closed
TejasQ opened this issue Feb 13, 2019 · 11 comments
Closed

Injecting styles into new windows opened via window.open #1229

TejasQ opened this issue Feb 13, 2019 · 11 comments

Comments

@TejasQ
Copy link

TejasQ commented Feb 13, 2019

  • emotion version: 9.2.5
  • react version: 16.8.2

Relevant code:

const popupWindow = window.open("", target, openOptionsToString(options));
popupWindowRef.current = popupWindow;

// I need to do this because my styles aren't injected into `popupWindow`.
popupWindow.document.head.innerHTML = window.document.head.innerHTML;

React.createPortal(props.children, popupWindowRef.current.document.body)

What you did:
Given a component and the snippet above,

<ShowInNewWindow>
  hello world
</ShowInNewWindow

The "hello world" rendered in the new window is rendered without any styling whatsoever, even though the page that triggered the new window has styles added to its <head>.

Reproduction:
Edit 24p0lk4oyj

Full reproduction on CodeSandbox

Expected
The contents of the new window receive the same styling as the source window.

What I find particularly interesting is that the components on the new window have computed classNames – so that part works. It's just that there are no styles injected into <head> that is throwing me off.

cc @stereobooster who showed me this issue

@TejasQ TejasQ changed the title Question: preserving styles on new windows opened via window.open Injecting styles into new windows opened via window.open Feb 13, 2019
@Andarist
Copy link
Member

This should be quite easily doable with emotion@10 using CacheProvider and such, but I see you are on emotion@9.

It's not as easy as copying innerHTML (at least not for the production path) - I can't see in your sandbox where do you attempt to do that though.

I've prepared a quick demo for you how you can achieve this now - https://codesandbox.io/s/jv0jr2j2ny . This was a quick hack, so I have not tested this thoroughly - it shows the idea though.

@Vaexqua
Copy link

Vaexqua commented May 24, 2019

@Andarist What would be the approach for doing this with CacheProvider? The link to the cache options in the docs is broken, so I'm not really sure what to look for...

@TejasQ
Copy link
Author

TejasQ commented Jun 28, 2019

Hi everyone. I'd like to pick up the discussion here because it currently ails us. We're on emotion 10 as well. We'll be happy to make a PR if pointed in the right direction.

@Andarist
Copy link
Member

Wont this work for you - #760 (comment) ?

@Andarist
Copy link
Member

This problem is quite easily solvable with CacheProvider. Docs are live here - https://emotion.sh/docs/cache-provider . I hope this helps you - if not, please feel free to raise a new issue so we can discuss more (I promise you won't wait for a response as long as you did in the past).

@RPDeshaies
Copy link

Hey @Andarist, I just read the doc, and I was wondering if you all had any example showing this live in action with React using this CacheProvider?

Thanks! :)

@Andarist
Copy link
Member

Andarist commented May 6, 2021

If you set up a CodeSandbox that would do what you want, just without styling, then I could probably showcase this to you.

@RPDeshaies
Copy link

Here you go 😄

It doesn't refresh the setState when the modal is closed, but I think it's relatively good enough to see what I'm trying to achieve.

https://codesandbox.io/s/admiring-fog-xsjnj?file=/src/App.tsx

Thanks in advance

@tomconnors
Copy link

I'm also having difficulty styling components in a window opened with window.open. I forked @RPDeshaies' sandbox and added the CacheProvider, but I'm still unable to style anything in the external window. I'm creating the cache w/ createCache({key: "my-cache", container: externalWindow.document.head}), and passing that cache as the value for the CacheProvider component. Is this the intended API usage?

https://codesandbox.io/s/elastic-visvesvaraya-ucypu

@Andarist
Copy link
Member

Andarist commented Jun 2, 2021

@RPDeshaies sorry for the late reply but here you go: https://codesandbox.io/s/silly-burnell-c4ncs?file=/src/App.tsx . For this use case, it's much better to use @emotion/react than @emotion/css because you can easily target any window/frame without your component caring about it. It's all thanks to the CacheProvider

@tomconnors your sandbox is very similar to the one provided by @RPDeshaies so I won't be making it work - I think it should become much more clear how to achieve that based on my fork of the sandbox provided by @RPDeshaies . One of the key things here is to use css from @emotion/react. It is all doable with @emotion/css but it can't be achieved in such a clean way - you would have to resort to @emotion/css/create-instance and pass that instance around so it could be used in place of the default instance provided by @emotion/css

@tomconnors
Copy link

@Andarist Thanks! This solved my problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants