feature/ux-improvements #26
@@ -10,6 +10,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts" generics="T">
|
<script lang="ts" generics="T">
|
||||||
import { createVirtualizer } from '$shared/lib';
|
import { createVirtualizer } from '$shared/lib';
|
||||||
|
import { throttle } from '$shared/lib/utils';
|
||||||
import { ScrollArea } from '$shared/shadcn/ui/scroll-area';
|
import { ScrollArea } from '$shared/shadcn/ui/scroll-area';
|
||||||
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
@@ -154,10 +155,20 @@ $effect(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const throttledVisibleChange = throttle((visibleItems: T[]) => {
|
||||||
|
onVisibleItemsChange?.(visibleItems);
|
||||||
|
}, 150); // 150ms debounce
|
||||||
|
|
||||||
|
const throttledNearBottom = throttle((lastVisibleIndex: number) => {
|
||||||
|
onNearBottom?.(lastVisibleIndex);
|
||||||
|
}, 200); // 200ms debounce
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const visibleItems = virtualizer.items.map(item => items[item.index]);
|
const visibleItems = virtualizer.items.map(item => items[item.index]);
|
||||||
onVisibleItemsChange?.(visibleItems);
|
throttledVisibleChange(visibleItems);
|
||||||
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
// Trigger onNearBottom when user scrolls near the end of loaded items (within 5 items)
|
// Trigger onNearBottom when user scrolls near the end of loaded items (within 5 items)
|
||||||
if (virtualizer.items.length > 0 && onNearBottom) {
|
if (virtualizer.items.length > 0 && onNearBottom) {
|
||||||
const lastVisibleItem = virtualizer.items[virtualizer.items.length - 1];
|
const lastVisibleItem = virtualizer.items[virtualizer.items.length - 1];
|
||||||
@@ -165,7 +176,7 @@ $effect(() => {
|
|||||||
const itemsRemaining = items.length - lastVisibleItem.index;
|
const itemsRemaining = items.length - lastVisibleItem.index;
|
||||||
|
|
||||||
if (itemsRemaining <= 5) {
|
if (itemsRemaining <= 5) {
|
||||||
onNearBottom(lastVisibleItem.index);
|
throttledNearBottom(lastVisibleItem.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -180,6 +191,7 @@ $effect(() => {
|
|||||||
data-index={item.index}
|
data-index={item.index}
|
||||||
class="absolute top-0 left-0 w-full will-change-transform"
|
class="absolute top-0 left-0 w-full will-change-transform"
|
||||||
style:transform="translateY({item.start}px)"
|
style:transform="translateY({item.start}px)"
|
||||||
|
data-lenis-prevent
|
||||||
>
|
>
|
||||||
{#if item.index < items.length}
|
{#if item.index < items.length}
|
||||||
{@render children({
|
{@render children({
|
||||||
@@ -212,7 +224,6 @@ $effect(() => {
|
|||||||
data-index={item.index}
|
data-index={item.index}
|
||||||
class="absolute top-0 left-0 w-full will-change-transform"
|
class="absolute top-0 left-0 w-full will-change-transform"
|
||||||
style:transform="translateY({item.start}px)"
|
style:transform="translateY({item.start}px)"
|
||||||
animate:flip={{ delay: 0, duration: 300, easing: quintOut }}
|
|
||||||
>
|
>
|
||||||
{#if item.index < items.length}
|
{#if item.index < items.length}
|
||||||
{@render children({
|
{@render children({
|
||||||
|
|||||||
Reference in New Issue
Block a user