1
1
<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' )
3
6
4
7
const container = ref ()
5
8
@@ -21,14 +24,16 @@ let startSplit = 0
21
24
22
25
function dragStart(e : MouseEvent ) {
23
26
state .dragging = true
24
- startPosition = e .pageX
27
+ startPosition = isVertical . value ? e . pageY : e .pageX
25
28
startSplit = boundSplit ()
26
29
}
27
30
28
31
function dragMove(e : MouseEvent ) {
29
32
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
32
37
const dp = position - startPosition
33
38
state .split = startSplit + ~~ ((dp / totalSize ) * 100 )
34
39
}
@@ -43,16 +48,26 @@ function dragEnd() {
43
48
<div
44
49
ref =" container"
45
50
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
+ }"
47
56
@mousemove =" dragMove"
48
57
@mouseup =" dragEnd"
49
58
@mouseleave =" dragEnd"
50
59
>
51
- <div class =" left" :style =" { width: boundSplit() + '%' }" >
60
+ <div
61
+ class =" left"
62
+ :style =" { [isVertical ? 'height' : 'width']: boundSplit() + '%' }"
63
+ >
52
64
<slot name =" left" />
53
65
<div class =" dragger" @mousedown.prevent =" dragStart" />
54
66
</div >
55
- <div class =" right" :style =" { width: 100 - boundSplit() + '%' }" >
67
+ <div
68
+ class =" right"
69
+ :style =" { [isVertical ? 'height' : 'width']: 100 - boundSplit() + '%' }"
70
+ >
56
71
<slot name =" right" />
57
72
</div >
58
73
@@ -110,15 +125,51 @@ function dragEnd() {
110
125
.dark .toggler {
111
126
background-color : var (--bg );
112
127
}
113
- @media (max-width : 720px ) {
114
- .toggler {
128
+
129
+ /* vertical */
130
+ @media (min-width : 721px ) {
131
+ .split-pane.vertical {
115
132
display : block ;
116
133
}
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 ) {
117
161
.left ,
118
162
.right {
119
163
width : 100% !important ;
164
+ height : 100% !important ;
120
165
}
121
- .right {
166
+ .dragger {
167
+ display : none ;
168
+ }
169
+ .split-pane .toggler {
170
+ display : block ;
171
+ }
172
+ .split-pane .right {
122
173
display : none ;
123
174
}
124
175
.split-pane.show-output .right {
0 commit comments