Feat(Tools): Support theme
This commit is contained in:
@@ -24,6 +24,7 @@ interface EditorProps {
|
||||
options?: IEditorOptions
|
||||
onJumpFile?: (fileName: string) => void
|
||||
extraLibs?: ExtraLib[]
|
||||
onEditorDidMount?: (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => void
|
||||
}
|
||||
|
||||
const Editor = ({
|
||||
@@ -35,7 +36,8 @@ const Editor = ({
|
||||
onChange,
|
||||
options,
|
||||
onJumpFile,
|
||||
extraLibs = []
|
||||
extraLibs = [],
|
||||
onEditorDidMount
|
||||
}: EditorProps) => {
|
||||
const { styles } = useStyles()
|
||||
const editorRef = useRef<editor.IStandaloneCodeEditor>()
|
||||
@@ -98,6 +100,8 @@ const Editor = ({
|
||||
monaco.languages.typescript.typescriptDefaults.addExtraLib(item.content, item.path)
|
||||
)
|
||||
|
||||
onEditorDidMount?.(editor, monaco)
|
||||
|
||||
void autoLoadExtraLib(editor, monaco, file.value, onWatch)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Monaco } from '@monaco-editor/react'
|
||||
import { editor } from 'monaco-editor'
|
||||
import _ from 'lodash'
|
||||
import useStyles from '@/components/Playground/CodeEditor/index.style'
|
||||
import FlexBox from '@/components/common/FlexBox'
|
||||
@@ -22,6 +24,7 @@ interface CodeEditorProps {
|
||||
selectedFileName?: string
|
||||
options?: IEditorOptions
|
||||
extraLibs?: ExtraLib[]
|
||||
onEditorDidMount?: (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => void
|
||||
onSelectedFileChange?: (fileName: string) => void
|
||||
onAddFile?: (fileName: string, files: IFiles) => void
|
||||
onRemoveFile?: (fileName: string, files: IFiles) => void
|
||||
@@ -46,6 +49,7 @@ const CodeEditor = ({
|
||||
onChangeFileContent,
|
||||
onError,
|
||||
extraLibs,
|
||||
onEditorDidMount,
|
||||
...props
|
||||
}: CodeEditorProps) => {
|
||||
const { styles } = useStyles()
|
||||
@@ -157,6 +161,7 @@ const CodeEditor = ({
|
||||
onChange={handleOnChangeFileContent}
|
||||
onJumpFile={handleOnChangeSelectedFile}
|
||||
extraLibs={extraLibs}
|
||||
onEditorDidMount={onEditorDidMount}
|
||||
/>
|
||||
{errorMsg && <div className={styles.errorMessage}>{errorMsg}</div>}
|
||||
</FlexBox>
|
||||
|
||||
@@ -2,6 +2,7 @@ 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'
|
||||
@@ -14,11 +15,12 @@ interface RenderProps {
|
||||
}
|
||||
|
||||
interface IMessage {
|
||||
type: 'LOADED' | 'ERROR' | 'UPDATE' | 'DONE'
|
||||
type: 'LOADED' | 'ERROR' | 'UPDATE' | 'DONE' | 'THEME'
|
||||
msg: string
|
||||
data: {
|
||||
compiledCode?: string
|
||||
zoom?: number
|
||||
themeSrc?: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +59,16 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
|
||||
setIsRotate(!isRotate)
|
||||
}
|
||||
|
||||
const loadTheme = () => {
|
||||
iframeRef.current?.contentWindow?.postMessage(
|
||||
{
|
||||
type: 'THEME',
|
||||
data: { themeSrc: generateThemeCssVariable(theme).styles }
|
||||
} as IMessage,
|
||||
'*'
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoaded) {
|
||||
return
|
||||
@@ -68,8 +80,16 @@ const Render = ({ iframeKey, compiledCode, mobileMode = false }: RenderProps) =>
|
||||
} as IMessage,
|
||||
'*'
|
||||
)
|
||||
loadTheme()
|
||||
}, [isLoaded, compiledCode])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoaded) {
|
||||
return
|
||||
}
|
||||
loadTheme()
|
||||
}, [isLoaded, isDarkMode])
|
||||
|
||||
return mobileMode ? (
|
||||
<>
|
||||
<ReactFlow
|
||||
|
||||
@@ -4,13 +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>
|
||||
</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(style[id$=\"_oxygen_base_style.css\"])") || [];
|
||||
const appStyleElement = document.querySelectorAll("style:not(:is(style[id$=\"_oxygen_base_style.css\"], style[id=\"theme-variable\"]))") || [];
|
||||
|
||||
// Remove old app
|
||||
const appSrcElement = document.querySelector("#appSrc");
|
||||
@@ -35,6 +36,10 @@
|
||||
document.body.appendChild(script);
|
||||
URL.revokeObjectURL(oldSrc);
|
||||
}
|
||||
|
||||
if (data?.type === "THEME") {
|
||||
document.querySelector("#theme-variable").textContent = data.data.themeSrc;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script type="module" id="appSrc"></script>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createStyles } from 'antd-style'
|
||||
|
||||
export default createStyles(({ token }) => ({
|
||||
renderRoot: {
|
||||
border: 'none',
|
||||
border: `1px solid ${token.colorBorder}`,
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
flex: 1
|
||||
|
||||
Reference in New Issue
Block a user