1
1
<script lang="ts">
2
- import { ref , computed , watch , defineComponent , PropType } from ' @vue/composition-api'
3
- import { getStorage , setStorage } from ' @vue-devtools/shared-utils'
2
+ import { ref , computed , defineComponent , PropType } from ' @vue/composition-api'
4
3
import { useOrientation } from ' ./orientation'
4
+ import { useSavedRef } from ' @front/util/reactivity'
5
5
6
6
export default defineComponent ({
7
7
props: {
@@ -30,24 +30,33 @@ export default defineComponent({
30
30
type: String ,
31
31
default: null ,
32
32
},
33
+
34
+ collapsableLeft: {
35
+ type: Boolean ,
36
+ default: false ,
37
+ },
38
+
39
+ collapsableRight: {
40
+ type: Boolean ,
41
+ default: false ,
42
+ },
33
43
},
34
44
35
45
setup (props ) {
36
46
const { orientation } = useOrientation ()
37
47
38
48
const split = ref (props .defaultSplit )
49
+ const leftCollapsed = ref (false )
50
+ const rightCollapsed = ref (false )
39
51
40
52
if (props .saveId ) {
41
- const storageKey = ` split-pane-${props .saveId } `
42
-
43
- const savedValue = getStorage (storageKey )
44
- if (savedValue != null && typeof savedValue === ' number' ) {
45
- split .value = savedValue
53
+ useSavedRef (split , ` split-pane-${props .saveId } ` )
54
+ if (props .collapsableLeft ) {
55
+ useSavedRef (leftCollapsed , ` split-pane-collapsed-left-${props .saveId } ` )
56
+ }
57
+ if (props .collapsableRight ) {
58
+ useSavedRef (rightCollapsed , ` split-pane-collapsed-right-${props .saveId } ` )
46
59
}
47
-
48
- watch (split , value => {
49
- setStorage (storageKey , value )
50
- })
51
60
}
52
61
53
62
const boundSplit = computed (() => {
@@ -61,11 +70,11 @@ export default defineComponent({
61
70
})
62
71
63
72
const leftStyle = computed (() => ({
64
- [orientation .value === ' landscape' ? ' width' : ' height' ]: ` ${boundSplit .value }% ` ,
73
+ [orientation .value === ' landscape' ? ' width' : ' height' ]: ` ${leftCollapsed . value ? 0 : rightCollapsed . value ? 100 : boundSplit .value }% ` ,
65
74
}))
66
75
67
76
const rightStyle = computed (() => ({
68
- [orientation .value === ' landscape' ? ' width' : ' height' ]: ` ${100 - boundSplit .value }% ` ,
77
+ [orientation .value === ' landscape' ? ' width' : ' height' ]: ` ${rightCollapsed . value ? 0 : leftCollapsed . value ? 100 : 100 - boundSplit .value }% ` ,
69
78
}))
70
79
71
80
const dragging = ref (false )
@@ -99,6 +108,24 @@ export default defineComponent({
99
108
dragging .value = false
100
109
}
101
110
111
+ // Collapsing
112
+
113
+ function collapseLeft () {
114
+ if (rightCollapsed .value ) {
115
+ rightCollapsed .value = false
116
+ } else {
117
+ leftCollapsed .value = true
118
+ }
119
+ }
120
+
121
+ function collapseRight () {
122
+ if (leftCollapsed .value ) {
123
+ leftCollapsed .value = false
124
+ } else {
125
+ rightCollapsed .value = true
126
+ }
127
+ }
128
+
102
129
return {
103
130
el ,
104
131
dragging ,
@@ -108,6 +135,10 @@ export default defineComponent({
108
135
dragEnd ,
109
136
leftStyle ,
110
137
rightStyle ,
138
+ leftCollapsed ,
139
+ rightCollapsed ,
140
+ collapseLeft ,
141
+ collapseRight ,
111
142
}
112
143
},
113
144
})
@@ -131,13 +162,17 @@ export default defineComponent({
131
162
class =" relative top-0 left-0"
132
163
:class =" {
133
164
'pointer-events-none': dragging,
134
- 'border-r border-gray-200 dark:border-gray-800': orientation === 'landscape'
165
+ 'border-r border-gray-200 dark:border-gray-800': orientation === 'landscape' && !leftCollapsed && !rightCollapsed,
135
166
}"
136
167
:style =" leftStyle"
137
168
>
138
- <slot name =" left" />
169
+ <slot
170
+ v-if =" !leftCollapsed"
171
+ name =" left"
172
+ />
139
173
140
174
<div
175
+ v-if =" !leftCollapsed && !rightCollapsed"
141
176
class =" dragger absolute z-100 hover:bg-green-500 hover:bg-opacity-25 transition-colors duration-150 delay-150"
142
177
:class =" {
143
178
'top-0 bottom-0 cursor-ew-resize': orientation === 'landscape',
@@ -146,6 +181,21 @@ export default defineComponent({
146
181
}"
147
182
@mousedown.prevent =" dragStart"
148
183
/>
184
+
185
+ <div
186
+ v-if =" (collapsableLeft && !leftCollapsed) || rightCollapsed"
187
+ class =" collapse-btn absolute z-[101] flex items-center pointer-events-none"
188
+ :class =" {
189
+ 'top-0 bottom-0 right-0': orientation === 'landscape',
190
+ 'left-0 right-0 bottom-0 flex-col': orientation === 'portrait',
191
+ }"
192
+ >
193
+ <VueButton
194
+ :icon-left =" orientation === 'landscape' ? 'arrow_left': 'arrow_drop_up'"
195
+ class =" block icon-button flat pointer-events-auto opacity-40 hover:opacity-100"
196
+ @click =" collapseLeft()"
197
+ />
198
+ </div >
149
199
</div >
150
200
<div
151
201
class =" relative bottom-0 right-0"
@@ -155,7 +205,25 @@ export default defineComponent({
155
205
}"
156
206
:style =" rightStyle"
157
207
>
158
- <slot name =" right" />
208
+ <div
209
+ v-if =" (collapsableRight && !rightCollapsed) || leftCollapsed"
210
+ class =" collapse-btn absolute z-[101] flex items-center pointer-events-none"
211
+ :class =" {
212
+ 'top-0 bottom-0 left-0': orientation === 'landscape',
213
+ 'left-0 right-0 top-0 flex-col': orientation === 'portrait',
214
+ }"
215
+ >
216
+ <VueButton
217
+ :icon-left =" orientation === 'landscape' ? 'arrow_right': 'arrow_drop_down'"
218
+ class =" block icon-button flat pointer-events-auto opacity-40 hover:opacity-100"
219
+ @click =" collapseRight()"
220
+ />
221
+ </div >
222
+
223
+ <slot
224
+ v-if =" !rightCollapsed"
225
+ name =" right"
226
+ />
159
227
</div >
160
228
</div >
161
229
</template >
@@ -200,4 +268,14 @@ export default defineComponent({
200
268
}
201
269
}
202
270
}
271
+
272
+ .collapse-btn {
273
+ .icon-button {
274
+ @apply w-2.5 h-6 rounded-sm !important ;
275
+
276
+ .portrait & {
277
+ @apply w-6 h-2.5 !important ;
278
+ }
279
+ }
280
+ }
203
281
</style >
0 commit comments