Complete main UI #37
@@ -4,8 +4,7 @@ import { Loader } from 'esbuild-wasm'
|
|||||||
import '@/components/Playground/Output/Transform/transform.scss'
|
import '@/components/Playground/Output/Transform/transform.scss'
|
||||||
import { useUpdatedEffect } from '@/util/hooks'
|
import { useUpdatedEffect } from '@/util/hooks'
|
||||||
import { IFile, ITheme } from '@/components/Playground/shared'
|
import { IFile, ITheme } from '@/components/Playground/shared'
|
||||||
import { addReactImport } from '@/components/Playground/utils'
|
import { cssToJs, jsonToJs, addReactImport } from '@/components/Playground/files'
|
||||||
import { cssToJs, jsonToJs } from '@/components/Playground/files'
|
|
||||||
import Compiler from '@/components/Playground/compiler'
|
import Compiler from '@/components/Playground/compiler'
|
||||||
import { MonacoEditorConfig } from '@/components/Playground/CodeEditor/Editor/monacoConfig'
|
import { MonacoEditorConfig } from '@/components/Playground/CodeEditor/Editor/monacoConfig'
|
||||||
|
|
||||||
@@ -29,7 +28,7 @@ const Transform: React.FC<OutputProps> = ({ file, theme }) => {
|
|||||||
setCompiledCode(value.code)
|
setCompiledCode(value.code)
|
||||||
setErrorMsg('')
|
setErrorMsg('')
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e: Error) => {
|
||||||
setErrorMsg(`编译失败:${e.message}`)
|
setErrorMsg(`编译失败:${e.message}`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import esbuild, { Loader, OnLoadArgs, Plugin, PluginBuild } from 'esbuild-wasm'
|
|||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { IFiles, IImportMap } from '@/components/Playground/shared'
|
import { IFiles, IImportMap } from '@/components/Playground/shared'
|
||||||
import { cssToJs, ENTRY_FILE_NAME, jsonToJs } from '@/components/Playground/files'
|
import { cssToJs, ENTRY_FILE_NAME, jsonToJs, addReactImport } from '@/components/Playground/files'
|
||||||
import { addReactImport } from '@/components/Playground/utils'
|
|
||||||
|
|
||||||
class Compiler {
|
class Compiler {
|
||||||
private init = false
|
private init = false
|
||||||
@@ -71,7 +70,7 @@ class Compiler {
|
|||||||
return {
|
return {
|
||||||
name: 'file-resolver-plugin',
|
name: 'file-resolver-plugin',
|
||||||
setup: (build: PluginBuild) => {
|
setup: (build: PluginBuild) => {
|
||||||
build.onResolve({ filter: /.*/ }, async (args: esbuild.OnResolveArgs) => {
|
build.onResolve({ filter: /.*/ }, (args: esbuild.OnResolveArgs) => {
|
||||||
if (args.path === ENTRY_FILE_NAME) {
|
if (args.path === ENTRY_FILE_NAME) {
|
||||||
return {
|
return {
|
||||||
namespace: 'OxygenToolbox',
|
namespace: 'OxygenToolbox',
|
||||||
@@ -142,7 +141,7 @@ class Compiler {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
build.onLoad({ filter: /.*\.css$/ }, async (args: OnLoadArgs) => {
|
build.onLoad({ filter: /.*\.css$/ }, (args: OnLoadArgs) => {
|
||||||
const contents = cssToJs(files[args.path])
|
const contents = cssToJs(files[args.path])
|
||||||
return {
|
return {
|
||||||
loader: 'js',
|
loader: 'js',
|
||||||
@@ -150,7 +149,7 @@ class Compiler {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
build.onLoad({ filter: /.*\.json$/ }, async (args: OnLoadArgs) => {
|
build.onLoad({ filter: /.*\.json$/ }, (args: OnLoadArgs) => {
|
||||||
const contents = jsonToJs(files[args.path])
|
const contents = jsonToJs(files[args.path])
|
||||||
return {
|
return {
|
||||||
loader: 'js',
|
loader: 'js',
|
||||||
@@ -198,11 +197,11 @@ class Compiler {
|
|||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data, request } = await axios.get(args.path)
|
const axiosResponse = await axios.get<string>(args.path)
|
||||||
const result: esbuild.OnLoadResult = {
|
const result: esbuild.OnLoadResult = {
|
||||||
loader: 'jsx',
|
loader: 'jsx',
|
||||||
contents: data,
|
contents: axiosResponse.data,
|
||||||
resolveDir: request.responseURL
|
resolveDir: (axiosResponse.request as XMLHttpRequest).responseURL
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.fileCache.setItem(args.path, result)
|
await this.fileCache.setItem(args.path, result)
|
||||||
|
|||||||
@@ -90,6 +90,13 @@ export const cssToJs = (file: IFile) => {
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addReactImport = (code: string) => {
|
||||||
|
if (!/import\s+React/g.test(code)) {
|
||||||
|
return `import React from 'react';\n${code}`
|
||||||
|
}
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
export const initFiles: IFiles = getFilesFromUrl() || {
|
export const initFiles: IFiles = getFilesFromUrl() || {
|
||||||
[ENTRY_FILE_NAME]: {
|
[ENTRY_FILE_NAME]: {
|
||||||
name: ENTRY_FILE_NAME,
|
name: ENTRY_FILE_NAME,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const Playground: React.FC<PlaygroundProps> = ({ initFiles, initImportMap }) =>
|
|||||||
|
|
||||||
const handleOnChangeFileContent = (content: string, fileName: string, files: IFiles) => {
|
const handleOnChangeFileContent = (content: string, fileName: string, files: IFiles) => {
|
||||||
if (fileName === IMPORT_MAP_FILE_NAME) {
|
if (fileName === IMPORT_MAP_FILE_NAME) {
|
||||||
setImportMap(JSON.parse(content))
|
setImportMap(JSON.parse(content) as IImportMap)
|
||||||
} else {
|
} else {
|
||||||
delete files[IMPORT_MAP_FILE_NAME]
|
delete files[IMPORT_MAP_FILE_NAME]
|
||||||
setFiles(files)
|
setFiles(files)
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import { ITheme } from '@/components/Playground/shared'
|
|
||||||
|
|
||||||
const STORAGE_DARK_THEME = 'react-playground-prefer-dark'
|
|
||||||
|
|
||||||
export const setPlaygroundTheme = (theme: ITheme) => {
|
|
||||||
localStorage.setItem(STORAGE_DARK_THEME, String(theme === 'vs-dark'))
|
|
||||||
document
|
|
||||||
.querySelectorAll('div[data-id="react-playground"]')
|
|
||||||
?.forEach((item) => item.setAttribute('class', theme))
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getPlaygroundTheme = (): ITheme => {
|
|
||||||
const isDarkTheme = JSON.parse(localStorage.getItem(STORAGE_DARK_THEME) || 'false') as ITheme
|
|
||||||
return isDarkTheme ? 'vs-dark' : 'light'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const addReactImport = (code: string) => {
|
|
||||||
if (!/import\s+React/g.test(code)) {
|
|
||||||
return `import React from 'react';\n${code}`
|
|
||||||
}
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user