fix(layout): remove min-h-screen from main wrapper to prevent outer-page scroll on vines

This commit is contained in:
Chad Curtis
2026-03-01 13:41:49 -06:00
parent e5a7a7c121
commit 4bae1cdf31
2 changed files with 27 additions and 41 deletions
+1 -1
View File
@@ -80,7 +80,7 @@ function MainLayoutInner() {
<MobileDrawer open={drawerOpen} onOpenChange={setDrawerOpen} />
{/* Main layout - three column on desktop */}
<div className={cn("flex justify-center min-h-screen mx-auto max-w-[1200px]", wrapperClassName)}>
<div className={cn("flex justify-center mx-auto max-w-[1200px]", wrapperClassName)}>
{/* Desktop left sidebar - hidden below sidebar breakpoint */}
<div className="hidden sidebar:block">
<LeftSidebar />
+26 -40
View File
@@ -624,11 +624,9 @@ export function VinesFeedPage() {
[events],
);
// Reset active index when tab or vine list changes significantly
// Reset active index when tab changes
useEffect(() => {
setActiveIndex(0);
const container = containerRef.current;
if (container) container.scrollTop = 0;
}, [tab]);
const activeVine = vines[activeIndex];
@@ -656,20 +654,10 @@ export function VinesFeedPage() {
};
}, [commentsOpen]);
// Snap-scroll to a specific vine index
const scrollToIndex = useCallback((index: number) => {
const container = containerRef.current;
if (!container) return;
const target = container.children[index] as HTMLElement | undefined;
if (!target) return;
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}, []);
// Update active index based on intersection
// Sync activeIndex when CSS snap settles (touch swipe, mouse wheel, trackpad)
useEffect(() => {
const container = containerRef.current;
if (!container) return;
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
@@ -681,30 +669,30 @@ export function VinesFeedPage() {
},
{ root: container, threshold: 0.5 },
);
const kids = Array.from(container.children);
kids.forEach((child) => observer.observe(child));
Array.from(container.children).forEach((child) => observer.observe(child));
return () => observer.disconnect();
}, [vines]);
// Keyboard arrow navigation
useEffect(() => {
const handleKey = (e: KeyboardEvent) => {
const container = containerRef.current;
if (!container) return;
if (e.key === 'ArrowDown') {
e.preventDefault();
const next = Math.min(activeIndex + 1, vines.length - 1);
container.scrollTo({ top: next * container.clientHeight, behavior: 'smooth' });
setActiveIndex(next);
scrollToIndex(next);
} else if (e.key === 'ArrowUp') {
e.preventDefault();
const prev = Math.max(activeIndex - 1, 0);
container.scrollTo({ top: prev * container.clientHeight, behavior: 'smooth' });
setActiveIndex(prev);
scrollToIndex(prev);
}
};
window.addEventListener('keydown', handleKey);
return () => window.removeEventListener('keydown', handleKey);
}, [activeIndex, vines.length, scrollToIndex]);
}, [activeIndex, vines.length]);
// ── Loading state ────────────────────────────────────────────────────────
if (isLoading) {
@@ -765,26 +753,24 @@ export function VinesFeedPage() {
<VinesTabBar tab={tab} onTabChange={setTab} hasUser={!!user} />
{/* ── Scroll container ────────────────────────────────────────── */}
<div className="relative flex-1">
<div
ref={containerRef}
className={cn("vine-slide-height sidebar:h-[calc(100vh-3rem)] snap-y snap-mandatory", commentsOpen ? "overflow-hidden" : "overflow-y-scroll")}
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
>
{vines.map((event, i) => (
<div
key={event.id}
className="w-full vine-slide-height sidebar:h-[calc(100vh-3rem)] snap-start snap-always flex-shrink-0"
>
<VineCard
event={event}
isActive={i === activeIndex}
isNearActive={Math.abs(i - activeIndex) <= 1}
onCommentClick={handleCommentClick}
/>
</div>
))}
</div>
<div
ref={containerRef}
className="vine-slide-height sidebar:h-[calc(100vh-3rem)] snap-y snap-mandatory overflow-y-scroll"
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none', overscrollBehavior: 'none' }}
>
{vines.map((event, i) => (
<div
key={event.id}
className="w-full vine-slide-height sidebar:h-[calc(100vh-3rem)] snap-start snap-always flex-shrink-0"
>
<VineCard
event={event}
isActive={i === activeIndex}
isNearActive={Math.abs(i - activeIndex) <= 1}
onCommentClick={handleCommentClick}
/>
</div>
))}
</div>
{/* ── Mobile comments panel — full overlay, xl:hidden ─────────── */}