Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@
"vite-plugin-dts": "^4.5.0",
"vscode-uri": "^3.1.0",
"vue": "^3.5.13",
"vue-tsc": "~2.2.2"
"vue-tsc": "~2.2.2",
"luna-console": "^1.3.5",
"luna-data-grid": "^1.3.0",
"luna-dom-viewer": "^1.4.0",
"luna-object-viewer": "^0.3.1"
}
}
52 changes: 52 additions & 0 deletions pnpm-lock.yaml

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

11 changes: 9 additions & 2 deletions src/Repl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import {
injectKeyProps,
} from './types'
import EditorContainer from './editor/EditorContainer.vue'
import 'luna-object-viewer/luna-object-viewer.css'
import 'luna-data-grid/luna-data-grid.css'
import 'luna-dom-viewer/luna-dom-viewer.css'
import 'luna-console/luna-console.css'

import type * as monaco from 'monaco-editor-core'

export interface Props {
Expand All @@ -20,6 +25,7 @@ export interface Props {
showCompileOutput?: boolean
showImportMap?: boolean
showTsConfig?: boolean
showConsole?: boolean
clearConsole?: boolean
layout?: 'horizontal' | 'vertical'
layoutReverse?: boolean
Expand Down Expand Up @@ -127,8 +133,9 @@ defineExpose({ reload })
margin: 0;
overflow: hidden;
font-size: 13px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: var(--bg-soft);
}

Expand Down
83 changes: 80 additions & 3 deletions src/output/Output.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
<script setup lang="ts">
import Preview from './Preview.vue'
import { computed, inject, useTemplateRef } from 'vue'
import SplitPane from '../SplitPane.vue'
import {
computed,
inject,
onMounted,
ref,
useTemplateRef,
watch,
type WatchHandle,
} from 'vue'
import LunaConsole from 'luna-console'
import {
type EditorComponentType,
type OutputModes,
Expand All @@ -13,8 +23,36 @@ const props = defineProps<{
ssr: boolean
}>()

const { store } = inject(injectKeyProps)!
const { store, showConsole, theme } = inject(injectKeyProps)!
const previewRef = useTemplateRef('preview')
const consoleContainerRef = useTemplateRef('console-container')
const lunaConsole = ref<LunaConsole>()
let lunaWatcher: WatchHandle | undefined = undefined

onMounted(createConsole)

watch(
showConsole,
(val) => {
if (val) {
createConsole()
} else {
lunaConsole.value = undefined
lunaWatcher?.stop()
}
},
{ flush: 'post' },
)

function createConsole() {
if (!consoleContainerRef.value || lunaConsole.value) return
lunaConsole.value = new LunaConsole(consoleContainerRef.value, {
theme: theme.value || 'light',
})
lunaWatcher ??= watch(() => store.value.activeFile.code, clearLunaConsole)
lunaWatcher.resume()
}

const modes = computed(() =>
props.showCompileOutput
? (['preview', 'js', 'css', 'ssr'] as const)
Expand All @@ -33,8 +71,14 @@ const mode = computed<OutputModes>({
},
})

function clearLunaConsole() {
console.log('clear')
lunaConsole.value?.clear(true)
}

function reload() {
previewRef.value?.reload()
clearLunaConsole()
}

defineExpose({ reload, previewRef })
Expand All @@ -53,7 +97,21 @@ defineExpose({ reload, previewRef })
</div>

<div class="output-container">
<Preview ref="preview" :show="mode === 'preview'" :ssr="ssr" />
<SplitPane v-if="showConsole" layout="vertical">
<template #left>
<Preview
ref="preview"
:luna-console="lunaConsole"
:show="mode === 'preview'"
:ssr="ssr"
/>
</template>
<template #right>
<div ref="console-container" />
<button class="clear-btn" @click="clearLunaConsole">clear</button>
</template>
</SplitPane>
<Preview v-else ref="preview" :show="mode === 'preview'" :ssr="ssr" />
<props.editorComponent
v-if="mode !== 'preview'"
readonly
Expand Down Expand Up @@ -95,4 +153,23 @@ button.active {
color: var(--color-branding-dark);
border-bottom: 3px solid var(--color-branding-dark);
}
.luna-console-theme-dark {
background-color: var(--bg) !important;
}
.clear-btn {
position: absolute;
font-size: 18px;
font-family: var(--font-code);
color: #999;
top: 10px;
right: 10px;
z-index: 99;
padding: 8px 10px 6px;
background-color: var(--bg);
border-radius: 4px;
border: 1px solid var(--border);
&:hover {
color: var(--color-branding);
}
}
</style>
8 changes: 7 additions & 1 deletion src/output/Preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
import { computed, inject, useTemplateRef } from 'vue'
import { injectKeyProps } from '../../src/types'
import Sandbox from './Sandbox.vue'
import LunaConsole from 'luna-console'

const props = defineProps<{ show: boolean; ssr: boolean }>()
const props = defineProps<{
show: boolean
ssr: boolean
lunaConsole?: LunaConsole
}>()

const { store, clearConsole, theme, previewTheme, previewOptions } =
inject(injectKeyProps)!
Expand All @@ -30,5 +35,6 @@ defineExpose({
:preview-options="previewOptions"
:ssr="props.ssr"
:clear-console="clearConsole"
:luna-console="props.lunaConsole"
/>
</template>
25 changes: 12 additions & 13 deletions src/output/Sandbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import {
watch,
watchEffect,
} from 'vue'
import LunaConsole from 'luna-console'
import srcdoc from './srcdoc.html?raw'
import { PreviewProxy } from './PreviewProxy'
import { compileModulesForPreview } from './moduleCompiler'
import type { Store } from '../store'
import { injectKeyProps } from '../types'
import type { Store } from '../store'

export interface SandboxProps {
store: Store
Expand All @@ -36,6 +37,7 @@ export interface SandboxProps {
}
/** @default true */
autoStoreInit?: boolean
lunaConsole?: LunaConsole
}

const props = withDefaults(defineProps<SandboxProps>(), {
Expand Down Expand Up @@ -157,32 +159,34 @@ function createSandbox() {
runtimeError.value = 'Uncaught (in promise): ' + error.message
},
on_console: (log: any) => {
if (log.duplicate) {
return
}
const lc = props.lunaConsole
if (log.level === 'error') {
if (log.args[0] instanceof Error) {
runtimeError.value = log.args[0].message
} else {
runtimeError.value = log.args[0]
}
lc?.error(...log.args)
} else if (log.level === 'warn') {
if (log.args[0].toString().includes('[Vue warn]')) {
runtimeWarning.value = log.args
.join('')
.replace(/\[Vue warn\]:/, '')
.trim()
}
lc?.warn(...log.args)
} else {
lc?.log(...log.args)
}
},
on_console_group: (action: any) => {
// group_logs(action.label, false);
props.lunaConsole?.group(action.label)
},
on_console_group_end: () => {
// ungroup_logs();
props.lunaConsole?.groupEnd()
},
on_console_group_collapsed: (action: any) => {
// group_logs(action.label, true);
props.lunaConsole?.groupCollapsed(action.label)
},
})

Expand Down Expand Up @@ -312,12 +316,7 @@ defineExpose({ reload, container: containerRef })
</script>

<template>
<div
v-show="props.show"
ref="container"
class="iframe-container"
:class="theme"
/>
<div v-show="show" ref="container" class="iframe-container" :class="theme" />
<Message :err="(previewOptions?.showRuntimeError ?? true) && runtimeError" />
<Message
v-if="!runtimeError && (previewOptions?.showRuntimeWarning ?? true)"
Expand Down
Loading