Open lencioni opened 8 years ago
Huh. Interesting problem! How are you rendering the react components? Can you pass the actual React components between the frames, or do you generate HTML (e.g. with ReactDOMServer.renderToString) and pass that?
It's a bit of a roundabout way - we render the iframe with html elements with specific class names, and then replace those elements in the iframe with React elements. Does that answer your question?
React DOM does (mostly) support rendering into a container in another window.
I don't have the code in front of me right now, but IIRC, it was something along the lines of this (simplified):
<html>
<head>
<script src="my-app.js"></script>
</head>
<body>
<iframe id="my-iframe">
<div id="react-thing"></div>
</iframe>
</body>
</html>
The JS in my-app.js renders React into the react-thing div which is inside of the iframe. Since the JS is executed in the context of the parent document, and Aphrodite puts the styles in the head of document
, the styles end up not styling the rendered components.
Interesting! I didn't know that React supported that. Unfortunately, there's no way for Aphrodite to know implicitly which frame you are trying to render to, because it isn't connected to React. Maybe we could expose an API like StyleSheet.renderInFrame(frame, () => { ... })
and then it would put the styles in that given frame?
@lencioni I am facing the same issue working with iframe, but in my case, sometimes the style tag is not appended at all. I don't now what is happening... Depending on the screen, the style is not appended andI even if I change "views", doesn't get new css from components.
I am debugging inject.js
and seems that this line inject.js#168 is causing my bug. Its sending a empty string to injectStyle method and its not injecting anything. If I remove this line, it works just fine.
@lnmunhoz Can you provide a more complete example of what you're trying to do? I seriously doubt that removing that line is the solution to your problem.
Hi @xymostech, I am rendering an App inside a iframe. What basically happens is when the page loads, aphrodite randomically don't append the <style>
tag inside the iframe (neither outside, on the host website). Its a very strange behaviour and I can't figure out why this is happening.
I use react-storybook to manage my components and all of them are rendering fine and the <styles>
tag is being appended on the <head>
, but when I use them in the iframe, sometimes the styles are applied and other times not. The only way that makes 100% guarantee to append is removing that line but I know is not the right solution.
The App stack that runs inside the iframe is:
I don't know if it helps, but I am looking for help to figure out what is going on.
This is one of the components, I am doing something wrong to bug aphrodite?
import React, { PropTypes } from 'react';
import { StyleSheet, css } from 'aphrodite';
const styles = StyleSheet.create({
root: {
borderRadius: '4px',
border: 'none',
color: 'white',
backgroundColor: '#1088cc',
boxShadow: '0px 2px 0px 0px #005888',
fontSize: '15px',
letterSpacing: '0.02em',
padding: '10px 20px',
outline: '0',
transition: 'all 0.2s linear',
':hover': {
backgroundColor: '#005888 !important',
boxShadow: '0px 2px 0px 0px #011d4f !important',
},
},
iconRightContainer: {
width: '16px',
display: 'inline-block',
},
iconRightContainerMarginLeft: {
marginLeft: 10,
},
iconRight: {
maxWidth: '100%',
},
});
const Button = ({ label, iconRight, style, ...props }) => (
<button
className={css(styles.root)}
style={style}
{...props}
>
{label}
{iconRight ? (
<div
className={css(
styles.iconRightContainer,
label && styles.iconRightContainerMarginLeft
)}
>
{React.cloneElement(iconRight, {
className: css(styles.iconRight),
})}
</div>
) : null}
</button>
);
Button.propTypes = {
label: PropTypes.string,
iconRight: PropTypes.node,
style: PropTypes.object,
};
export default Button;
I am working on a new component library and I am using Storybook to display the component. I also ran into this issue. Its been almost a year on this issue, any progress on nailing this bug down?
Interesting! I didn't know that React supported that. Unfortunately, there's no way for Aphrodite to know implicitly which frame you are trying to render to, because it isn't connected to React. Maybe we could expose an API like
StyleSheet.renderInFrame(frame, () => { ... })
and then it would put the styles in that given frame?
This would be great for styling components inside shadow root containers 👍
I have recently run into an issue when rendering some React components that use Aphrodite in an iframe. Specifically, when the the JavaScript that renders the components is running in the iframe's parent context. The component is rendered correctly with the Aphrodite className, but the styles are added to the head of the parent document instead of the iframe document.
I've hacked around this by finding the aphrodite styles via
document.querySelector('style[data-aphrodite]')
and copying them into the iframe.Do you see a reasonable way to make this just work without having to worry about it?