mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-04-06 03:57:56 +08:00
feat(editor): 选中页面后页面列表自动滚动到选中项
This commit is contained in:
parent
0727fe4fea
commit
7a47315bc1
@ -1,6 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="m-editor-page-bar-tabs">
|
<div class="m-editor-page-bar-tabs">
|
||||||
<PageBarScrollContainer :page-bar-sort-options="pageBarSortOptions" :length="list.length">
|
<PageBarScrollContainer
|
||||||
|
ref="pageBarScrollContainer"
|
||||||
|
:page-bar-sort-options="pageBarSortOptions"
|
||||||
|
:length="list.length"
|
||||||
|
>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<slot name="page-bar-add-button"><AddButton></AddButton></slot>
|
<slot name="page-bar-add-button"><AddButton></AddButton></slot>
|
||||||
|
|
||||||
@ -13,8 +17,9 @@
|
|||||||
<div
|
<div
|
||||||
v-for="item in list"
|
v-for="item in list"
|
||||||
class="m-editor-page-bar-item"
|
class="m-editor-page-bar-item"
|
||||||
|
ref="pageBarItems"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:page-id="item.id"
|
:data-page-id="item.id"
|
||||||
:class="{ active: page?.id === item.id }"
|
:class="{ active: page?.id === item.id }"
|
||||||
@click="switchPage(item.id)"
|
@click="switchPage(item.id)"
|
||||||
>
|
>
|
||||||
@ -63,7 +68,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, ref } from 'vue';
|
import { computed, inject, ref, watch } from 'vue';
|
||||||
import { CaretBottom, Delete, DocumentCopy } from '@element-plus/icons-vue';
|
import { CaretBottom, Delete, DocumentCopy } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
import { type Id, type MPage, type MPageFragment, NodeType } from '@tmagic/core';
|
import { type Id, type MPage, type MPageFragment, NodeType } from '@tmagic/core';
|
||||||
@ -138,4 +143,42 @@ const copy = (node: MPage | MPageFragment) => {
|
|||||||
const remove = (node: MPage | MPageFragment) => {
|
const remove = (node: MPage | MPageFragment) => {
|
||||||
editorService?.remove(node);
|
editorService?.remove(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pageBarScrollContainer = ref<InstanceType<typeof PageBarScrollContainer>>();
|
||||||
|
const pageBarItems = ref<HTMLDivElement[]>();
|
||||||
|
watch(page, (page) => {
|
||||||
|
if (
|
||||||
|
!page ||
|
||||||
|
!pageBarScrollContainer.value?.itemsContainerWidth ||
|
||||||
|
!pageBarItems.value ||
|
||||||
|
pageBarItems.value.length < 2
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstItem = pageBarItems.value[0];
|
||||||
|
const lastItem = pageBarItems.value[pageBarItems.value.length - 1];
|
||||||
|
|
||||||
|
if (page.id === firstItem.dataset.pageId) {
|
||||||
|
pageBarScrollContainer.value.scroll('start');
|
||||||
|
} else if (page.id === lastItem.dataset.pageId) {
|
||||||
|
pageBarScrollContainer.value.scroll('end');
|
||||||
|
} else {
|
||||||
|
const pageItem = pageBarItems.value.find((item) => item.dataset.pageId === page.id);
|
||||||
|
if (!pageItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageItemRect = pageItem.getBoundingClientRect();
|
||||||
|
const offsetLeft = pageItemRect.left - firstItem.getBoundingClientRect().left;
|
||||||
|
const { itemsContainerWidth } = pageBarScrollContainer.value;
|
||||||
|
|
||||||
|
const left = itemsContainerWidth - offsetLeft - pageItemRect.width;
|
||||||
|
|
||||||
|
const translateLeft = pageBarScrollContainer.value.getTranslateLeft();
|
||||||
|
if (offsetLeft + translateLeft < 0 || offsetLeft + pageItemRect.width > itemsContainerWidth - translateLeft) {
|
||||||
|
pageBarScrollContainer.value.scrollTo(left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -92,22 +92,29 @@ const scroll = (type: 'left' | 'right' | 'start' | 'end') => {
|
|||||||
const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
|
const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
|
||||||
|
|
||||||
if (type === 'left') {
|
if (type === 'left') {
|
||||||
translateLeft += 200;
|
scrollTo(translateLeft + 200);
|
||||||
|
|
||||||
if (translateLeft > 0) {
|
|
||||||
translateLeft = 0;
|
|
||||||
}
|
|
||||||
} else if (type === 'right') {
|
} else if (type === 'right') {
|
||||||
translateLeft -= 200;
|
scrollTo(translateLeft - 200);
|
||||||
|
|
||||||
if (-translateLeft > maxScrollLeft) {
|
|
||||||
translateLeft = -maxScrollLeft;
|
|
||||||
}
|
|
||||||
} else if (type === 'start') {
|
} else if (type === 'start') {
|
||||||
translateLeft = 0;
|
scrollTo(0);
|
||||||
} else if (type === 'end') {
|
} else if (type === 'end') {
|
||||||
translateLeft = -maxScrollLeft;
|
scrollTo(-maxScrollLeft);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const scrollTo = (value: number) => {
|
||||||
|
if (!itemsContainer.value || !canScroll.value) return;
|
||||||
|
const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
|
||||||
|
|
||||||
|
if (value >= 0) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-value > maxScrollLeft) {
|
||||||
|
value = -maxScrollLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
translateLeft = value;
|
||||||
|
|
||||||
itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
|
itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
|
||||||
};
|
};
|
||||||
@ -159,4 +166,13 @@ watch(
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
itemsContainerWidth,
|
||||||
|
scroll,
|
||||||
|
scrollTo,
|
||||||
|
getTranslateLeft() {
|
||||||
|
return translateLeft;
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -57,7 +57,7 @@ const editorService = services?.editorService;
|
|||||||
|
|
||||||
const showPageListButton = computed(() => uiService?.get('showPageListButton'));
|
const showPageListButton = computed(() => uiService?.get('showPageListButton'));
|
||||||
const page = computed(() => editorService?.get('page'));
|
const page = computed(() => editorService?.get('page'));
|
||||||
const switchPage = (id: Id) => {
|
const switchPage = async (id: Id) => {
|
||||||
editorService?.select(id);
|
await editorService?.select(id);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user