Skip to content

Commit 38077dc

Browse files
committed
feat(timeline): collapse panes
1 parent f8f457a commit 38077dc

File tree

4 files changed

+109
-17
lines changed

4 files changed

+109
-17
lines changed

packages/app-frontend/src/features/layout/SplitPane.vue

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<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'
43
import { useOrientation } from './orientation'
4+
import { useSavedRef } from '@front/util/reactivity'
55
66
export default defineComponent({
77
props: {
@@ -30,24 +30,33 @@ export default defineComponent({
3030
type: String,
3131
default: null,
3232
},
33+
34+
collapsableLeft: {
35+
type: Boolean,
36+
default: false,
37+
},
38+
39+
collapsableRight: {
40+
type: Boolean,
41+
default: false,
42+
},
3343
},
3444
3545
setup (props) {
3646
const { orientation } = useOrientation()
3747
3848
const split = ref(props.defaultSplit)
49+
const leftCollapsed = ref(false)
50+
const rightCollapsed = ref(false)
3951
4052
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}`)
4659
}
47-
48-
watch(split, value => {
49-
setStorage(storageKey, value)
50-
})
5160
}
5261
5362
const boundSplit = computed(() => {
@@ -61,11 +70,11 @@ export default defineComponent({
6170
})
6271
6372
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}%`,
6574
}))
6675
6776
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}%`,
6978
}))
7079
7180
const dragging = ref(false)
@@ -99,6 +108,24 @@ export default defineComponent({
99108
dragging.value = false
100109
}
101110
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+
102129
return {
103130
el,
104131
dragging,
@@ -108,6 +135,10 @@ export default defineComponent({
108135
dragEnd,
109136
leftStyle,
110137
rightStyle,
138+
leftCollapsed,
139+
rightCollapsed,
140+
collapseLeft,
141+
collapseRight,
111142
}
112143
},
113144
})
@@ -131,13 +162,17 @@ export default defineComponent({
131162
class="relative top-0 left-0"
132163
:class="{
133164
'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,
135166
}"
136167
:style="leftStyle"
137168
>
138-
<slot name="left" />
169+
<slot
170+
v-if="!leftCollapsed"
171+
name="left"
172+
/>
139173

140174
<div
175+
v-if="!leftCollapsed && !rightCollapsed"
141176
class="dragger absolute z-100 hover:bg-green-500 hover:bg-opacity-25 transition-colors duration-150 delay-150"
142177
:class="{
143178
'top-0 bottom-0 cursor-ew-resize': orientation === 'landscape',
@@ -146,6 +181,21 @@ export default defineComponent({
146181
}"
147182
@mousedown.prevent="dragStart"
148183
/>
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>
149199
</div>
150200
<div
151201
class="relative bottom-0 right-0"
@@ -155,7 +205,25 @@ export default defineComponent({
155205
}"
156206
:style="rightStyle"
157207
>
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+
/>
159227
</div>
160228
</div>
161229
</template>
@@ -200,4 +268,14 @@ export default defineComponent({
200268
}
201269
}
202270
}
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+
}
203281
</style>

packages/app-frontend/src/features/timeline/Timeline.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ export default defineComponent({
353353
:default-split="50"
354354
:max="85"
355355
dragger-offset="after"
356+
collapsable-left
357+
collapsable-right
356358
>
357359
<template #left>
358360
<div class="h-full flex flex-col select-none">

packages/app-frontend/src/features/timeline/TimelineEventListItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export default defineComponent({
3535

3636
<template>
3737
<div
38-
class="event border-gray-100 dark:border-gray-900 border-b flex items-center space-x-2 px-2 text-xs cursor-pointer select-none"
38+
class="event border-gray-100 dark:border-gray-900 border-b flex items-center space-x-2 pl-3 pr-2 text-xs cursor-pointer select-none"
3939
:class="{
4040
'inspected bg-green-500 text-white': isInspected,
4141
'hover:bg-blue-100 dark:hover:bg-blue-900 text-bluegray-800 dark:text-bluegray-200': !isInspected

packages/app-frontend/src/util/reactivity.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Ref, watch } from '@vue/composition-api'
2+
import { getStorage, setStorage } from '@vue-devtools/shared-utils'
23

34
export function nonReactive<T> (ref: Ref<T>) {
45
const holder = {
@@ -24,3 +25,14 @@ export function addNonReactiveProperties<T = any> (target: T, props: Partial<T>)
2425
})
2526
}
2627
}
28+
29+
export function useSavedRef<T> (ref: Ref<T>, storageKey: string) {
30+
const savedValue = getStorage(storageKey)
31+
if (savedValue != null) {
32+
ref.value = savedValue
33+
}
34+
35+
watch(ref, value => {
36+
setStorage(storageKey, value)
37+
})
38+
}

0 commit comments

Comments
 (0)