-
Notifications
You must be signed in to change notification settings - Fork 1
/
DoubleSidebarLayout.vue
100 lines (75 loc) · 2.59 KB
/
DoubleSidebarLayout.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<template>
<div class="double-sidebar-grid" ref="doubleSidebarLayoutContainer">
<div class="side-menu-container" :hidden="hideMenuL">
<slot name="sidebarA"></slot>
</div>
<div class="resize-border-v left" @mousedown="resizeMenu($event, 'left')">
<button @click="toggleMenuL" class="btn-toggle-menu"><span v-if="!hideMenuL"><</span><span v-else>></span></button>
</div>
<slot></slot>
<div class="resize-border-v right" @mousedown="resizeMenu($event, 'right')">
<button @click="toggleMenuR" class="btn-toggle-menu"><span v-if="!hideMenuR">></span><span v-else><</span></button>
</div>
<div class="side-menu-container" :hidden="hideMenuR">
<slot name="sidebarB"></slot>
</div>
</div>
</template>
<script setup>
import { ref, inject } from "vue"
let hideMenuL = ref(false)
let hideMenuR = ref(false)
const eventBus = inject('eventBus')
const doubleSidebarLayoutContainer = ref(null)
// State
let resizing = false
let leftWidth = 290
let rightWidth = 290
function toggleMenuL () {
hideMenuL.value = !hideMenuL.value
adjustLayout()
}
function toggleMenuR () {
hideMenuR.value = !hideMenuR.value
adjustLayout()
}
function adjustLayout () {
let left = hideMenuL.value ? "" : `${leftWidth}px `
let middle ="10px auto 10px"
let right = hideMenuR.value ? "" : ` ${rightWidth}px`
doubleSidebarLayoutContainer.value.style.gridTemplateColumns = left + middle + right
// Doing this immediately does not work. There needs to be a slight delay.
setTimeout(() => {eventBus.emit('Layout.contentResize')}, 250)
}
function resizeMenu (evt, side) {
resizing = true
document.body.onmouseup = () => {
resizing = false
document.body.onmousemove = null
}
document.body.onmousemove = (evt) => {
const minWidth = 220 // px
if (!resizing) return
let mouseX = evt.clientX
if (side === 'left') {
leftWidth = mouseX
if (leftWidth < minWidth) leftWidth = minWidth
} else if (side === 'right') {
rightWidth = doubleSidebarLayoutContainer.value.clientWidth - mouseX
if (rightWidth < minWidth) rightWidth = minWidth
} else {
throw new Error('Unclear layout resize instructions.')
}
doubleSidebarLayoutContainer.value.style.gridTemplateColumns = `${leftWidth}px 10px auto 10px ${rightWidth}px`
// Resize child component
eventBus.emit('Layout.contentResize')
}
}
</script>
<style lang="scss" scoped>
.double-sidebar-grid {
height: 100%;
display: grid;
grid-template-columns: 290px 10px auto 10px 290px; // Menu, resize-border, workspace
}
</style>