import { unref } from "vue"; const resolveElement = (reference) => { const value = unref(reference); return value?.$el ?? value; }; export const useScroll = () => { /** * Scrolls to a specific component within a scroll container * @param {Ref} targetRef - Reference to the component to scroll to * @param {Ref} containerRef - Reference to the Quasar ScrollArea component * @param {Object} options - Scroll options * @param {number} options.offset - Offset from the top in pixels (default: 50) * @param {number} options.duration - Animation duration in milliseconds (default: 150) * @returns {boolean} - Whether the scroll was successful */ const scrollToComponent = (targetRef, containerRef, options = {}) => { const { offset = 50, duration = 150 } = options; const targetElement = resolveElement(targetRef); const container = unref(containerRef); const containerElement = resolveElement(containerRef); if ( !targetElement?.getBoundingClientRect || !containerElement?.getBoundingClientRect ) { console.warn("useScroll: Target or container element not found"); return false; } try { if (!containerElement.contains(targetElement)) { console.warn("useScroll: Target is not a child of the container"); return false; } const currentPosition = container?.getScrollPosition?.().top ?? containerElement.scrollTop ?? 0; const targetPosition = Math.max( 0, currentPosition + targetElement.getBoundingClientRect().top - containerElement.getBoundingClientRect().top - offset, ); if (typeof container?.setScrollPosition === "function") { container.setScrollPosition("vertical", targetPosition, duration); } else if (typeof containerElement.scrollTo === "function") { containerElement.scrollTo({ top: targetPosition, behavior: duration > 0 ? "smooth" : "auto", }); } else { containerElement.scrollTop = targetPosition; } return true; } catch (error) { console.error("useScroll: Error while scrolling", error); return false; } }; return { scrollToComponent, }; };