Material-UI Componentss not rendering properly when those are inside
It should render components in iframe as well
It is not rendering the components inside iframe, showing plain html elements without any styles
Link: https://codesandbox.io/s/rjo0r3yooo
| Tech | Version |
|--------------|---------|
| Material-UI | v3.5.1 |
| React | v16.6.3 |
| Browser | chrome |
I don't how this issue (#12125) has been closed without fixing it, or if I am missing anything specific to iframe ? If so could you please fix this https://codesandbox.io/s/rjo0r3yooo and share the url back
Material-UI is not working inside
@naniaryan Material-UI is working inside iframes, popup, and shadow DOM. Here is an example with an iframe: https://material-ui.com/demos/app-bar/#bottom-app-bar. The related issues have been closed for a reason. I would have been way better to ask: "How can I use Material-UI inside an iframe?" I know @markdalgleish has already faced this need. The answer isn't obvious, we can improve this story. Going forward, I think that we should:
@naniaryan Is this something you want to work on? :) I was already tracking this need: https://trello.com/c/yHhl6Aiz/1017-demo-inside-an-iframe-and-a-popup.
@oliviertassinari
Thanks for prompt response. I have tried your solution(example) however styles are still broken.
Kindly check and please let me know If I am missing anything.
Find below sandbox link:
https://codesandbox.io/s/p799pp1qzx
Your example works without
Hi @naniaryan I've tried to use your solution to add Material UI to several iframes (we develop a widget that adds several iframes) but I can't seem to make it work.
The css in correctly injected on the first frame but not on the second.
From what I gathered the style elements are not added to the second frame.
Please check the code at: https://codesandbox.io/s/9nnp8xl04
@bcapinski I too am having an issue getting the iframe example to work. You mention above that @naniaryan example works, however, it does not and copying directly from the source and attempting to use it in code doesn't work either. It seems the actual implementation on the AppBar
component demo you point to looks similar to our implementation of it but still, the same result happens between the both of us. The react app renders but it does not inject the styles into the given iframe, but instead to the main body. Is this something we should take up with the jss repo instead?
@HugoMag Your solution works as long as there are no Material UI components outside the frame. When a component is added outside the frame, components inside the frame looses their styles. As seen in this demo: https://codesandbox.io/s/jj3q079m75
Finally got it to work after updating the packages and adding the following lines of code.
import { install } from "@material-ui/styles";
install();
@siriwatknp Here is an iframe example with v4: https://codesandbox.io/s/v0kvljw0r3.
@oliviertassinari I'm assuming this should be working no problem with hooks?
e: Ah it's because I'm not on v4?
MUI versions
"@material-ui/core": "^3.9.3",
"@material-ui/icons": "^3.0.2",
"@material-ui/styles": "^3.0.0-alpha.10",
I keep getting contentDocument
being undefined with this code:
let contentDocument: any;
let contentWindow: any;
const _Frame: React.FC<CombinedProps> = (props) => {
const { children, classes } = props;
const handleRef = (ref: any) => {
const newContentDocument = pathOr(null, ['node', 'contentDocument'], ref);
const newContentWindow = pathOr(null, ['node', 'contentWindow'], ref);
if(!!newContentDocument) {
contentDocument = newContentDocument
}
if(!!newContentWindow) {
contentWindow = newContentWindow;
}
}
const [isReady, setReady] = React.useState<boolean>(false);
const [jss, setJss] = React.useState<any>(undefined);
const [sheetsManager, setSheetsManager] = React.useState<any>(undefined);
const [container, setContainer] = React.useState<any>(undefined);
const contentDidMount = () => {
setReady(true);
setJss(create({
plugins: [...jssPreset().plugins, rtl()],
insertionPoint: contentWindow['demo-frame-jss']
}));
setSheetsManager(new Map());
setContainer(contentDocument.body);
}
const contentDidUpdate = () => {
contentDocument.body.dir = props.theme.direction
}
return (
<NoSsr>
<Frame
ref={handleRef}
className={classes.root}
contentDidMount={contentDidMount}
contentDidUpdate={contentDidUpdate}
>
<div id="demo-frame-jss" />
{isReady ? (
<StylesProvider jss={jss} sheetsManager={sheetsManager}>
{React.cloneElement(children as React.DetailedReactHTMLElement<any, HTMLElement>, {
container,
})}
</StylesProvider>
) : null}
</Frame>
</NoSsr>
);
};
const styled = withStyles(styles, { withTheme: true });
export default compose<CombinedProps, {}>(
styled,
// React.memo
)(_Frame);
@martinmckenna The documentation has an iframe "mode" that works with v3: https://material-ui.com/demos/app-bar/#bottom-app-bar and v4: https://next.material-ui.com/demos/app-bar/#bottom-app-bar.
@oliviertassinari I'm not seeing any iframe mode in the links you posted? Am I missing something here?
@martinmckenna The bottom app bar demo is rendered inside an iframe.
Ok. In this case, it seems like upgrading to v4 is really my only option.
The styles are not being applied with the previous examples and attempts to use @rajithaw solution resolves in more problems because I've added properties to the base MUI Theme
Hey, the demo with the popout doesn't work, the menu is not styled in the popout window. I'm trying to do something like this but can't make it copy the styles to the new window when they change. Any ideas how to make the demo work?
@rumpl Thanks for the report. We should update the code sandbox examples for v4.
Thanks!
In the meantime, do you have some pointers on how I could implement it? I tried to play with the StylesProvider
and custom jss but didn't manage to make it work.
The process should be similar to how we make the iframe demos work in the documentation.
@rumpl Here is a rough example that works for the styles: https://codesandbox.io/s/308nkoz2xp. Now, it seems to have an issue with the popover positioning logic.
@oliviertassinari thanks! This will help me a lot!
@rumpl My demo code is really garbage, you can simplify it, there is no doubt :)
Sure sure, I'm using a different solution for the popup that uses react portals, will try to make it work with what I have already in place.
Thanks!
The examples on codesandbox works but when I download the same package and run locally, it does not 馃槙
In our project, we use Material-UI in ShadowRoot. We've resolved the problem and use it in production.
To archive this, I write a custom JSS Renderer and use a new web feature called Constructable StyleSheets to dispath stylesheets between different ShadowRoots.
Our solution also works for MUI's portal.
https://github.com/DimensionDev/Maskbook/tree/master/src/utils/jss
This is a AGPL-v3-or-later project, but the core of the custom JSS renderer ConstructableStyleSheetsRenderer
is MIT licenced to the JSS project.
Most helpful comment
In our project, we use Material-UI in ShadowRoot. We've resolved the problem and use it in production.
To archive this, I write a custom JSS Renderer and use a new web feature called Constructable StyleSheets to dispath stylesheets between different ShadowRoots.
Our solution also works for MUI's portal.
https://github.com/DimensionDev/Maskbook/tree/master/src/utils/jss
This is a AGPL-v3-or-later project, but the core of the custom JSS renderer
ConstructableStyleSheetsRenderer
is MIT licenced to the JSS project.