Skip to content

Commit d59bb6c

Browse files
committed
feat: vertical mode
1 parent 313823f commit d59bb6c

File tree

3 files changed

+65
-12
lines changed

3 files changed

+65
-12
lines changed

src/Repl.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ interface Props {
1212
showImportMap?: boolean
1313
clearConsole?: boolean
1414
sfcOptions?: SFCOptions
15+
layout?: string
1516
}
1617
1718
const props = withDefaults(defineProps<Props>(), {
@@ -32,7 +33,7 @@ provide('clear-console', toRef(props, 'clearConsole'))
3233

3334
<template>
3435
<div class="vue-repl">
35-
<SplitPane>
36+
<SplitPane :layout="layout">
3637
<template #left>
3738
<Editor />
3839
</template>

src/SplitPane.vue

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<script setup lang="ts">
2-
import { ref, reactive } from 'vue'
2+
import { ref, reactive, computed } from 'vue'
3+
4+
const props = defineProps<{ layout?: string }>()
5+
const isVertical = computed(() => props.layout === 'vertical')
36
47
const container = ref()
58
@@ -21,14 +24,16 @@ let startSplit = 0
2124
2225
function dragStart(e: MouseEvent) {
2326
state.dragging = true
24-
startPosition = e.pageX
27+
startPosition = isVertical.value ? e.pageY : e.pageX
2528
startSplit = boundSplit()
2629
}
2730
2831
function dragMove(e: MouseEvent) {
2932
if (state.dragging) {
30-
const position = e.pageX
31-
const totalSize = container.value.offsetWidth
33+
const position = isVertical.value ? e.pageY : e.pageX
34+
const totalSize = isVertical.value
35+
? container.value.offsetHeight
36+
: container.value.offsetWidth
3237
const dp = position - startPosition
3338
state.split = startSplit + ~~((dp / totalSize) * 100)
3439
}
@@ -43,16 +48,26 @@ function dragEnd() {
4348
<div
4449
ref="container"
4550
class="split-pane"
46-
:class="{ dragging: state.dragging, 'show-output': showOutput }"
51+
:class="{
52+
dragging: state.dragging,
53+
'show-output': showOutput,
54+
vertical: isVertical
55+
}"
4756
@mousemove="dragMove"
4857
@mouseup="dragEnd"
4958
@mouseleave="dragEnd"
5059
>
51-
<div class="left" :style="{ width: boundSplit() + '%' }">
60+
<div
61+
class="left"
62+
:style="{ [isVertical ? 'height' : 'width']: boundSplit() + '%' }"
63+
>
5264
<slot name="left" />
5365
<div class="dragger" @mousedown.prevent="dragStart" />
5466
</div>
55-
<div class="right" :style="{ width: 100 - boundSplit() + '%' }">
67+
<div
68+
class="right"
69+
:style="{ [isVertical ? 'height' : 'width']: 100 - boundSplit() + '%' }"
70+
>
5671
<slot name="right" />
5772
</div>
5873

@@ -110,15 +125,51 @@ function dragEnd() {
110125
.dark .toggler {
111126
background-color: var(--bg);
112127
}
113-
@media (max-width: 720px) {
114-
.toggler {
128+
129+
/* vertical */
130+
@media (min-width: 721px) {
131+
.split-pane.vertical {
115132
display: block;
116133
}
134+
135+
.split-pane.vertical.dragging {
136+
cursor: ns-resize;
137+
}
138+
139+
.vertical .dragger {
140+
top: auto;
141+
height: 10px;
142+
width: 100%;
143+
left: 0;
144+
right: 0;
145+
bottom: -5px;
146+
cursor: ns-resize;
147+
}
148+
149+
.vertical .left,
150+
.vertical .right {
151+
width: 100%;
152+
}
153+
.vertical .left {
154+
border-right: none;
155+
border-bottom: 1px solid var(--border);
156+
}
157+
}
158+
159+
/* mobile */
160+
@media (max-width: 720px) {
117161
.left,
118162
.right {
119163
width: 100% !important;
164+
height: 100% !important;
120165
}
121-
.right {
166+
.dragger {
167+
display: none;
168+
}
169+
.split-pane .toggler {
170+
display: block;
171+
}
172+
.split-pane .right {
122173
display: none;
123174
}
124175
.split-pane.show-output .right {

test/main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ const App = {
3131

3232
return () =>
3333
h(Repl, {
34-
store
34+
store,
35+
layout: 'vertical'
3536
// showCompileOutput: false,
3637
// showImportMap: false
3738
})

0 commit comments

Comments
 (0)