import { ref, watch, onUnmounted, type Ref } from 'vue'; export function useAutoScroll(elementRef: Ref) { const userIsScrollingUp = ref(false); const THRESHOLD = 50; const isAtBottom = () => { const el = elementRef.value; if (!el) return false; const distanceToBottom = el.scrollHeight - el.scrollTop - el.clientHeight; return distanceToBottom <= THRESHOLD; }; const scrollToBottom = (behavior: ScrollBehavior = 'auto') => { const el = elementRef.value; if (!el) return; el.scrollTo({ top: el.scrollHeight, behavior, }); }; const handleScroll = () => { const el = elementRef.value; if (!el) return; userIsScrollingUp.value = !isAtBottom(); }; let observer: MutationObserver | null = null; watch(elementRef, (newEl, oldEl) => { if (oldEl) { oldEl.removeEventListener('scroll', handleScroll); observer?.disconnect(); } if (newEl) { newEl.addEventListener('scroll', handleScroll, { passive: true }); observer = new MutationObserver(() => { if (!userIsScrollingUp.value) { scrollToBottom(); } }); observer.observe(newEl, { childList: true, subtree: true, characterData: true }); } }); onUnmounted(() => { elementRef.value?.removeEventListener('scroll', handleScroll); observer?.disconnect(); }); return { userIsScrollingUp, scrollToBottom, }; }