Skip to content

Commit

Permalink
feat: monaco editor
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed Jun 23, 2023
1 parent a7bf741 commit 93b9e2d
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 92 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"dependencies": {
"@unocss/reset": "^0.53.3",
"@vue/repl": "^1.5.0",
"@vue/repl": "^2.1.3",
"@vueuse/core": "^10.2.0",
"element-plus": "^2.3.7",
"semver": "^7.5.3",
Expand All @@ -32,7 +32,6 @@
"@iconify-json/ri": "^1.1.10",
"@sxzz/eslint-config": "^3.0.0",
"@types/node": "^20.3.1",
"@types/prettier": "^2.7.3",
"@types/semver": "^7.5.0",
"@unocss/transformer-directives": "^0.53.3",
"@vitejs/plugin-vue": "^4.2.3",
Expand Down
12 changes: 4 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 3 additions & 72 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
<script setup lang="ts">
import { Repl, type SFCOptions } from '@vue/repl'
import { type Fn } from '@vueuse/core'
import { type BuiltInParserName, type format } from 'prettier'
import Monaco from '@vue/repl/monaco-editor'
import { type ImportMap } from '@/utils/import-map'
import { type UserOptions } from '@/composables/store'
import { genCdnLink } from '@/utils/dependency'
import { IS_DEV } from '@/constants'
import type parserHtml from 'prettier/parser-html'
import type parserTypescript from 'prettier/parser-typescript'
import type parserBabel from 'prettier/parser-babel'
import type parserPostcss from 'prettier/parser-postcss'
const loading = ref(true)
// enable experimental features
Expand Down Expand Up @@ -65,72 +58,9 @@ const handleKeydown = (evt: KeyboardEvent) => {
evt.preventDefault()
return
}
if ((evt.altKey || evt.ctrlKey) && evt.shiftKey && evt.code === 'KeyF') {
evt.preventDefault()
formatCode()
return
}
}
let prettier:
| [
typeof format,
typeof parserHtml,
typeof parserTypescript,
typeof parserBabel,
typeof parserPostcss
]
| undefined
const loadPrettier = async () => {
const load = (path: string) =>
import(/* @vite-ignore */ genCdnLink('prettier', '2', `/esm/${path}`))
if (!prettier)
prettier = await Promise.all([
load('standalone.mjs').then((r) => r.default.format),
load('parser-html.mjs').then((m) => m.default),
load('parser-typescript.mjs').then((m) => m.default),
load('parser-babel.mjs').then((m) => m.default),
load('parser-postcss.mjs').then((m) => m.default),
])
return prettier
}
const formatCode = async () => {
let close: Fn | undefined
if (!prettier) {
;({ close } = ElMessage.info({
message: 'Loading Prettier...',
duration: 0,
}))
}
const [format, parserHtml, parserTypeScript, parserBabel, parserPostcss] =
await loadPrettier()
close?.()
const file = store.state.activeFile
let parser: BuiltInParserName
if (file.filename.endsWith('.vue')) {
parser = 'vue'
} else if (file.filename.endsWith('.js')) {
parser = 'babel'
} else if (file.filename.endsWith('.ts')) {
parser = 'typescript'
} else if (file.filename.endsWith('.json')) {
parser = 'json'
} else {
return
}
file.code = format(file.code, {
parser,
plugins: [parserHtml, parserTypeScript, parserBabel, parserPostcss],
semi: false,
singleQuote: true,
})
}
useDark()
useDark().value = true
// persist state
watchEffect(() => history.replaceState({}, '', `#${store.serialize()}`))
Expand All @@ -141,6 +71,7 @@ watchEffect(() => history.replaceState({}, '', `#${store.serialize()}`))
<Header :store="store" />
<Repl
:store="store"
:editor="Monaco"
show-compile-output
auto-resize
:sfc-options="sfcOptions"
Expand Down
8 changes: 4 additions & 4 deletions src/components/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const appVersion = import.meta.env.APP_VERSION
const replVersion = import.meta.env.REPL_VERSION
const nightly = ref(false)
const dark = useDark()
const toggleDark = useToggle(dark)
// const dark = useDark()
// const toggleDark = useToggle(dark)
const { store } = defineProps<{
store: ReplStore
Expand Down Expand Up @@ -105,12 +105,12 @@ async function copyLink() {

<div flex="~ gap-4" text-lg>
<button hover:color-primary i-ri-share-line @click="copyLink" />
<button
<!-- <button
hover:color-primary
i-ri-sun-line
dark:i-ri-moon-line
@click="toggleDark()"
/>
/> -->
<a
href="https://github.com/element-plus/element-plus-playground"
target="_blank"
Expand Down
26 changes: 20 additions & 6 deletions src/composables/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ export type SerializeState = Record<string, string> & {
_o?: UserOptions
}

const MAIN_FILE = 'PlaygroundMain.vue'
const APP_FILE = 'App.vue'
const ELEMENT_PLUS_FILE = 'element-plus.js'
const MAIN_FILE = 'src/PlaygroundMain.vue'
const APP_FILE = 'src/App.vue'
const ELEMENT_PLUS_FILE = 'src/element-plus.js'
const IMPORT_MAP = 'import-map.json'
export const USER_IMPORT_MAP = 'import_map.json'
export const USER_IMPORT_MAP = 'src/import_map.json'

export const useStore = (initial: Initial) => {
const versions = reactive(
Expand All @@ -40,10 +40,14 @@ export const useStore = (initial: Initial) => {
const hideFile = computed(() => !IS_DEV && !userOptions.value.showHidden)

const _files = initFiles(initial.serializedState || '')

let activeFile = _files[APP_FILE]
if (!activeFile) activeFile = Object.values(_files)[0]

const state = reactive<StoreState>({
mainFile: MAIN_FILE,
files: _files,
activeFile: _files[APP_FILE],
activeFile,
errors: [],
vueRuntimeURL: '',
vueServerRendererURL: '',
Expand Down Expand Up @@ -164,8 +168,11 @@ export const useStore = (initial: Initial) => {
const files: StoreState['files'] = {}
if (serializedState) {
const saved = deserialize(serializedState)
for (const [filename, file] of Object.entries(saved)) {
for (let [filename, file] of Object.entries(saved)) {
if (filename === '_o') continue
if (!filename.startsWith('src/') && filename !== IMPORT_MAP) {
filename = `src/${filename}`
}
files[filename] = new File(filename, file as string)
}
userOptions.value = saved._o || {}
Expand Down Expand Up @@ -290,6 +297,13 @@ export const useStore = (initial: Initial) => {
versions.elementPlus = version
}

watch(
() => state.files[IMPORT_MAP].code,
() => {
state.resetFlip = !state.resetFlip
}
)

return {
...store,

Expand Down

0 comments on commit 93b9e2d

Please sign in to comment.