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>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref, reactive } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { QSeparator, useQuasar } from 'quasar';
|
import { QSeparator, useQuasar } from 'quasar';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
@ -22,6 +22,8 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const expansionItemElements = reactive({});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await navigation.fetchPinned();
|
await navigation.fetchPinned();
|
||||||
getRoutes();
|
getRoutes();
|
||||||
|
@ -108,6 +110,10 @@ async function togglePinned(item, event) {
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleItemExpansion = (itemName) => {
|
||||||
|
expansionItemElements[itemName].scrollToLastElement();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -213,8 +219,12 @@ async function togglePinned(item, event) {
|
||||||
:icon="item.icon"
|
:icon="item.icon"
|
||||||
:label="t(item.title)"
|
:label="t(item.title)"
|
||||||
:content-inset-level="0.5"
|
:content-inset-level="0.5"
|
||||||
|
@after-show="handleItemExpansion(item.name)"
|
||||||
>
|
>
|
||||||
<LeftMenuItemGroup :item="item" />
|
<LeftMenuItemGroup
|
||||||
|
:ref="(el) => (expansionItemElements[item.name] = el)"
|
||||||
|
:item="item"
|
||||||
|
/>
|
||||||
</QExpansionItem>
|
</QExpansionItem>
|
||||||
</QList>
|
</QList>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue';
|
import { computed, ref, defineExpose } from 'vue';
|
||||||
import LeftMenuItem from './LeftMenuItem.vue';
|
import LeftMenuItem from './LeftMenuItem.vue';
|
||||||
|
import { elementIsVisibleInViewport } from 'src/composables/elementIsVisibleInViewport';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
item: {
|
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
|
const item = computed(() => props.item); // eslint-disable-line vue/no-dupe-keys
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
scrollToLastElement,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<template v-for="section in item.children" :key="section.name">
|
<template v-for="section in item.children" :key="section.name">
|
||||||
<LeftMenuItem :item="section" />
|
<LeftMenuItem :item="section" />
|
||||||
</template>
|
</template>
|
||||||
|
<div ref="groupEnd" />
|
||||||
</template>
|
</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