useScroll.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { unref } from "vue";
  2. export const useScroll = () => {
  3. /**
  4. * Scrolls to a specific component within a scroll container
  5. * @param {Ref<Component>} targetRef - Reference to the component to scroll to
  6. * @param {Ref<Component>} containerRef - Reference to the Quasar ScrollArea component
  7. * @param {Object} options - Scroll options
  8. * @param {number} options.offset - Offset from the top in pixels (default: 50)
  9. * @param {number} options.duration - Animation duration in milliseconds (default: 150)
  10. * @returns {boolean} - Whether the scroll was successful
  11. */
  12. const scrollToComponent = (targetRef, containerRef, options = {}) => {
  13. const { offset = 50, duration = 150 } = options;
  14. const target = unref(targetRef);
  15. const container = unref(containerRef);
  16. const targetElement = target?.$el;
  17. const containerElement = container?.$el;
  18. if (!targetElement || !containerElement) {
  19. console.warn("useScroll: Target or container element not found");
  20. return false;
  21. }
  22. try {
  23. let currentElement = targetElement;
  24. let offsetTop = 0;
  25. // Calculate total offset up to the scroll container
  26. while (currentElement && currentElement !== containerElement) {
  27. offsetTop += currentElement.offsetTop;
  28. currentElement = currentElement.offsetParent;
  29. }
  30. if (!currentElement) {
  31. console.warn("useScroll: Target is not a child of the container");
  32. return false;
  33. }
  34. const targetPosition = Math.max(0, offsetTop - offset);
  35. container.setScrollPosition("vertical", targetPosition, duration);
  36. return true;
  37. } catch (error) {
  38. console.error("useScroll: Error while scrolling", error);
  39. return false;
  40. }
  41. };
  42. return {
  43. scrollToComponent,
  44. };
  45. };