UNPKG

@skbkontur/db-viewer-ui

Version:

Database Viewer with custom configuration

123 lines 5.74 kB
"use strict"; 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