import React, { useRef, useState, useEffect } from 'react'; import Frame from 'react-frame-component'; import { landingLinksWithoutFontQuery, animationCss, getGoogleFontQuery, fontQueryParams, useStore, } from '@tempi/core-renderer'; import { IFrameProvider } from './IFrameProvider'; import { reset } from './reset'; import { StyleProvider } from '@ant-design/cssinjs'; import { useBuilder } from '@tempi/core-editor'; interface IFrameProps { children: React.ReactNode; id?: string; } export const IFrame = ({ children, ...props }: IFrameProps) => { const [injectCss, setInjectCss] = useState(); const [fontFamilyQuery, setFontFamilyQuery] = useState(); const ref = useRef(); const { pageFonts } = useBuilder(); const { globalData } = useStore(); const savedPageFonts = globalData?.page?.fonts; const { flagPB4971 } = window?.config || {}; useEffect(() => { setFontFamilyQuery(getGoogleFontQuery(savedPageFonts)); }, [savedPageFonts]); useEffect(() => { if (pageFonts && flagPB4971) { setFontFamilyQuery(getGoogleFontQuery(pageFonts)); } // use !!pageFonts instead of pageFonts to avoid continuous changes in pageFonts due to re-renders, which can lead to constant queries to Google // eslint-disable-next-line }, [!!pageFonts, flagPB4971]); const links = [ ...landingLinksWithoutFontQuery, // The IFrame use in both client and builder // client doesn't need to import builder style sheets such as antd { type: 'text/css', rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/npm/emoji-mart@3.0.1/css/emoji-mart.css', }, { type: 'text/css', rel: 'stylesheet', href: '/css/builder.css', }, fontFamilyQuery ? { rel: 'preLoad stylesheet', href: fontFamilyQuery, as: 'style', type: 'text/css', } : { rel: 'preLoad stylesheet', href: `https://fonts.googleapis.com/css2?${fontQueryParams}&display=swap`, as: 'style', type: 'text/css', }, ]; return (
`} mountTarget="#mountHere" head={[...links.map((link, index) => )]} style={{ overflow: 'hidden', width: '100%', position: 'absolute', top: 0, bottom: 0, right: 0, left: 0, margin: 'auto', minHeight: '100%', }} {...props} contentDidMount={() => { setInjectCss(ref.current?.contentDocument?.querySelector('head')); }} > {children} ); }; export const MemoizedIFrame = React.memo(IFrame);