@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
JavaScript
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']);
}
};
}