Feat(Playground): Support load global js and css variables
This commit is contained in:
@@ -2,7 +2,6 @@ import Icon from '@ant-design/icons'
|
||||
import { Background, Controls, MiniMap, Node, Panel, ReactFlow } from '@xyflow/react'
|
||||
import '@xyflow/react/dist/style.css'
|
||||
import { AppContext } from '@/App'
|
||||
import { generateThemeCssVariable } from '@/util/common'
|
||||
import useStyles from '@/components/Playground/Output/Preview/render.style'
|
||||
import iframeRaw from '@/components/Playground/Output/Preview/iframe.html?raw'
|
||||
import devices, { DeviceName } from '@/components/Playground/Output/Preview/devices'
|
||||
@@ -12,15 +11,18 @@ interface RenderProps {
|
||||
iframeKey: string
|
||||
compiledCode: string
|
||||
mobileMode?: boolean
|
||||
globalJsVariables?: Record<string, unknown>
|
||||
globalCssVariables?: string
|
||||
}
|
||||
|
||||
interface IMessage {
|
||||
type: 'LOADED' | 'ERROR' | 'UPDATE' | 'DONE' | 'THEME'
|
||||
type: 'LOADED' | 'ERROR' | 'UPDATE' | 'DONE' | 'GLOBAL_VARIABLES'
|
||||
msg: string
|
||||
data: {
|
||||
compiledCode?: string
|
||||
zoom?: number
|
||||
themeSrc?: string
|
||||
globalJsVariables?: Record<string, unknown>
|
||||
globalCssVariables?: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +32,13 @@ const getIframeUrl = (iframeRaw: string) => {
|
||||
|
||||
const iframeUrl = getIframeUrl(iframeRaw)
|
||||
|
||||
const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) => {
|
||||
const Render = ({
|
||||
iframeKey,
|
||||
compiledCode,
|
||||
mobileMode = false,
|
||||
globalJsVariables,
|
||||
globalCssVariables
|
||||
}: RenderProps) => {
|
||||
const { styles, theme } = useStyles()
|
||||
const { isDarkMode } = useContext(AppContext)
|
||||
const iframeRef = useRef<HTMLIFrameElement>(null)
|
||||
@@ -59,11 +67,11 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
|
||||
setIsRotate(!isRotate)
|
||||
}
|
||||
|
||||
const loadTheme = () => {
|
||||
const loadGlobalVariables = () => {
|
||||
iframeRef.current?.contentWindow?.postMessage(
|
||||
{
|
||||
type: 'THEME',
|
||||
data: { themeSrc: generateThemeCssVariable(theme).styles }
|
||||
type: 'GLOBAL_VARIABLES',
|
||||
data: { globalJsVariables, globalCssVariables }
|
||||
} as IMessage,
|
||||
'*'
|
||||
)
|
||||
@@ -80,15 +88,15 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
|
||||
} as IMessage,
|
||||
'*'
|
||||
)
|
||||
loadTheme()
|
||||
loadGlobalVariables()
|
||||
}, [isLoaded, compiledCode])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoaded) {
|
||||
return
|
||||
}
|
||||
loadTheme()
|
||||
}, [isLoaded, isDarkMode])
|
||||
loadGlobalVariables()
|
||||
}, [isLoaded, globalJsVariables, globalCssVariables])
|
||||
|
||||
return mobileMode ? (
|
||||
<>
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Preview</title>
|
||||
<style id="theme-variable"></style>
|
||||
<style id="global-css-variable"></style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener("message", ({ data }) => {
|
||||
if (data?.type === "UPDATE") {
|
||||
// Record old styles that need to be removed
|
||||
const appStyleElement = document.querySelectorAll("style:not(:is(style[id$=\"_oxygen_base_style.css\"], style[id=\"theme-variable\"]))") || [];
|
||||
const appStyleElement = document.querySelectorAll("style:not(:is(style[id$=\"_oxygen_base_style.css\"], style[id=\"global-css-variable\"]))") || [];
|
||||
|
||||
// Remove old app
|
||||
const appSrcElement = document.querySelector("#appSrc");
|
||||
@@ -37,8 +37,11 @@
|
||||
URL.revokeObjectURL(oldSrc);
|
||||
}
|
||||
|
||||
if (data?.type === "THEME") {
|
||||
document.querySelector("#theme-variable").textContent = data.data.themeSrc;
|
||||
if (data?.type === "GLOBAL_VARIABLES") {
|
||||
document.querySelector("#global-css-variable").textContent = data.data.globalCssVariables;
|
||||
for (const key in data.data.globalJsVariables) {
|
||||
globalThis[key] = data.data.globalJsVariables[key]
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -11,6 +11,8 @@ interface PreviewProps {
|
||||
preExpansionCode?: string
|
||||
postExpansionCode?: string
|
||||
mobileMode?: boolean
|
||||
globalJsVariables?: Record<string, unknown>
|
||||
globalCssVariables?: string
|
||||
}
|
||||
|
||||
const Preview = ({
|
||||
@@ -20,7 +22,9 @@ const Preview = ({
|
||||
entryPoint,
|
||||
preExpansionCode = '',
|
||||
postExpansionCode = '',
|
||||
mobileMode = false
|
||||
mobileMode = false,
|
||||
globalJsVariables,
|
||||
globalCssVariables
|
||||
}: PreviewProps) => {
|
||||
const { styles } = useStyles()
|
||||
const [errorMsg, setErrorMsg] = useState('')
|
||||
@@ -44,7 +48,13 @@ const Preview = ({
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<Render iframeKey={iframeKey} compiledCode={compiledCode} mobileMode={mobileMode} />
|
||||
<Render
|
||||
iframeKey={iframeKey}
|
||||
compiledCode={compiledCode}
|
||||
mobileMode={mobileMode}
|
||||
globalJsVariables={globalJsVariables}
|
||||
globalCssVariables={globalCssVariables}
|
||||
/>
|
||||
{errorMsg && <div className={styles.errorMessage}>{errorMsg}</div>}
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user