useScroll.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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 {
  14. offset = 50,
  15. duration = 150
  16. } = options
  17. const target = unref(targetRef)
  18. const container = unref(containerRef)
  19. const targetElement = target?.$el
  20. const containerElement = container?.$el
  21. if (!targetElement || !containerElement) {
  22. console.warn('useScroll: Target or container element not found')
  23. return false
  24. }
  25. try {
  26. let currentElement = targetElement
  27. let offsetTop = 0
  28. // Calculate total offset up to the scroll container
  29. while (currentElement && currentElement !== containerElement) {
  30. offsetTop += currentElement.offsetTop
  31. currentElement = currentElement.offsetParent
  32. }
  33. if (!currentElement) {
  34. console.warn('useScroll: Target is not a child of the container')
  35. return false
  36. }
  37. const targetPosition = Math.max(0, offsetTop - offset)
  38. container.setScrollPosition('vertical', targetPosition, duration)
  39. return true
  40. } catch (error) {
  41. console.error('useScroll: Error while scrolling', error)
  42. return false
  43. }
  44. }
  45. return {
  46. scrollToComponent
  47. }
  48. }