@skbkontur/db-viewer-ui
Version:
Database Viewer with custom configuration
123 lines • 5.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScrollableContainer = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const renderEnvironment_1 = require("@skbkontur/react-ui/lib/renderEnvironment");
const debounce_1 = tslib_1.__importDefault(require("lodash/debounce"));
const react_1 = require("react");
const ScrollableContainer_styles_1 = require("./ScrollableContainer.styles");
const helpers_1 = require("./helpers");
const ScrollableContainer = ({ children, className, style, scrollStyle = {}, }) => {
const jsStyles = (0, renderEnvironment_1.useStyles)(ScrollableContainer_styles_1.getStyles);
const scrollLeft = (0, react_1.useRef)(0);
const scrollingSource = (0, react_1.useRef)("none");
const setScrollingSource = (0, debounce_1.default)(x => (scrollingSource.current = x), 50, { leading: false });
const root = (0, react_1.useRef)(null);
const container = (0, react_1.useRef)(null);
const scrollbarChild = (0, react_1.useRef)(null);
const scrollbar = (0, react_1.useRef)(null);
const handlePageResize = () => {
adjustPositions();
adjustShadows();
};
const resizeDebounced = (0, debounce_1.default)(handlePageResize, 10, { leading: false });
(0, react_1.useEffect)(() => {
init();
document.addEventListener("scroll", resizeDebounced);
window.addEventListener("scroll", resizeDebounced);
document.addEventListener("resize", handlePageResize);
window.addEventListener("resize", handlePageResize);
return () => {
document.removeEventListener("scroll", resizeDebounced);
window.removeEventListener("scroll", resizeDebounced);
document.removeEventListener("resize", handlePageResize);
window.removeEventListener("resize", handlePageResize);
};
}, []);
(0, react_1.useEffect)(() => {
adjustShadows();
});
return ((0, jsx_runtime_1.jsx)("div", { ref: root, "data-tid": "ScrollableContainer", className: `${jsStyles.root()} ${className}`, style: style, children: (0, jsx_runtime_1.jsxs)("div", { className: jsStyles.container(), style: style, ref: container, children: [children, (0, jsx_runtime_1.jsx)("div", { style: Object.assign({ overflowX: "auto", position: "fixed", width: "100%", bottom: 0 }, scrollStyle), ref: scrollbar, children: (0, jsx_runtime_1.jsx)("div", { ref: scrollbarChild, style: { height: "1px" } }) })] }) }));
function adjustPositions() {
const currentScrollLeft = scrollLeft.current;
const containerElement = container.current;
const scrollbarElement = scrollbar.current;
const scrollbarChildElement = scrollbarChild.current;
if (!containerElement || !scrollbarElement || !scrollbarChildElement) {
return;
}
showFixedScrollbar();
const isScrollbarVisible = (0, helpers_1.isScrollbarInViewport)(containerElement, scrollbarElement);
if (isScrollbarVisible) {
(0, helpers_1.updateScrollbarPosition)(containerElement, scrollbarElement, scrollbarChildElement, currentScrollLeft);
}
else {
hideFixedScrollbar();
}
}
function adjustShadows() {
const containerElement = container.current;
const scrollbarElement = scrollbar.current;
const rootElement = root.current;
if (!scrollbarElement || !rootElement || !containerElement) {
return;
}
const epsilon = 5;
if (containerElement.scrollLeft > epsilon) {
rootElement.classList.add(jsStyles.leftShadow());
}
else {
rootElement.classList.remove(jsStyles.leftShadow());
}
const containerWidth = containerElement.scrollWidth - containerElement.offsetWidth;
if (containerElement.scrollLeft < containerWidth - epsilon) {
rootElement.classList.add(jsStyles.rightShadow());
}
else {
rootElement.classList.remove(jsStyles.rightShadow());
}
}
function hideFixedScrollbar() {
if (scrollbar.current) {
scrollbar.current.style.display = "none";
}
}
function showFixedScrollbar() {
if (scrollbar.current) {
scrollbar.current.style.display = "block";
}
}
function init() {
const scrollbarElement = scrollbar.current;
const containerElement = container.current;
if (!scrollbarElement || !containerElement) {
return;
}
scrollbarElement.addEventListener("scroll", () => {
if (scrollingSource.current === "scrollbar" || scrollingSource.current === "none") {
scrollingSource.current = "scrollbar";
containerElement.scrollLeft = scrollbarElement.scrollLeft;
setScrollingSource("none");
}
else {
scrollLeft.current = scrollbarElement.scrollLeft;
}
adjustShadows();
});
containerElement.addEventListener("scroll", () => {
if (scrollingSource.current === "container" || scrollingSource.current === "none") {
scrollingSource.current = "container";
scrollbarElement.scrollLeft = containerElement.scrollLeft;
scrollLeft.current = containerElement.scrollLeft;
setScrollingSource("none");
}
else {
scrollLeft.current = containerElement.scrollLeft;
}
adjustShadows();
});
}
};
exports.ScrollableContainer = ScrollableContainer;
//# sourceMappingURL=ScrollableContainer.js.map