UNPKG

fixed-data-table-one.com

Version:

A React table component designed to allow presenting thousands of rows of data.

189 lines (156 loc) 6.4 kB
/** * Copyright Schrodinger, LLC * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * This class listens to events on the document and then updates a react * component through callbacks. * Please note that captureMouseMove must be called in * order to initialize listeners on mousemove and mouseup. * releaseMouseMove must be called to remove them. It is important to * call releaseMouseMoves since mousemove is expensive to listen to. * * @providesModule DOMMouseMoveTracker * @typechecks */ 'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _EventListener = require('./EventListener'); var _EventListener2 = _interopRequireDefault(_EventListener); var _cancelAnimationFramePolyfill = require('./cancelAnimationFramePolyfill'); var _cancelAnimationFramePolyfill2 = _interopRequireDefault(_cancelAnimationFramePolyfill); var _requestAnimationFramePolyfill = require('./requestAnimationFramePolyfill'); var _requestAnimationFramePolyfill2 = _interopRequireDefault(_requestAnimationFramePolyfill); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var DOMMouseMoveTracker = function () { /** * onMove is the callback that will be called on every mouse move. * onMoveEnd is called on mouse up when movement has ended. */ function DOMMouseMoveTracker( /*function*/onMove, /*function*/onMoveEnd, /*DOMElement*/domNode) { _classCallCheck(this, DOMMouseMoveTracker); this._isDragging = false; this._animationFrameID = null; this._domNode = domNode; this._onMove = onMove; this._onMoveEnd = onMoveEnd; this._onMouseEnd = this._onMouseEnd.bind(this); this._onMouseMove = this._onMouseMove.bind(this); this._onMouseUp = this._onMouseUp.bind(this); this._didMouseMove = this._didMouseMove.bind(this); } /** * This is to set up the listeners for listening to mouse move * and mouse up signaling the movement has ended. Please note that these * listeners are added at the document.body level. It takes in an event * in order to grab inital state. */ _createClass(DOMMouseMoveTracker, [{ key: 'captureMouseMoves', value: function captureMouseMoves( /*object*/event) { if (!this._eventMoveToken && !this._eventUpToken && !this._eventLeaveToken && !this._eventOutToken) { this._eventMoveToken = _EventListener2.default.listen(this._domNode, 'mousemove', this._onMouseMove); this._eventUpToken = _EventListener2.default.listen(this._domNode, 'mouseup', this._onMouseUp); this._eventLeaveToken = _EventListener2.default.listen(this._domNode, 'mouseleave', this._onMouseEnd); this._eventOutToken = _EventListener2.default.listen(this._domNode, 'mouseout', this.onMouseEnd); } if (!this._isDragging) { this._deltaX = 0; this._deltaY = 0; this._isDragging = true; this._x = event.clientX; this._y = event.clientY; } event.preventDefault(); } /** * These releases all of the listeners on document.body. */ }, { key: 'releaseMouseMoves', value: function releaseMouseMoves() { if (this._eventMoveToken && this._eventUpToken && this._eventLeaveToken && this._eventOutToken) { this._eventMoveToken.remove(); this._eventMoveToken = null; this._eventUpToken.remove(); this._eventUpToken = null; this._eventLeaveToken.remove(); this._eventLeaveToken = null; this._eventOutToken.remove(); this._eventOutToken = null; } if (this._animationFrameID !== null) { (0, _cancelAnimationFramePolyfill2.default)(this._animationFrameID); this._animationFrameID = null; } if (this._isDragging) { this._isDragging = false; this._x = null; this._y = null; } } /** * Returns whether or not if the mouse movement is being tracked. */ }, { key: 'isDragging', value: function isDragging() /*boolean*/{ return this._isDragging; } /** * Calls onMove passed into constructor and updates internal state. */ }, { key: '_onMouseMove', value: function _onMouseMove( /*object*/event) { var x = event.clientX; var y = event.clientY; this._deltaX += x - this._x; this._deltaY += y - this._y; if (this._animationFrameID === null) { // The mouse may move faster then the animation frame does. // Use `requestAnimationFramePolyfill` to avoid over-updating. this._animationFrameID = (0, _requestAnimationFramePolyfill2.default)(this._didMouseMove); } this._x = x; this._y = y; event.preventDefault(); } }, { key: '_didMouseMove', value: function _didMouseMove() { this._animationFrameID = null; this._onMove(this._deltaX, this._deltaY); this._deltaX = 0; this._deltaY = 0; } /** * Calls onMoveEnd passed into constructor and updates internal state. */ }, { key: '_onMouseUp', value: function _onMouseUp() { if (this._animationFrameID) { this._didMouseMove(); } this._onMoveEnd(false); } /** * Calls onMoveEnd passed into the constructor, updates internal state, and cancels the move. */ }, { key: '_onMouseEnd', value: function _onMouseEnd() { this._onMoveEnd(true); } }]); return DOMMouseMoveTracker; }(); module.exports = DOMMouseMoveTracker;