diff --git a/docs/PROJECT_REVIEW.md b/docs/PROJECT_REVIEW.md index 6256093..0123b3c 100644 --- a/docs/PROJECT_REVIEW.md +++ b/docs/PROJECT_REVIEW.md @@ -131,18 +131,16 @@ async function safeInvoke(fn: () => Promise, errorMsg?: string): Promise(fn: () => Promise, errorMsg?: string): Promise +import { ref, computed, onMounted, onUnmounted, watch } from 'vue' +import { useVirtualizer } from '@tanstack/vue-virtual' + +const props = withDefaults(defineProps<{ + items: any[] + itemHeight?: number + overscan?: number + height?: string +}>(), { + itemHeight: 36, + overscan: 5, + height: '100%', +}) + +const emit = defineEmits<{ + (e: 'scrollEnd'): void +}>() + +const scrollRef = ref(null) + +const virtualizer = useVirtualizer( + computed(() => ({ + count: props.items.length, + getScrollElement: () => scrollRef.value, + estimateSize: () => props.itemHeight, + overscan: props.overscan, + })) +) + +const virtualItems = computed(() => virtualizer.value.getVirtualItems()) +const totalHeight = computed(() => virtualizer.value.getTotalSize()) + +// Emit scrollEnd when user scrolls near the bottom +function onScroll() { + const el = scrollRef.value + if (!el) return + if (el.scrollTop + el.clientHeight >= el.scrollHeight - props.itemHeight * 5) { + emit('scrollEnd') + } +} + +// Reset scroll position when items array reference changes entirely +watch(() => props.items, (newItems, oldItems) => { + if (newItems.length === 0 && oldItems && oldItems.length > 0) { + virtualizer.value.scrollToIndex(0) + } +}) + + + + + diff --git a/src/renderer/src/components/editors/ListEditor.vue b/src/renderer/src/components/editors/ListEditor.vue index 6245058..563c0c2 100644 --- a/src/renderer/src/components/editors/ListEditor.vue +++ b/src/renderer/src/components/editors/ListEditor.vue @@ -1,10 +1,11 @@