Files
ember-market-frontend/lib/hooks/use-chromebook-scroll.tsx
g 5de8f80007
All checks were successful
Build Frontend / build (push) Successful in 1m15s
Improve scroll handling and robustness for chat UI
Added 'overscroll-behavior: contain' to body and Chromebook scroll containers to prevent unwanted scroll chaining. Updated scrollToBottom utilities to handle null/undefined containers and errors gracefully. Fixed ChatDetail to use the correct scroll handler function.
2026-01-14 06:06:03 +00:00

106 lines
3.1 KiB
TypeScript

import { useEffect, useRef } from 'react';
/**
* Hook to enhance scrolling behavior for Chromebooks and touch devices
*/
export function useChromebookScroll() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
// Enhanced scrolling for Chromebooks
container.style.overscrollBehavior = 'contain';
const handleTouchStart = (e: TouchEvent) => {
// Prevent default touch behavior that might interfere with scrolling
if (e.touches.length === 1) {
// Single touch - allow normal scrolling
return;
}
// Multi-touch - prevent zoom gestures
if (e.touches.length > 1) {
e.preventDefault();
}
};
const handleTouchMove = (e: TouchEvent) => {
// Allow momentum scrolling on Chromebooks
if (e.touches.length === 1) {
// Single touch scrolling - allow default behavior
return;
}
// Multi-touch - prevent zoom
if (e.touches.length > 1) {
e.preventDefault();
}
};
const handleWheel = (e: WheelEvent) => {
// Enhanced wheel scrolling for Chromebook trackpads
const delta = e.deltaY;
const container = e.currentTarget as HTMLElement;
// Smooth scrolling for Chromebook trackpads
if (Math.abs(delta) > 0) {
container.scrollBy({
top: delta * 0.5, // Reduce scroll speed for better control
behavior: 'smooth'
});
}
};
// Add event listeners
container.addEventListener('touchstart', handleTouchStart, { passive: false });
container.addEventListener('touchmove', handleTouchMove, { passive: false });
container.addEventListener('wheel', handleWheel, { passive: true });
// Cleanup
return () => {
container.removeEventListener('touchstart', handleTouchStart);
container.removeEventListener('touchmove', handleTouchMove);
container.removeEventListener('wheel', handleWheel);
};
}, []);
return containerRef;
}
/**
* Hook for smooth scrolling to bottom (useful for chat interfaces)
*/
export function useSmoothScrollToBottom() {
const scrollToBottom = (container: HTMLElement | null | undefined) => {
if (!container || typeof container !== 'object') return;
try {
if ('scrollTo' in container && typeof container.scrollTo === 'function') {
container.scrollTo({
top: container.scrollHeight,
behavior: 'smooth'
});
} else {
container.scrollTop = container.scrollHeight;
}
} catch (err) {
console.error('Error in scrollToBottom:', err);
// Fallback to direct property assignment if scrollTo fails
try {
container.scrollTop = container.scrollHeight;
} catch (e) { }
}
};
const scrollToBottomInstant = (container: HTMLElement | null | undefined) => {
if (!container || typeof container !== 'object') return;
try {
container.scrollTop = container.scrollHeight;
} catch (e) { }
};
return { scrollToBottom, scrollToBottomInstant };
}