import { unref } from "vue"; export const useScroll = () => { /** * Scrolls to a target element within a scroll container. * The function is agnostic to whether the container is a QScrollArea or a native DOM element. * * @param {Ref} targetRef - Ref to the target component or DOM element. * @param {Ref} containerRef - Ref to the container (QScrollArea or a scrollable DOM element like body). * @param {Object} options - Scroll options. * @param {number} options.offset - Offset from the top in pixels (default: 50). * @param {number} options.duration - Animation duration for QScrollArea (default: 150). Note: duration is not supported for native scrolling. * @returns {boolean} - Whether the scroll was successful. */ const scrollToComponent = (targetRef, containerRef, options = {}) => { const { offset = 150, duration = 150 } = options; const targetInstance = unref(targetRef); const containerInstance = unref(containerRef); const targetElement = targetInstance?.$el ?? targetInstance; const containerElement = containerInstance?.$el ?? containerInstance; if (!targetElement || !containerElement) { console.warn("useScroll: Target or container element not found"); return false; } try { let currentElement = targetElement; let offsetTop = 0; while (currentElement && currentElement !== containerElement) { offsetTop += currentElement.offsetTop; if ( containerElement.contains(currentElement.offsetParent) || containerElement === document.body ) { currentElement = currentElement.offsetParent; } else { currentElement = null; } } if ( containerElement !== document.body && !containerElement.contains(targetElement) ) { console.warn("useScroll: Target is not a child of the container"); return false; } const targetPosition = Math.max(0, offsetTop - offset); if (typeof containerInstance.setScrollPosition === "function") { containerInstance.setScrollPosition( "vertical", targetPosition, duration, ); } else { const scrollable = containerElement === document.body ? window : containerElement; scrollable.scrollTo({ top: targetPosition, behavior: "smooth", }); } return true; } catch (error) { console.error("useScroll: Error while scrolling", error); return false; } }; return { scrollToComponent, }; };