Skip to content

Commit ba6a7dc

Browse files
committed
chore: deplace LunaConsole to Output.vue
1 parent bc2f076 commit ba6a7dc

File tree

3 files changed

+99
-75
lines changed

3 files changed

+99
-75
lines changed

src/output/Output.vue

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
<script setup lang="ts">
22
import Preview from './Preview.vue'
3-
import { computed, inject, useTemplateRef } from 'vue'
3+
import SplitPane from '../SplitPane.vue'
4+
import {
5+
computed,
6+
inject,
7+
onMounted,
8+
ref,
9+
useTemplateRef,
10+
watch,
11+
type WatchHandle,
12+
} from 'vue'
13+
import LunaConsole from 'luna-console'
414
import {
515
type EditorComponentType,
616
type OutputModes,
@@ -13,8 +23,36 @@ const props = defineProps<{
1323
ssr: boolean
1424
}>()
1525
16-
const { store } = inject(injectKeyProps)!
26+
const { store, showConsole, theme } = inject(injectKeyProps)!
1727
const previewRef = useTemplateRef('preview')
28+
const consoleContainerRef = useTemplateRef('console-container')
29+
const lunaConsole = ref<LunaConsole>()
30+
let lunaWatcher: WatchHandle | undefined = undefined
31+
32+
onMounted(createConsole)
33+
34+
watch(
35+
showConsole,
36+
(val) => {
37+
if (val) {
38+
createConsole()
39+
} else {
40+
lunaConsole.value = undefined
41+
lunaWatcher?.stop()
42+
}
43+
},
44+
{ flush: 'post' },
45+
)
46+
47+
function createConsole() {
48+
if (!consoleContainerRef.value || lunaConsole.value) return
49+
lunaConsole.value = new LunaConsole(consoleContainerRef.value, {
50+
theme: theme.value || 'light',
51+
})
52+
lunaWatcher ??= watch(() => store.value.activeFile.code, clearLunaConsole)
53+
lunaWatcher.resume()
54+
}
55+
1856
const modes = computed(() =>
1957
props.showCompileOutput
2058
? (['preview', 'js', 'css', 'ssr'] as const)
@@ -33,8 +71,14 @@ const mode = computed<OutputModes>({
3371
},
3472
})
3573
74+
function clearLunaConsole() {
75+
console.log('clear')
76+
lunaConsole.value?.clear(true)
77+
}
78+
3679
function reload() {
3780
previewRef.value?.reload()
81+
clearLunaConsole()
3882
}
3983
4084
defineExpose({ reload, previewRef })
@@ -53,7 +97,21 @@ defineExpose({ reload, previewRef })
5397
</div>
5498

5599
<div class="output-container">
56-
<Preview ref="preview" :show="mode === 'preview'" :ssr="ssr" />
100+
<SplitPane v-if="showConsole" layout="vertical">
101+
<template #left>
102+
<Preview
103+
ref="preview"
104+
:luna-console="lunaConsole"
105+
:show="mode === 'preview'"
106+
:ssr="ssr"
107+
/>
108+
</template>
109+
<template #right>
110+
<div ref="console-container" />
111+
<button class="clear-btn" @click="clearLunaConsole">clear</button>
112+
</template>
113+
</SplitPane>
114+
<Preview v-else ref="preview" :show="mode === 'preview'" :ssr="ssr" />
57115
<props.editorComponent
58116
v-if="mode !== 'preview'"
59117
readonly
@@ -95,4 +153,23 @@ button.active {
95153
color: var(--color-branding-dark);
96154
border-bottom: 3px solid var(--color-branding-dark);
97155
}
156+
.luna-console-theme-dark {
157+
background-color: var(--bg) !important;
158+
}
159+
.clear-btn {
160+
position: absolute;
161+
font-size: 18px;
162+
font-family: var(--font-code);
163+
color: #999;
164+
top: 10px;
165+
right: 10px;
166+
z-index: 99;
167+
padding: 8px 10px 6px;
168+
background-color: var(--bg);
169+
border-radius: 4px;
170+
border: 1px solid var(--border);
171+
&:hover {
172+
color: var(--color-branding);
173+
}
174+
}
98175
</style>

src/output/Preview.vue

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22
import { computed, inject, useTemplateRef } from 'vue'
33
import { injectKeyProps } from '../../src/types'
44
import Sandbox from './Sandbox.vue'
5+
import LunaConsole from 'luna-console'
56
6-
const props = defineProps<{ show: boolean; ssr: boolean }>()
7+
const props = defineProps<{
8+
show: boolean
9+
ssr: boolean
10+
lunaConsole?: LunaConsole
11+
}>()
712
8-
const {
9-
store,
10-
clearConsole,
11-
showConsole,
12-
theme,
13-
previewTheme,
14-
previewOptions,
15-
} = inject(injectKeyProps)!
13+
const { store, clearConsole, theme, previewTheme, previewOptions } =
14+
inject(injectKeyProps)!
1615
1716
const sandboxTheme = computed(() =>
1817
previewTheme.value ? theme.value : undefined,
@@ -35,7 +34,7 @@ defineExpose({
3534
:theme="sandboxTheme"
3635
:preview-options="previewOptions"
3736
:ssr="props.ssr"
38-
:show-console="showConsole"
3937
:clear-console="clearConsole"
38+
:luna-console="props.lunaConsole"
4039
/>
4140
</template>

src/output/Sandbox.vue

Lines changed: 10 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,15 @@ import {
1414
import LunaConsole from 'luna-console'
1515
import srcdoc from './srcdoc.html?raw'
1616
import { PreviewProxy } from './PreviewProxy'
17-
import SplitPane from '../SplitPane.vue'
1817
import { compileModulesForPreview } from './moduleCompiler'
1918
import { injectKeyProps } from '../types'
20-
2119
import type { Store } from '../store'
2220
2321
export interface SandboxProps {
2422
store: Store
2523
show?: boolean
2624
ssr?: boolean
2725
clearConsole?: boolean
28-
showConsole?: boolean
2926
theme?: 'dark' | 'light'
3027
previewOptions?: {
3128
headHTML?: string
@@ -40,13 +37,13 @@ export interface SandboxProps {
4037
}
4138
/** @default true */
4239
autoStoreInit?: boolean
40+
lunaConsole?: LunaConsole
4341
}
4442
4543
const props = withDefaults(defineProps<SandboxProps>(), {
4644
show: true,
4745
ssr: false,
4846
theme: 'light',
49-
showConsole: false,
5047
clearConsole: true,
5148
previewOptions: () => ({}),
5249
autoStoreInit: true,
@@ -59,26 +56,15 @@ if (keyProps === undefined && props.autoStoreInit) {
5956
}
6057
6158
const containerRef = useTemplateRef('container')
62-
const consoleContainerRef = useTemplateRef('console-container')
6359
const runtimeError = ref<string>()
6460
const runtimeWarning = ref<string>()
6561
6662
let sandbox: HTMLIFrameElement
67-
let lunaConsole: LunaConsole
6863
let proxy: PreviewProxy
6964
let stopUpdateWatcher: WatchStopHandle | undefined
7065
7166
// create sandbox on mount
72-
onMounted(() => {
73-
createSandbox()
74-
if (!consoleContainerRef.value) return
75-
if (props.showConsole) {
76-
lunaConsole = new LunaConsole(consoleContainerRef.value, {
77-
theme: keyProps?.theme.value || 'light',
78-
})
79-
watch(() => store.value.activeFile.code, clearLunaConsole)
80-
}
81-
})
67+
onMounted(createSandbox)
8268
8369
// reset sandbox when import map changes
8470
watch(
@@ -173,33 +159,34 @@ function createSandbox() {
173159
runtimeError.value = 'Uncaught (in promise): ' + error.message
174160
},
175161
on_console: (log: any) => {
162+
const lc = props.lunaConsole
176163
if (log.level === 'error') {
177164
if (log.args[0] instanceof Error) {
178165
runtimeError.value = log.args[0].message
179166
} else {
180167
runtimeError.value = log.args[0]
181168
}
182-
lunaConsole.error(...log.args)
169+
lc?.error(...log.args)
183170
} else if (log.level === 'warn') {
184171
if (log.args[0].toString().includes('[Vue warn]')) {
185172
runtimeWarning.value = log.args
186173
.join('')
187174
.replace(/\[Vue warn\]:/, '')
188175
.trim()
189176
}
190-
lunaConsole.warn(...log.args)
177+
lc?.warn(...log.args)
191178
} else {
192-
lunaConsole.log(...log.args)
179+
lc?.log(...log.args)
193180
}
194181
},
195182
on_console_group: (action: any) => {
196-
lunaConsole.group(action.label)
183+
props.lunaConsole?.group(action.label)
197184
},
198185
on_console_group_end: () => {
199-
lunaConsole.groupEnd()
186+
props.lunaConsole?.groupEnd()
200187
},
201188
on_console_group_collapsed: (action: any) => {
202-
lunaConsole.groupCollapsed(action.label)
189+
props.lunaConsole?.groupCollapsed(action.label)
203190
},
204191
})
205192
@@ -318,38 +305,18 @@ async function updatePreview() {
318305
}
319306
}
320307
321-
function clearLunaConsole() {
322-
lunaConsole?.clear(true)
323-
}
324-
325308
/**
326309
* Reload the preview iframe
327310
*/
328311
function reload() {
329312
sandbox.contentWindow?.location.reload()
330-
clearLunaConsole()
331313
}
332314
333315
defineExpose({ reload, container: containerRef })
334316
</script>
335317

336318
<template>
337-
<SplitPane v-if="show && showConsole" layout="vertical">
338-
<template #left>
339-
<div ref="container" class="iframe-container" :class="theme" />
340-
</template>
341-
<template #right>
342-
<div ref="console-container" />
343-
<button class="clear-btn" @click="clearLunaConsole">clear</button>
344-
</template>
345-
</SplitPane>
346-
<div
347-
v-if="!showConsole"
348-
v-show="props.show"
349-
ref="container"
350-
class="iframe-container"
351-
:class="theme"
352-
/>
319+
<div v-show="show" ref="container" class="iframe-container" :class="theme" />
353320
<Message :err="(previewOptions?.showRuntimeError ?? true) && runtimeError" />
354321
<Message
355322
v-if="!runtimeError && (previewOptions?.showRuntimeWarning ?? true)"
@@ -368,23 +335,4 @@ defineExpose({ reload, container: containerRef })
368335
.iframe-container.dark :deep(iframe) {
369336
background-color: #1e1e1e;
370337
}
371-
.luna-console-theme-dark {
372-
background-color: var(--bg) !important;
373-
}
374-
.clear-btn {
375-
position: absolute;
376-
font-size: 18px;
377-
font-family: var(--font-code);
378-
color: #999;
379-
top: 10px;
380-
right: 10px;
381-
z-index: 99;
382-
padding: 8px 10px 6px;
383-
background-color: var(--bg);
384-
border-radius: 4px;
385-
border: 1px solid var(--border);
386-
&:hover {
387-
color: var(--color-branding);
388-
}
389-
}
390338
</style>

0 commit comments

Comments
 (0)