Files
agenciapsilmno/src/layout/AppSidebar.vue
2025-12-25 10:03:32 +03:00

67 lines
1.8 KiB
Vue

<script setup>
import { useLayout } from '@/layout/composables/layout';
import { onBeforeUnmount, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import AppMenu from './AppMenu.vue';
const { layoutState, isDesktop, hasOpenOverlay } = useLayout();
const route = useRoute();
const sidebarRef = ref(null);
let outsideClickListener = null;
watch(
() => route.path,
(newPath) => {
if (isDesktop()) layoutState.activePath = null;
else layoutState.activePath = newPath;
layoutState.overlayMenuActive = false;
layoutState.mobileMenuActive = false;
layoutState.menuHoverActive = false;
},
{ immediate: true }
);
watch(hasOpenOverlay, (newVal) => {
if (isDesktop()) {
if (newVal) bindOutsideClickListener();
else unbindOutsideClickListener();
}
});
const bindOutsideClickListener = () => {
if (!outsideClickListener) {
outsideClickListener = (event) => {
if (isOutsideClicked(event)) {
layoutState.overlayMenuActive = false;
}
};
document.addEventListener('click', outsideClickListener);
}
};
const unbindOutsideClickListener = () => {
if (outsideClickListener) {
document.removeEventListener('click', outsideClickListener);
outsideClickListener = null;
}
};
const isOutsideClicked = (event) => {
const topbarButtonEl = document.querySelector('.layout-menu-button');
return !(sidebarRef.value.isSameNode(event.target) || sidebarRef.value.contains(event.target) || topbarButtonEl?.isSameNode(event.target) || topbarButtonEl?.contains(event.target));
};
onBeforeUnmount(() => {
unbindOutsideClickListener();
});
</script>
<template>
<div ref="sidebarRef" class="layout-sidebar">
<AppMenu />
</div>
</template>