forked from verdnatura/salix-front
Add scroll on LeftMenu item expansion
This commit is contained in:
parent
7eca27b8af
commit
c767bcde7d
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, ref, reactive } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { QSeparator, useQuasar } from 'quasar';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
@ -22,6 +22,8 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const expansionItemElements = reactive({});
|
||||
|
||||
onMounted(async () => {
|
||||
await navigation.fetchPinned();
|
||||
getRoutes();
|
||||
|
@ -108,6 +110,10 @@ async function togglePinned(item, event) {
|
|||
type: 'positive',
|
||||
});
|
||||
}
|
||||
|
||||
const handleItemExpansion = (itemName) => {
|
||||
expansionItemElements[itemName].scrollToLastElement();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -213,8 +219,12 @@ async function togglePinned(item, event) {
|
|||
:icon="item.icon"
|
||||
:label="t(item.title)"
|
||||
:content-inset-level="0.5"
|
||||
@after-show="handleItemExpansion(item.name)"
|
||||
>
|
||||
<LeftMenuItemGroup :item="item" />
|
||||
<LeftMenuItemGroup
|
||||
:ref="(el) => (expansionItemElements[item.name] = el)"
|
||||
:item="item"
|
||||
/>
|
||||
</QExpansionItem>
|
||||
</QList>
|
||||
</template>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { computed, ref, defineExpose } from 'vue';
|
||||
import LeftMenuItem from './LeftMenuItem.vue';
|
||||
import { elementIsVisibleInViewport } from 'src/composables/elementIsVisibleInViewport';
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
|
@ -13,10 +14,27 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const groupEnd = ref(null);
|
||||
|
||||
const scrollToLastElement = () => {
|
||||
if (groupEnd.value && !elementIsVisibleInViewport(groupEnd.value)) {
|
||||
groupEnd.value.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'end',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const item = computed(() => props.item); // eslint-disable-line vue/no-dupe-keys
|
||||
|
||||
defineExpose({
|
||||
scrollToLastElement,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-for="section in item.children" :key="section.name">
|
||||
<LeftMenuItem :item="section" />
|
||||
</template>
|
||||
<div ref="groupEnd" />
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
export const elementIsVisibleInViewport = (el) => {
|
||||
const { top, left, bottom, right } = el.getBoundingClientRect();
|
||||
const { innerHeight, innerWidth } = window;
|
||||
|
||||
return top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
|
||||
};
|
Loading…
Reference in New Issue