Closed chrisvxd closed 3 months ago
I've been investigating this issue using the Mantine library and have found two problems that prevent it from rendering all of the styles correctly.
AutoFrame
component only mirrors the styles from the document head. Mantine is also injecting styles into the body
, and these styles aren't getting mirrored. html
tag for theme/color mode selection, but this isn't getting copied across.PR #544 is ready for review.
Mantine now working. @xaviemirmon to review further Tailwind setups before closing.
Hello @chrisvxd,
we really appreciate your work and love the puck editor. As we would like to work with serverless infrastructure we started a new project with the remix recipe and added Chakra UI and eventually realized that stylings from the Iframe are not generated and rendered in the editor route. The published site will be rendered as expected.
We tried to enforce client rendering and some other hacks, but did not manage to solve it from the outside. We think this issue is connected with the iframe.
I created a minimal sample for this: https://github.com/henning-f/puck-remix-chakra-issue I followed the instructions of the Chakra UI documentation for Remix.
Are these issues connected?
I am looking forward to your response.
Hello.
In our project we are using styled-components library for React to style our components. With iframe enabled , those styles are not being picked up by editor. However inline stylings works as expected. Sharing some code example so maybe You can try to reproduce that issue.
Editor Config :
import BlockQuote from './BlockQuote
const config = {
components: {
Quote:{
fields: {
quote: {
type: 'text',
},
},
defaultProps: {
quote: 'Hello, quote',
},
render: ({ quote }) => {
return <BlockQuote quote={quote} />;
},
}
},
};
Component Code
import styled from 'styled-components';
export default function BlockQuote(props) {
const { quote } = props;
return (
<QuoteWrapper>
<LineDiv />
<div className='quote-text'>
<span>{quote}</span>
</div>
</QuoteWrapper>
);
}
const LineDiv = styled.div`
width: 0.25rem;
background-color: ${({ theme }) => theme.colors.blue[60]};
align-self: stretch;
margin-right: 1rem;
`;
const QuoteWrapper = styled.div`
padding-bottom: 3rem;
padding-top: 2rem;
display: flex;
align-items: center;
.quote-text {
font-size: 1.75rem;
line-height: 2.25rem;
color: ${({ theme }) => theme.colors.blue[60]};
}
`;
Hey @chrisvxd, Just wanted to confirm that disabling iframes (iframe={{enabled:false}}) fixed the issue with the remix recipe, too. I thought it wouldn't work, but I guess I had a configuration error last time.
@MiniMarPaz which version of Puck are you using? Have you tried the canary which has some iFrame enhancements?
@xaviemirmon I'm using latest available version of Puck. 0.15.0 . I did not tried canary version but I will try and let You know if canary version fix issue
@henning-f I have been looking at your issue and have narrowed it down to how Emotion Cache is interacting with the iFrame. My current theory is that Emotion Cache isn't able to interact with the style tags in the iFrame.
Related to: https://github.com/emotion-js/emotion/issues/3071 and https://github.com/chakra-ui/chakra-ui/issues/8241
@MiniMarPaz amazing thanks!
@xaviemirmon I've tried canary version of Puck but unfortunately those improvements that You've mentioned do not fix issue. While iframe is enabled, styled-components styles are not picked up.
@MiniMarPaz I tried replicating your issue in the demo app using your code, and was unable to
Can you provide a codesandbox that replicates the issue?
Okay, I was able to reproduce the Chakra/Remix issue and have released some new APIs and tools to help in (available in 0.16.0-canary.607a585).
Here's an example chakra + remix example using the new APIs: https://github.com/chrisvxd/puck-chakra-remix-example/commit/baf0863fe0fa4ea1a20c4011320c37a8d489ca32
iframe
override APIReceives the iframe document
as a prop. This enables you to inject your styles and manipulate the iframe document however you need. This example injects a custom emotion cache with the cha
key for Chakra:
<Puck overrides={{
iframe: ({ children, document }) => {
const [cache, setCache] = useState<EmotionCache | null>(null);
useEffect(() => {
if (document) {
setCache(
createCache({
key: "cha",
container: document.head,
})
);
}
}, [document]);
if (cache) {
return <CacheProvider value={cache}>{children}</CacheProvider>;
}
return <>{children}</>;
},
}} />
emotion-cache
pluginThis captures the above as a plugin, since it's likely a common use-case. We could consider adding one for style-components, if necessary.
import { Puck } from "@measured/puck";
import createEmotionCache from "@measured/puck-plugin-emotion-cache";
// Create your emotion cache plugin. This example configures it for Chakra.
const chakraEmotionCache = createEmotionCache("cha");
// Render Puck
export function Page() {
return <Puck config={config} data={data} plugins={[chakraEmotionCache]} />;
}
I'm going to close this out as I'm pretty sure this will cover any remaining use-cases, but shout if there are still issues and I'll
Test Puck's iframe behaviour across multiple CSS frameworks and improve resiliency:
Related: #409