UNPKG

@adaptabletools/adaptable-cjs

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

81 lines (80 loc) 2.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useContainerScrollObserver = void 0; const react_1 = require("react"); class SectionSelector { constructor(node) { this.scrollTop = 0; this.childrenHeights = []; this.select = (scrollTop) => { this.refreshFromDOM(); const relativeCurrentHeight = (scrollTop * this.boxHeight) / this.maxScrollTop; let heightSum = 0; for (let i = 0, len = this.childrenHeights.length; i < len; i++) { heightSum += this.childrenHeights[i]; if (heightSum > relativeCurrentHeight) { return i; } } return this.childrenHeights.length - 1; }; this.node = node; this.refreshFromDOM(); } refreshFromDOM() { this.boxHeight = this.node.scrollHeight; this.childrenHeights = Array.prototype.map.call(this.node.children, (child) => child.offsetHeight); this.maxScrollTop = this.boxHeight - this.node.offsetHeight; } getVisibleRange(scrollTop = this.scrollTop) { const top = scrollTop; const height = this.node.offsetHeight; const bottom = scrollTop + this.node.offsetHeight; return { top, bottom, height, }; } } const useContainerScrollObserver = (callback) => { const containerNodeRef = (0, react_1.useRef)(null); const sectionSelectorRef = (0, react_1.useRef)(null); const update = (0, react_1.useCallback)((scrollTop) => { callback(sectionSelectorRef.current.select(scrollTop)); }, []); const scrollRafRef = (0, react_1.useRef)(null); const onScroll = (0, react_1.useCallback)(() => { if (scrollRafRef.current) { cancelAnimationFrame(scrollRafRef.current); scrollRafRef.current = null; } requestAnimationFrame(() => { scrollRafRef.current = null; update(containerNodeRef.current.scrollTop); }); }, []); const setupScroll = (0, react_1.useCallback)((node) => { if (node) { containerNodeRef.current = node; node.addEventListener('scroll', onScroll, { passive: true }); sectionSelectorRef.current = new SectionSelector(node); } else { containerNodeRef.current?.removeEventListener('scroll', onScroll); sectionSelectorRef.current = null; } }, []); const ref = setupScroll; return { ref, scrollToIndex: (0, react_1.useCallback)((index) => { const container = containerNodeRef.current; const node = container.childNodes[index]; node.scrollIntoView({ behavior: 'smooth', }); }, []), }; }; exports.useContainerScrollObserver = useContainerScrollObserver;