Skip to content

Commit ab04f34

Browse files
ArturoManzolirafaellehmkuhl
authored andcommitted
Components: Add side config panel
Signed-off-by: Arturo Manzoli <arturomanzoli@gmail.com>
1 parent ecb8312 commit ab04f34

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

src/components/SideConfigPanel.vue

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<template>
2+
<transition
3+
:enter-active-class="enterActiveClass"
4+
:leave-active-class="leaveActiveClass"
5+
:enter-from-class="enterFromClass"
6+
:enter-to-class="enterToClass"
7+
:leave-from-class="leaveFromClass"
8+
:leave-to-class="leaveToClass"
9+
>
10+
<div v-if="visible" class="fixed shadow-lg" :class="panelPositionClass">
11+
<v-btn
12+
v-if="hideButton"
13+
icon
14+
size="x-small"
15+
variant="text"
16+
class="close_btn bg-transparent text-white"
17+
@click="closePanel"
18+
>
19+
<v-icon class="text-[18px]">{{ `mdi-arrow-${position}` }}</v-icon>
20+
</v-btn>
21+
<slot></slot>
22+
</div>
23+
</transition>
24+
</template>
25+
26+
<script setup lang="ts">
27+
import { computed, defineProps } from 'vue'
28+
29+
import { useAppInterfaceStore } from '@/stores/appInterface'
30+
31+
const interfaceStore = useAppInterfaceStore()
32+
33+
const props = defineProps<{
34+
/**
35+
* Panel position
36+
*/
37+
position?: 'right' | 'bottom' | 'top' | 'left'
38+
/**
39+
* hide button
40+
*/
41+
hideButton?: boolean
42+
}>()
43+
44+
const visible = computed(() => interfaceStore.configPanelVisible)
45+
46+
const closePanel = (): void => {
47+
interfaceStore.configPanelVisible = false
48+
}
49+
50+
const enterActiveClass = 'transition-transform duration-500 ease-in-out'
51+
const leaveActiveClass = 'transition-transform duration-0 ease-in-out'
52+
53+
const enterFromClass = computed(() => {
54+
switch (props.position) {
55+
case 'right':
56+
return 'translate-x-full opacity-0'
57+
case 'bottom':
58+
return 'translate-y-full opacity-0'
59+
case 'top':
60+
return '-translate-y-full opacity-0'
61+
case 'left':
62+
default:
63+
return '-translate-x-full opacity-0'
64+
}
65+
})
66+
const enterToClass = 'translate-x-0 translate-y-0 opacity-100'
67+
const leaveFromClass = 'translate-x-0 translate-y-0 opacity-100'
68+
const leaveToClass = computed(() => {
69+
switch (props.position) {
70+
case 'right':
71+
return 'translate-x-full opacity-0'
72+
case 'bottom':
73+
return 'translate-y-full opacity-0'
74+
case 'top':
75+
return '-translate-y-full opacity-0'
76+
case 'left':
77+
default:
78+
return '-translate-x-full opacity-0'
79+
}
80+
})
81+
82+
const panelPositionClass = computed(() => {
83+
switch (props.position) {
84+
case 'right':
85+
return 'right-0 top-0 bottom-0 w-64'
86+
case 'bottom':
87+
return 'left-0 right-0 bottom-0 h-64'
88+
case 'top':
89+
return 'left-0 right-0 top-0 h-64'
90+
case 'left':
91+
default:
92+
return 'left-0 top-0 bottom-0 w-64'
93+
}
94+
})
95+
</script>
96+
97+
<style scoped>
98+
.fixed {
99+
height: 100%;
100+
z-index: 500;
101+
pointer-events: all;
102+
}
103+
.close_btn {
104+
z-index: 500;
105+
position: absolute;
106+
margin-top: 3px;
107+
}
108+
</style>

0 commit comments

Comments
 (0)