Created
May 28, 2021 15:08
-
-
Save holmberd/22ca75648d50aa5ccb4ac2508a206325 to your computer and use it in GitHub Desktop.
React Hook: useVisibleElementsIndex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect } from 'react'; | |
import { debounce } from 'lodash'; | |
/** | |
* React Hook that returns an index for the right-most element that is horizontally | |
* visible within the boundaries of the container. | |
*/ | |
function useVisibleElementsIndex(containerRef, items) { | |
const [visibleElementsIndex, setVisibleElementsIndex] = useState(0); | |
const didUpdate = () => { | |
if (!containerRef || !containerRef.current) { | |
return; | |
} | |
const containerElement = containerRef.current; | |
const elements = Array.from(containerElement.children) | |
if (!elements.length) { | |
return setVisibleElementsIndex(0); | |
} | |
const visibleIndex = elements | |
.reverse() | |
.findIndex(element => element.getBoundingClientRect().right < containerElement.getBoundingClientRect().right); | |
return setVisibleElementsIndex(elements.length - visibleIndex); | |
} | |
useEffect(() => { | |
if (!containerRef || !containerRef.current) { | |
return; | |
} | |
didUpdate(); | |
const debouncedDidUpdate = debounce(didUpdate, 150); | |
let resizeObserver = new ResizeObserver(debouncedDidUpdate); | |
resizeObserver.observe(containerRef.current); | |
return () => { | |
if (resizeObserver) { | |
debouncedDidUpdate.cancel(); | |
resizeObserver.disconnect(); | |
resizeObserver = null; | |
} | |
} | |
}, [containerRef.current, items]) | |
return visibleElementsIndex; | |
} | |
export default useVisibleElementsIndex; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment