@skbkontur/ui-kit
Version:
179 lines • 7.69 kB
JavaScript
"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