feature/ux-improvements #26

Merged
ilia merged 73 commits from feature/ux-improvements into main 2026-02-18 14:43:05 +00:00
Showing only changes of commit 21d8273967 - Show all commits

View File

@@ -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({