UNPKG

@coinmeca/ui

Version:

This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

59 lines 2.42 kB
'use client'; import { useState, useLayoutEffect } from 'react'; import { throttle } from '../lib/utils'; // Utility function to find all scrollable parents function getScrollableParents(element) { const scrollableParents = []; let parent = element?.parentElement; while (parent) { const overflowY = window.getComputedStyle(parent).overflowY; if (overflowY === 'scroll' || overflowY === 'auto') { scrollableParents.push(parent); } parent = parent.parentElement; } return scrollableParents; } export default function usePositionTracker(ref, throttleTime = 0.1) { const [position, setPosition] = useState(ref?.current?.getBoundingClientRect() || { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0, x: 0, y: 0, toJSON: () => undefined, }); useLayoutEffect(() => { const element = ref.current; if (!element) return; const scrollableParents = getScrollableParents(element); const update = throttle(() => setPosition(element.getBoundingClientRect()), throttleTime); scrollableParents.forEach((parent) => parent.addEventListener('scroll', update)); window.addEventListener('load', update); window.addEventListener('resize', update); window.addEventListener('scroll', update); window.addEventListener('focus', update); window.addEventListener('blur', update); window.addEventListener('beforeunload', update); window.addEventListener('orientationchange', update); document.addEventListener('visibilitychange', update); update(); return () => { scrollableParents.forEach((parent) => parent.removeEventListener('scroll', update)); window.removeEventListener('load', update); window.removeEventListener('resize', update); window.removeEventListener('scroll', update); window.removeEventListener('focus', update); window.removeEventListener('blur', update); window.removeEventListener('beforeunload', update); window.removeEventListener('orientationchange', update); document.removeEventListener('visibilitychange', update); }; }, [ref, throttleTime]); return position; } //# sourceMappingURL=usePositionTracker.js.map