UNPKG

@up-group-ui/react-controls

Version:
238 lines 9.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = (0, tslib_1.__importDefault)(require("react")); var react_dom_1 = (0, tslib_1.__importDefault)(require("react-dom")); function throttle(callback, limit) { var wait = false; return function () { if (!wait) { wait = true; setTimeout(function () { callback(); wait = false; }, limit); } }; } function debounce(func, wait) { var timeout; return function () { var context = this, args = arguments; var later = function () { timeout = null; func.apply(context, args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } var UpVisibilitySensor = (function (_super) { (0, tslib_1.__extends)(UpVisibilitySensor, _super); function UpVisibilitySensor(props) { var _this = _super.call(this, props) || this; _this.getContainer = function () { return _this.props.containment || window; }; _this.isVisibleWithOffset = function (offset, rect, containmentRect) { var offsetDir = offset.direction; var offsetVal = offset.value; switch (offsetDir) { case 'top': return (containmentRect.top + offsetVal < rect.top && containmentRect.bottom > rect.bottom && containmentRect.left < rect.left && containmentRect.right > rect.right); case 'left': return (containmentRect.left + offsetVal < rect.left && containmentRect.bottom > rect.bottom && containmentRect.top < rect.top && containmentRect.right > rect.right); case 'bottom': return (containmentRect.bottom - offsetVal > rect.bottom && containmentRect.left < rect.left && containmentRect.right > rect.right && containmentRect.top < rect.top); case 'right': return (containmentRect.right - offsetVal > rect.right && containmentRect.left < rect.left && containmentRect.top < rect.top && containmentRect.bottom > rect.bottom); } }; _this.addEventListener = function (target, event, delay, throttle) { if (!_this.debounceCheck) { _this.debounceCheck = {}; } var timeout; var func; var later = function () { timeout = null; this.check(); }.bind(_this); if (throttle > -1) { func = function () { if (!timeout) { timeout = setTimeout(later, throttle || 0); } }; } else { func = function () { clearTimeout(timeout); timeout = setTimeout(later, delay || 0); }; } var info = { target: target, fn: func, getLastTimeout: function () { return timeout; }, }; target.addEventListener(event, info.fn); _this.debounceCheck[event] = info; }; _this.startWatching = function () { if (_this.debounceCheck || _this.interval) { return; } if (_this.props.intervalCheck) { _this.interval = setInterval(_this.check, _this.props.intervalDelay); } if (_this.props.scrollCheck) { _this.addEventListener(_this.getContainer(), 'scroll', _this.props.scrollDelay, _this.props.scrollThrottle); } if (_this.props.resizeCheck) { _this.addEventListener(window, 'resize', _this.props.resizeDelay, _this.props.resizeThrottle); } !_this.props.delayedCall && _this.check(); }; _this.stopWatching = function () { if (_this.debounceCheck) { for (var debounceEvent in _this.debounceCheck) { if (_this.debounceCheck.hasOwnProperty(debounceEvent)) { var debounceInfo = _this.debounceCheck[debounceEvent]; clearTimeout(debounceInfo.getLastTimeout()); debounceInfo.target.removeEventListener(debounceEvent, debounceInfo.fn); _this.debounceCheck[debounceEvent] = null; } } } _this.debounceCheck = null; if (_this.interval) { _this.interval = clearInterval(_this.interval); } }; _this.check = function () { var el = _this.node; var containmentRect; if (!el) { return _this.state; } var rect = el.getBoundingClientRect(); if (_this.props.containment) { var containmentDOMRect = _this.props.containment.getBoundingClientRect(); containmentRect = { top: containmentDOMRect.top, left: containmentDOMRect.left, bottom: containmentDOMRect.bottom, right: containmentDOMRect.right, }; } else { containmentRect = { top: 0, left: 0, bottom: window.innerHeight || document.documentElement.clientHeight, right: window.innerWidth || document.documentElement.clientWidth, }; } var offset = _this.props.offset || {}; var hasValidOffset = typeof offset === 'object'; if (hasValidOffset) { containmentRect.top += offset.top || 0; containmentRect.left += offset.left || 0; containmentRect.bottom -= offset.bottom || 0; containmentRect.right -= offset.right || 0; } var visibilityRect = { top: rect.top >= containmentRect.top, left: rect.left >= containmentRect.left, bottom: rect.bottom <= containmentRect.bottom, right: rect.right <= containmentRect.right, }; var isVisible = visibilityRect.top && visibilityRect.left && visibilityRect.bottom && visibilityRect.right; if (_this.props.partialVisibility) { var partialVisible = rect.top <= containmentRect.bottom && rect.bottom >= containmentRect.top && rect.left <= containmentRect.right && rect.right >= containmentRect.left; if (typeof _this.props.partialVisibility === 'string') { partialVisible = visibilityRect[_this.props.partialVisibility]; } isVisible = _this.props.minTopValue ? partialVisible && rect.top <= containmentRect.bottom - _this.props.minTopValue : partialVisible; } var state = _this.state; if (_this.state.isVisible !== isVisible || (isVisible && _this.props.forceCheck)) { state = { isVisible: isVisible, visibilityRect: visibilityRect, }; _this.setState(state); _this.props.onChange(isVisible, visibilityRect); } return state; }; _this.state = { isVisible: false, visibilityRect: {}, }; return _this; } UpVisibilitySensor.prototype.componentDidMount = function () { this.node = react_dom_1.default.findDOMNode(this); if (this.props.active) { this.startWatching(); } }; UpVisibilitySensor.prototype.componentWillUnmount = function () { this.stopWatching(); }; UpVisibilitySensor.prototype.componentWillReceiveProps = function (nextProps) { if (nextProps.active) { this.startWatching(); } else { this.stopWatching(); } if (nextProps.forceCheck) { this.check(); } }; UpVisibilitySensor.prototype.render = function () { return react_1.default.Children.only(this.props.children); }; UpVisibilitySensor.defaultProps = { active: true, partialVisibility: false, minTopValue: 0, scrollCheck: false, scrollDelay: 250, scrollThrottle: -1, resizeCheck: false, resizeDelay: 250, resizeThrottle: -1, intervalCheck: true, intervalDelay: 100, delayedCall: false, offset: {}, containment: null, children: react_1.default.createElement('span'), }; return UpVisibilitySensor; }(react_1.default.Component)); exports.default = UpVisibilitySensor; //# sourceMappingURL=UpVisibilitySensor.js.map