Closed 318097 closed 2 years ago
Same problem here with styled-components
export const StyledFrame = ({ children, ...rest }) => (
<Frame {...rest}>
<FrameContextConsumer>
{
(frameContext) => (
<StyleSheetManager target={frameContext.document.head}>
<>{children}</>
</StyleSheetManager>
)
}
</FrameContextConsumer>
</Frame>
);
iframe's head remains empty :(
@vittorio can you create a codesandbox.io showing the problem please
@ryanseddon nevermind, it was a problem with children
not with Frame
. Sorry, example above is working just fine.
@ryanseddon - Hey, I have a sandbox that I forked from one of the solutions provided on StackOverflow. It's by the creators of Emotion I guess.
Here is the sandbox link
Note: Test
component has 2 buttons rendered -
mantine
library - latest version uses emotion
codedrops/react-ui
- my custom library. uses styled-components
When Test
is rendered outside Frame
it works fine but inside the frame, it loses the CSS.
Please help.
@ryanseddon nevermind, it was a problem with
children
not withFrame
. Sorry, example above is working just fine.
Can you please show me how you did it? Can you share codesandbox?
@ryanseddon I have created a new sandbox that shows how the component is rendered:
Frame
Frame
along with StyleSheetManager
Here is the link
The component should look the same in an iframe and outside the iframe.
@ryanseddon nevermind, it was a problem with
children
not withFrame
. Sorry, example above is working just fine.Can you please show me how you did it? Can you share codesandbox?
Exactly like here https://github.com/ryanseddon/react-frame-component/issues/208#issuecomment-1012324213
@ryanseddon nevermind, it was a problem with
children
not withFrame
. Sorry, example above is working just fine.Can you please show me how you did it? Can you share codesandbox?
Exactly like here #208 (comment)
I have implemented it here - https://codesandbox.io/s/load-styled-components-emotion-into-iframe-forked-v4kgc?file=/src/index.js
It's not working for external libraries. Can you suggest what can be done?
@318097 are your external libraries styles build with styled-components or just injected via <link>
?
@vittorio - It's build with styled-components
and one is built with emotion
@318097 try to add
<Frame initialContent={`<!DOCTYPE html><html><head>${document.head.innerHTML.toString()}</head><body><div></div></body></html>`} {...rest}>
to copy everything from parent's head into iframe
@vittorio will try it out
@vittorio - It's not working. Thanks anyways :)
@318097 I responded to the discussion in the mantine repo. Essentially mantine needs to expose some apis within the emotion library which supports injecting styles into another container. Closing this as it's an issue with mantine.
@ryanseddon Thanks. But then all the external libraries which make use of CSS-in-JS need to expose that API? Because I can really understand if updates are needed from CSS-in-JS libraries (styled-components, emotion), UI libraries making use of CSS-in-JS packages (mantine), or the iframe/shadow DOM libraries (react-frame-components)
Lol..Just stuck in a loop
But Thank you @ryanseddon for helping out with whatever you could :)
I think there is a way around it without having to rely on mantine to expose the apis, you'd have to install @emotion/cache
and @emotion/core
as direct dependencies which should dedupe for mantine. With that you then createCache and use the provider to pass down the configuration and in theory mantine will pick up that.
I'll try and have a play around with it when I get some free time.
Sure will try that. I would have to rewrite my app & library if I don't get a solution.
Please share codesandbox if you find a solution. I am trying variations of Vittorio's solution.
@318097 Did you ever get this working? I tried the solution over at the mantine thread but I didn't get any styles.
In the end, this is what worked for me. Hopefully it works well when there are a lot of components in the iframe. 🤔
const emotionStyles =
typeof document === "object"
? Array.from(
(document as any).head.querySelectorAll(`style[data-emotion]`),
)
: []
<FrameContextConsumer>
{({ document }) => {
setTimeout(() => {
if (document.head.querySelector("#emotion")) {
// remove the old styles
document.head.querySelector("#emotion").innerHTML = ""
// inject the new styles
;(stylesRef.current as Element[]).forEach(s =>
document.head
.querySelector("#emotion")
.appendChild(s.cloneNode(true)),
)
}
}, 100)
return <Editor />
}}
</FrameContextConsumer>
Hi @paulm17 , it's kinda interesting because i also use mantine on iframe but can you please share the code on codesandbox? i want to see the output itself. Thanks
@hilmanauz unfortunately not. All I can suggest is to try mantine v7, as v6 did not work. Also I am not really using mantine now, more of a fork to support tailwind.
I am developing a chrome extension that injects a react app into the webpage using a content script. To avoid style conflicts with the main page, I am trying to load the react app (chrome extension) through an iframe.
The JSX & all the local styles (through mini-css-extract-plugin) are getting loaded using iframe but I have used 2 external libraries for UI
The CSS from these 2 libraries is not getting injected into the iframe's head. Please help.