UNPKG

react-flexigrid

Version:

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

467 lines (401 loc) 13.7 kB
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties'; import _extends from 'babel-runtime/helpers/extends'; import _classCallCheck from 'babel-runtime/helpers/classCallCheck'; import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn'; import _inherits from 'babel-runtime/helpers/inherits'; /* eslint-disable react/require-default-props */ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import propTypes from './struct/propTypes'; import MouseMoveTracker from './dom/MouseMoveTracker'; import { shallowEqual, clamp, cancelAnimationFrame, requestAnimationFrame } from './utils'; import FlexiGridCell from './FlexiGridCell'; var FlexiGridColumnReorderHandler = function (_React$Component) { _inherits(FlexiGridColumnReorderHandler, _React$Component); function FlexiGridColumnReorderHandler(props) { _classCallCheck(this, FlexiGridColumnReorderHandler); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _this.onColumnReordering = function (deltaX) { if (deltaX !== 0) { var state = _this.cache || _this.state; var newLeft = state.delta + deltaX; var newFixedLeft = clamp(newLeft, _this.state.minLeft, _this.state.maxLeft); _this.cache = { movingLeft: deltaX < 0, left: newFixedLeft, delta: newLeft }; } }; _this.onColumnReordered = function () { var targetKey = _this.cache && _this.cache.targetKey; cancelAnimationFrame(_this.frameId); _this.cache = null; _this.frameId = null; _this.animating = false; _this.mouseMoveTracker.release(); if (_this.props.onColumnReordered) { _this.props.onColumnReordered(targetKey); } }; _this.updateState = function () { if (_this.animating) { _this.frameId = requestAnimationFrame(_this.updateState); } if (_this.cache) { var _this$props = _this.props, column = _this$props.column, targets = _this$props.targets, factor = _this$props.factor; var _this$cache = _this.cache, left = _this$cache.left, movingLeft = _this$cache.movingLeft; var right = left + column.width; var currentTarget = null; var tryLeftSide = function tryLeftSide() { targets.some(function (target) { if (target.key !== column.key && left > target.left && left < target.left + target.width * factor) { currentTarget = { targetKey: target.key, targetSortable: _this.sortable !== false, targetPosition: target.left, isLeftTarget: true, visible: target.leftSideVisible }; return true; } return false; }); }; var tryRightSide = function tryRightSide() { for (var i = targets.length - 1; i >= 0; i -= 1) { var target = targets[i]; if (target.key !== column.key && right < target.left + target.width && right > target.left + target.width * (1 - factor)) { currentTarget = { targetKey: target.key, targetSortable: _this.sortable !== false, targetPosition: target.left + target.width, isLeftTarget: false, visible: target.rightSideVisible }; break; } } }; if (movingLeft) { tryLeftSide(); } else { tryRightSide(); } if (!currentTarget) { if (movingLeft) { tryRightSide(); } else { tryLeftSide(); } } if (!currentTarget) { currentTarget = { targetKey: null, targetPosition: 0, isLeftTarget: true }; } if (!currentTarget.visible) { currentTarget.targetKey = null; } _this.cache = _extends({}, _this.cache, currentTarget); _this.setState(_this.cache); if (_this.props.onColumnReordering) { _this.props.onColumnReordering({ targetKey: currentTarget.targetKey, position: left, movingLeft: movingLeft }); } } }; _this.state = { minLeft: 0, maxLeft: 0, left: 0 }; _this.cache = null; _this.animating = false; return _this; } FlexiGridColumnReorderHandler.prototype.componentDidMount = function componentDidMount() { this.mouseMoveTracker = new MouseMoveTracker(document.body, this.onColumnReordering, this.onColumnReordered); }; FlexiGridColumnReorderHandler.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) { if (props.initialEvent && !this.mouseMoveTracker.isDragging()) { this.mouseMoveTracker.capture(props.initialEvent); var column = props.column, targets = props.targets, offsetLeft = props.offsetLeft; var minLeft = targets.length ? targets[0].left : offsetLeft; var maxLeft = targets.length ? targets[targets.length - 1].left + targets[targets.length - 1].width - column.width : offsetLeft; this.setState({ minLeft: minLeft, maxLeft: maxLeft, left: offsetLeft, delta: offsetLeft, targetKey: null, targetPosition: 0 }); this.cache = null; this.animating = true; this.frameId = requestAnimationFrame(this.updateState); } }; FlexiGridColumnReorderHandler.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); }; FlexiGridColumnReorderHandler.prototype.componentWillUnmount = function componentWillUnmount() { this.mouseMoveTracker.release(); this.mouseMoveTracker = null; }; FlexiGridColumnReorderHandler.prototype.renderDropTargets = function renderDropTargets() { var targets = this.props.targets; return (targets || []).map(function (_ref) { var key = _ref.key, style = _objectWithoutProperties(_ref, ['key']); return React.createElement('div', { key: key, style: style, className: 'drop-target' }); }); }; FlexiGridColumnReorderHandler.prototype.renderSourceMask = function renderSourceMask() { var _props = this.props, column = _props.column, columnHeight = _props.columnHeight, borderSize = _props.borderSize, offsetLeft = _props.offsetLeft, offsetTop = _props.offsetTop; return column ? React.createElement('div', { className: 'source-mask', style: { left: offsetLeft, top: offsetTop, height: columnHeight - borderSize, width: column.width - borderSize } }) : null; }; FlexiGridColumnReorderHandler.prototype.renderHeaderMergedCells = function renderHeaderMergedCells(height, left, column) { var _props2 = this.props, prefixCls = _props2.prefixCls, headerRowHeight = _props2.headerRowHeight; var children = column.children, width = column.width, title = column.title, key = column.key, align = column.align; var cellProps = { prefixCls: prefixCls, width: width, height: headerRowHeight, left: 0, render: title, align: align || 'center' }; return React.createElement( 'div', { key: key + '-merged-cells-wrap', className: prefixCls + '-header-merged-cells-wrap', style: { width: width, height: height, left: left } }, React.createElement(FlexiGridCell, cellProps), React.createElement( 'div', { key: key + '-merged-cells', className: prefixCls + '-header-merged-cells', style: { width: width, height: height - headerRowHeight, top: headerRowHeight } }, this.renderHeaderCells(children, height - headerRowHeight) ) ); }; FlexiGridColumnReorderHandler.prototype.renderHeaderCells = function renderHeaderCells(columns, height) { var _this2 = this; var prefixCls = this.props.prefixCls; var left = 0; return columns.map(function (column) { var children = column.children, width = column.width, title = column.title, key = column.key, align = column.align; var ret = void 0; if (children) { ret = _this2.renderHeaderMergedCells(height, left, column); } else { var cellProps = { key: key, prefixCls: prefixCls, width: width, height: height, left: left, align: align, render: title }; ret = React.createElement(FlexiGridCell, cellProps); } left += width; return ret; }); }; FlexiGridColumnReorderHandler.prototype.renderDragKnob = function renderDragKnob(column, height, offsetLeft, offsetTop) { var _props3 = this.props, prefixCls = _props3.prefixCls, knobSize = _props3.knobSize; var style = { top: offsetTop, left: offsetLeft, width: knobSize, height: height }; var className = classNames(prefixCls + '-reorder-knob', { active: column === this.props.column }); return React.createElement('div', { key: column.key, style: style, className: className }); }; FlexiGridColumnReorderHandler.prototype.renderDragKnobs = function renderDragKnobs(columns, height, offsetLeft, offsetTop) { var _this3 = this; var headerRowHeight = this.props.headerRowHeight; var knobs = []; var left = offsetLeft; columns.forEach(function (column) { if (column.children) { knobs.push.apply(knobs, [_this3.renderDragKnob(column, headerRowHeight, left, offsetTop)].concat(_this3.renderDragKnobs(column.children, height - headerRowHeight, left, offsetTop + headerRowHeight))); } else { knobs.push(_this3.renderDragKnob(column, height, left, offsetTop)); } left += column.width; }); return knobs; }; FlexiGridColumnReorderHandler.prototype.renderDragProxy = function renderDragProxy() { if (this.props.column) { var left = this.state.left; var _props4 = this.props, column = _props4.column, columnHeight = _props4.columnHeight, offsetTop = _props4.offsetTop; return React.createElement( 'div', { className: 'drag-proxy', style: { width: column.width, height: columnHeight, top: offsetTop, left: left } }, this.renderHeaderCells([column], columnHeight), this.renderDragKnobs([column], columnHeight, 0, 0) ); } return null; }; FlexiGridColumnReorderHandler.prototype.renderDropMarker = function renderDropMarker() { var _props5 = this.props, columnHeight = _props5.columnHeight, offsetTop = _props5.offsetTop, width = _props5.width; var _state = this.state, targetKey = _state.targetKey, targetPosition = _state.targetPosition, isLeftTarget = _state.isLeftTarget, targetSortable = _state.targetSortable; if (targetKey) { var className = classNames('target-marker', { 'is-left': isLeftTarget, 'is-right': !isLeftTarget, 'fix-position-sortable': !isLeftTarget && this.props.sortable && targetSortable }); var style = { height: columnHeight, top: offsetTop }; if (isLeftTarget) { style.left = targetPosition; } else { style.right = width - targetPosition; } return React.createElement('div', { className: className, style: style }); } return null; }; FlexiGridColumnReorderHandler.prototype.render = function render() { var _props6 = this.props, prefixCls = _props6.prefixCls, visible = _props6.visible, width = _props6.width, height = _props6.height; var className = classNames(prefixCls + '-reorder-handler', { visible: visible }); var wrapStyle = { width: width, height: height }; return React.createElement( 'div', { className: className, style: wrapStyle }, this.renderDropTargets(), this.renderSourceMask(), this.renderDropMarker(), this.renderDragProxy() ); }; return FlexiGridColumnReorderHandler; }(React.Component); FlexiGridColumnReorderHandler.propTypes = { prefixCls: PropTypes.string, column: propTypes.column, targets: propTypes.dropTarget, visible: PropTypes.bool, sortable: PropTypes.bool, factor: PropTypes.number, width: PropTypes.number, height: PropTypes.number, headerRowHeight: PropTypes.number, columnHeight: PropTypes.number, offsetLeft: PropTypes.number, offsetTop: PropTypes.number, borderSize: PropTypes.number, knobSize: PropTypes.number, initialEvent: propTypes.domEvent, onColumnReordering: PropTypes.func, onColumnReordered: PropTypes.func }; FlexiGridColumnReorderHandler.defaultProps = { visible: false, factor: 3 / 4, width: 0, height: 0, headerRowHeight: 0, columnHeight: 0, offsetLeft: 0, offsetTop: 0, borderSize: 0, knobSize: 0, targets: [], initialEvent: null }; export default FlexiGridColumnReorderHandler;