UNPKG

@awsui/components-react

Version:

AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A

87 lines (86 loc) 3.96 kB
import { ResizeObserver } from '@juggle/resize-observer'; import { useEffect, useState } from 'react'; import styles from './styles.css.js'; import { browserScrollbarSize, getOverflowParents, getOverflowParentDimensions } from '../internal/utils/scrollable-containers'; import { supportsStickyPosition } from '../internal/utils/dom'; export function useStickyScrollbar(scrollbarRef, scrollbarContentRef, tableRef, wrapperRef, footerHeight) { var _a; var stickyPositionIsSupported = supportsStickyPosition(); var _b = useState(false), isInContainer = _b[0], setIsInContainer = _b[1]; useEffect(function () { if (stickyPositionIsSupported) { window.addEventListener('scroll', updatePosition, true); return function () { window.removeEventListener('scroll', updatePosition, true); }; } }, [footerHeight, isInContainer]); useEffect(function () { if (stickyPositionIsSupported) { updatePosition(); var wrapperEl_1 = wrapperRef.current; if (wrapperEl_1) { var parents = getOverflowParents(wrapperEl_1); setIsInContainer(parents.length > 0); } } }, []); useEffect(function () { if (stickyPositionIsSupported && tableRef.current) { var observer_1 = new ResizeObserver(function (entries) { if (scrollbarContentRef.current) { scrollbarContentRef.current.style.width = entries[0].borderBoxSize[0].inlineSize + "px"; updatePosition(); } }); observer_1.observe(tableRef.current); return function () { observer_1.disconnect(); }; } }, []); if (!stickyPositionIsSupported) { return; } var scrollbarHeight = (_a = browserScrollbarSize()) === null || _a === void 0 ? void 0 : _a.height; var scrollbarEl = scrollbarRef.current; var scrollbarContentEl = scrollbarContentRef.current; var tableEl = tableRef.current; var wrapperEl = wrapperRef.current; if (scrollbarHeight && scrollbarEl && scrollbarContentEl) { scrollbarEl.style.height = scrollbarHeight + "px"; scrollbarContentEl.style.height = scrollbarHeight + "px"; } if (tableEl && wrapperEl && scrollbarContentEl && scrollbarEl) { var tableElRect = tableEl.getBoundingClientRect(); scrollbarContentEl.style.width = tableElRect.width + "px"; scrollbarEl.style.bottom = isInContainer ? '0px' : footerHeight + "px"; } var updatePosition = function () { var tableEl = tableRef.current; var wrapperEl = wrapperRef.current; var scrollbarEl = scrollbarRef.current; if (!tableEl || !scrollbarEl || !wrapperEl) { return; } var parent = getOverflowParentDimensions(wrapperEl)[0]; var parentBottom = parent.top + parent.height; var _a = tableEl.getBoundingClientRect(), tableBottom = _a.bottom, tableWidth = _a.width; var wrapperWidth = wrapperEl.getBoundingClientRect().width; var consideredFooterHeight = isInContainer ? 0 : footerHeight; var scrollBarCorrection = scrollbarHeight > 0 ? scrollbarHeight : -15 / 2; var tableBottomIsVisible = parentBottom - consideredFooterHeight >= tableBottom + scrollBarCorrection; var areaIsScrollable = tableWidth > wrapperWidth; if (tableBottomIsVisible || !areaIsScrollable) { scrollbarEl.classList.remove(styles['sticky-scrollbar-visible']); } else { if (!scrollbarEl.classList.contains(styles['sticky-scrollbar-visible'])) { requestAnimationFrame(function () { scrollbarEl.scrollLeft = wrapperEl.scrollLeft; }); } scrollbarEl.classList.add(styles['sticky-scrollbar-visible']); } }; }