UNPKG

@skbkontur/ui-kit

Version:

179 lines 7.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = tslib_1.__importDefault(require("react")); var getScrollWidth_1 = tslib_1.__importDefault(require("../../lib/dom/getScrollWidth")); var LayoutEvents_1 = tslib_1.__importDefault(require("../../lib/LayoutEvents")); var ScrollContainerView_1 = require("./ScrollContainerView"); var PADDING_RIGHT = 30; var MIN_SCROLL_SIZE = 20; var MAX_SCROLL_BAR_HOVER_DISTANCE = 12; var ScrollContainer = /** @class */ (function (_super) { tslib_1.__extends(ScrollContainer, _super); function ScrollContainer(props) { var _this = _super.call(this, props) || this; _this.refInner = function (element) { _this.inner = element; }; _this.handleNativeScroll = function (event) { _this.reflow(); if (_this.props.preventWindowScroll) { event.preventDefault(); return; } LayoutEvents_1.default.emit(); }; _this.reflow = function () { if (!_this.inner) { return; } var containerHeight = _this.inner.offsetHeight; var contentHeight = _this.inner.scrollHeight; var scrollTop = _this.inner.scrollTop; var scrollActive = containerHeight < contentHeight; if (!scrollActive && !_this.state.scrollActive) { return; } if (scrollActive) { var scrollSize_1 = containerHeight / contentHeight * containerHeight; if (scrollSize_1 < MIN_SCROLL_SIZE) { scrollSize_1 = MIN_SCROLL_SIZE; } var scrollPos_1 = scrollTop / (contentHeight - containerHeight) * (containerHeight - scrollSize_1); _this.setState(function (state) { if (state.scrollSize !== scrollSize_1 || state.scrollPos !== scrollPos_1) { return { scrollActive: true, scrollSize: scrollSize_1, scrollPos: scrollPos_1 }; } return null; }); } else { _this.setState({ scrollActive: false, scrollSize: 0, scrollPos: 0 }); } }; _this.handleScrollMouseDown = function (event) { if (!_this.inner || !document) { event.preventDefault(); return; } var initialY = event.clientY; var initialScrollTop = _this.inner.scrollTop; var mouseMove = function (documentEvent) { if (!_this.inner) { documentEvent.preventDefault(); return; } var ratio = (_this.inner.scrollHeight - _this.inner.offsetHeight) / (_this.inner.offsetHeight - _this.state.scrollSize); var deltaY = (documentEvent.clientY - initialY) * ratio; _this.inner.scrollTop = initialScrollTop + deltaY; documentEvent.preventDefault(); }; var mouseUp = function () { document.removeEventListener('mousemove', mouseMove); document.removeEventListener('mouseup', mouseUp); _this.setState({ scrolling: false }); }; document.addEventListener('mousemove', mouseMove); document.addEventListener('mouseup', mouseUp); _this.setState({ scrolling: true }); event.preventDefault(); }; _this.handleScrollWheel = function (event) { if (!_this.inner) { event.preventDefault(); return; } if (event.deltaY > 0 && _this.inner.scrollHeight <= _this.inner.scrollTop + _this.inner.offsetHeight) { return; } if (event.deltaY < 0 && _this.inner.scrollTop <= 0) { return; } _this.inner.scrollTop += event.deltaY; event.preventDefault(); }; _this.handleInnerScrollWheel = function (event) { if (_this.props.preventWindowScroll || !_this.inner) { return; } if (event.deltaY > 0 && _this.inner.scrollHeight <= _this.inner.scrollTop + _this.inner.offsetHeight) { event.preventDefault(); return; } if (event.deltaY < 0 && _this.inner.scrollTop <= 0) { event.preventDefault(); return; } }; _this.handleMouseMove = function (event) { var right = event.currentTarget.getBoundingClientRect().right - event.pageX; _this.setScrollBarHoverState(right <= MAX_SCROLL_BAR_HOVER_DISTANCE); }; _this.handleMouseLeave = function (event) { _this.setScrollBarHoverState(false); }; _this.state = { scrollActive: false, scrollSize: 0, scrollPos: 0, // Mouse is moving where big scrollbar can be located. hover: false, // True when scroll is following mouse (mouse down on scroll). scrolling: false }; _this.inner = null; return _this; } ScrollContainer.prototype.componentDidMount = function () { this.reflow(); }; ScrollContainer.prototype.componentDidUpdate = function () { this.reflow(); }; ScrollContainer.prototype.render = function () { var innerStyle = { marginRight: -(PADDING_RIGHT + getScrollWidth_1.default()), maxHeight: this.props.maxHeight, paddingRight: PADDING_RIGHT }; return (react_1.default.createElement(ScrollContainerView_1.ScrollContainerWrapper, { onMouseMove: this.handleMouseMove, onMouseLeave: this.handleMouseLeave }, this.state.scrollActive && (react_1.default.createElement(ScrollContainerView_1.ScrollContainerStyledScroll, { invert: this.props.invert, hover: this.state.hover || this.state.scrolling, style: { top: this.state.scrollPos, height: this.state.scrollSize }, onMouseDown: this.handleScrollMouseDown, onWheel: this.handleScrollWheel })), react_1.default.createElement(ScrollContainerView_1.ScrollContainerInner, { innerRef: this.refInner, style: innerStyle, onWheel: this.handleInnerScrollWheel, onScroll: this.handleNativeScroll }, this.props.children))); }; ScrollContainer.prototype.scrollTo = function (element) { if (!element || !this.inner) { return; } var maxScroll = element.offsetTop; if (this.inner.scrollTop > maxScroll) { this.inner.scrollTop = maxScroll; return; } var minScroll = element.offsetTop + element.scrollHeight - this.inner.offsetHeight; if (this.inner.scrollTop < minScroll) { this.inner.scrollTop = minScroll; } }; ScrollContainer.prototype.setScrollBarHoverState = function (hover) { if (this.state.hover !== hover) { this.setState(function (state) { return (state.hover !== hover ? { hover: hover } : null); }); } }; return ScrollContainer; }(react_1.default.Component)); exports.default = ScrollContainer; //# sourceMappingURL=ScrollContainer.js.map