Use normal context menus for sidebar submenus

This commit is contained in:
Johannes Zellner
2025-12-15 21:35:07 +01:00
parent c0ad75cc4d
commit b6df80dcef
2 changed files with 60 additions and 4 deletions
+29 -1
View File
@@ -20,7 +20,7 @@ defineProps({
const sideBar = useTemplateRef('sideBar');
const isVisible = ref(false);
const isCollapsed = ref(false);
const isCollapsed = ref(true);
function open() {
isVisible.value = true;
@@ -36,6 +36,10 @@ onMounted(() => {
});
});
function onToggleCollapse() {
isCollapsed.value = !isCollapsed.value;
}
</script>
<template>
@@ -57,9 +61,12 @@ onMounted(() => {
:active="item.active"
:separator="item.separator"
:child-items="item.childItems"
:collapsed="isCollapsed"
@close="close"
/>
</div>
<div style="flex-grow: 1"></div>
<div class="sidebar-collapse-action" @click="onToggleCollapse()"><i class="fa-solid" :class="{ 'fa-arrow-left': !isCollapsed, 'fa-arrow-right': isCollapsed }"></i> <span v-if="!isCollapsed">Collapse sidebar</span></div>
</div>
</div>
</template>
@@ -77,6 +84,27 @@ onMounted(() => {
min-width: 250px;
}
.sidebar-collapsed {
min-width: unset !important;
width: 70px;
}
.sidebar-collapse-action {
display: block;
color: gray;
border-radius: 3px;
padding: 10px 15px;
white-space: nowrap;
cursor: pointer;
transition: all 180ms ease-out;
}
.sidebar-collapse-action i {
opacity: 0.5;
margin-right: 10px;
}
.sidebar-inner {
display: flex;
flex-direction: column;
+31 -3
View File
@@ -1,6 +1,7 @@
<script setup>
import { ref, computed } from 'vue';
import { ref, computed, useTemplateRef } from 'vue';
import { Menu } from '@cloudron/pankow';
import SideBarItem from './SideBarItem.vue';
const emit = defineEmits(['close']);
@@ -23,6 +24,10 @@ const props = defineProps({
type: Boolean,
default: false,
},
collapsed: {
type: Boolean,
default: false,
},
visible: {
type: [ Boolean, Function ],
default: true,
@@ -49,13 +54,36 @@ function close() {
emit('close');
}
const menu = useTemplateRef('menu');
const elem = useTemplateRef('elem');
const subItems = computed(() => {
return props.childItems.map(i => {
return {
label: i.label,
icon: i.icon,
href: i.route,
};
});
});
function toggleMenu() {
if (props.collapsed) {
menu.value.open(event, elem.value);
} else {
isExpanded.value = !isExpanded.value;
}
}
</script>
<template>
<div v-if="isVisible">
<hr v-if="separator"/>
<a v-else-if="!childItems?.length" class="sidebar-item" :class="{ active: isActive }" :href="route" @click="close()"><i :class="icon"></i> {{ label }}</a>
<div v-else-if="childItems.length" class="sidebar-item" @click="isExpanded = !isExpanded"><i :class="icon"></i> {{ $t(label) }} <i class="collapse fa-solid fa-angle-right" :class="{ expanded: isExpanded }" style="margin-left: 6px;"></i></div>
<a v-else-if="!childItems?.length" class="sidebar-item" :class="{ active: isActive }" :href="route" @click="close()"><i :class="icon"></i> <span v-if="!collapsed">{{ label }}</span></a>
<div v-else-if="childItems.length" class="sidebar-item" ref="elem" @click="toggleMenu()"><i :class="icon"></i> <span v-if="!collapsed">{{ label }} <i class="collapse fa-solid fa-angle-right" :class="{ expanded: isExpanded }" style="margin-left: 6px;"></i></span></div>
<Menu ref="menu" :model="subItems"></Menu>
<Transition name="sidebar-item-group-animation">
<div class="sidebar-item-group" v-if="isExpanded">