feature/responsive #22

Merged
ilia merged 49 commits from feature/responsive into main 2026-02-09 06:49:25 +00:00
Showing only changes of commit 8580884896 - Show all commits

View File

@@ -202,6 +202,16 @@ export function createVirtualizer<T>(
});
}
// console.log('🎯 Virtual Items Calculation:', {
// scrollOffset,
// containerHeight,
// viewportEnd,
// startIdx,
// endIdx,
// withOverscan: { start, end },
// itemCount: end - start,
// });
return result;
});
// Svelte Actions (The DOM Interface)
@@ -225,32 +235,48 @@ export function createVirtualizer<T>(
return rect.top + window.scrollY;
};
let cachedOffsetTop = getElementOffset();
let cachedOffsetTop = 0;
let rafId: number | null = null;
containerHeight = window.innerHeight;
const handleScroll = () => {
// Use cached offset for scroll calculations
scrollOffset = Math.max(0, window.scrollY - cachedOffsetTop);
if (rafId !== null) return;
rafId = requestAnimationFrame(() => {
// Get current position of element relative to viewport
const rect = node.getBoundingClientRect();
// Calculate how much of the element has scrolled past the top of viewport
// When element.top is 0, element is at top of viewport
// When element.top is -100, element has scrolled up 100px past viewport top
const scrolledPastTop = Math.max(0, -rect.top);
scrollOffset = scrolledPastTop;
rafId = null;
});
// 🔍 DIAGNOSTIC
// console.log('📜 Scroll Event:', {
// windowScrollY: window.scrollY,
// elementRectTop: rect.top,
// scrolledPastTop,
// containerHeight
// });
};
const handleResize = () => {
const oldHeight = containerHeight;
containerHeight = window.innerHeight;
// Recalculate offset on resize (layout may have shifted)
const newOffsetTop = getElementOffset();
if (Math.abs(newOffsetTop - cachedOffsetTop) > 0.5) {
cachedOffsetTop = newOffsetTop;
handleScroll(); // Recalculate scroll position
}
cachedOffsetTop = getElementOffset();
handleScroll();
};
// Initial setup
requestAnimationFrame(() => {
cachedOffsetTop = getElementOffset();
handleScroll();
});
window.addEventListener('scroll', handleScroll, { passive: true });
window.addEventListener('resize', handleResize);
// Initial calculation
handleScroll();
return {
destroy() {
window.removeEventListener('scroll', handleScroll);
@@ -259,6 +285,10 @@ export function createVirtualizer<T>(
cancelAnimationFrame(frameId);
frameId = null;
}
if (rafId !== null) {
cancelAnimationFrame(rafId);
rafId = null;
}
elementRef = null;
},
};
@@ -366,6 +396,12 @@ export function createVirtualizer<T>(
}
return {
get scrollOffset() {
return scrollOffset;
},
get containerHeight() {
return containerHeight;
},
/** Computed array of visible items to render (reactive) */
get items() {
return items;