UNPKG

react-flexigrid

Version:

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

1,218 lines (1,028 loc) 44.5 kB
import _extends from 'babel-runtime/helpers/extends'; import _Number$MAX_SAFE_INTEGER from 'babel-runtime/core-js/number/max-safe-integer'; 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 invariant from 'invariant'; import classNames from 'classnames'; import propTypes from './struct/propTypes'; import WheelHandler from './dom/WheelHandler'; import TouchHandler from './dom/TouchHandler'; import Scrollbar from './Scrollbar'; import VerticalScrollHelper from './FlexiGridVerticalScrollHelper'; import HorizontalScrollHelper from './FlexiGridHorizontalScrollHelper'; import FlexiGridColumnBuffer from './FlexiGridColumnBuffer'; import FlexiGridHeader from './FlexiGridHeader'; import FlexiGridBody from './FlexiGridBody'; import FlexiGridShadowTop from './FlexiGridShadowTop'; import FlexiGridShadowLeft from './FlexiGridShadowLeft'; import FlexiGridShadowRight from './FlexiGridShadowRight'; import FlexiGridShadowBottom from './FlexiGridShadowBottom'; import FlexiGridSortKnobs from './FlexiGridSortKnobs'; import FlexiGridColumnResizeKnobs from './FlexiGridColumnResizeKnobs'; import FlexiGridColumnReorderKnobs from './FlexiGridColumnReorderKnobs'; import FlexiGridColumnResizeHandler from './FlexiGridColumnResizeHandler'; import FlexiGridColumnReorderHandler from './FlexiGridColumnReorderHandler'; import { debounce, clamp, deepEqual } from './utils'; import { getColumnsWidth, parseColumns, shrinkColumnsWidth } from './FlexiGridColumnHelper'; var FlexiGrid = function (_React$Component) { _inherits(FlexiGrid, _React$Component); function FlexiGrid() { var _temp, _this, _ret; _classCallCheck(this, FlexiGrid); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.onScroll = function (deltaX, deltaY) { if (!_this.scrolling) { _this.didScrollStart(); } if (Math.abs(deltaY) > Math.abs(deltaX) && _this.state.showScrollbarY) { _this.doVerticalScroll(deltaY, true); } else if (deltaX && _this.state.showScrollbarX) { _this.doHorizontalScroll(deltaX, true); } _this.didScrollStop(); }, _this.onHorizontalScroll = function (scrollX) { if (scrollX === _this.state.scrollX) { return; } if (!_this.scrolling) { _this.didScrollStart(); } _this.doHorizontalScroll(scrollX, false); _this.didScrollStop(); }, _this.onVerticalScroll = function (scrollY) { if (scrollY === _this.state.scrollY) { return; } if (!_this.scrolling) { _this.didScrollStart(); } _this.doVerticalScroll(scrollY, false); _this.didScrollStop(); }, _this.shouldHandleWheelX = function (delta) { if (!_this.state.showScrollbarX || delta === 0) { return false; } delta = Math.round(delta); // eslint-disable-line if (delta === 0) { return false; } return delta < 0 && _this.state.scrollX > 0 || delta >= 0 && _this.state.scrollX < _this.state.maxScrollX; }, _this.shouldHandleWheelY = function (delta) { if (!_this.state.showScrollbarY || delta === 0) { return false; } delta = Math.round(delta); // eslint-disable-line if (delta === 0) { return false; } return delta < 0 && _this.state.scrollY > 0 || delta >= 0 && _this.state.scrollY < _this.state.maxScrollY; }, _this.shouldHandleTouchX = function (delta) { return _this.props.touchScrollEnabled && _this.shouldHandleWheelX(delta); }, _this.shouldHandleTouchY = function (delta) { return _this.props.touchScrollEnabled && _this.shouldHandleWheelY(delta); }, _this.onColumnResize = function (_ref, e) { var column = _ref.column, knobSize = _ref.knobSize, left = _ref.left, top = _ref.top, rtl = _ref.rtl, adjustKnob = _ref.adjustKnob; // eslint-disable-line var _this$state = _this.state, headerHeight = _this$state.headerHeight, bodyHeight = _this$state.bodyHeight; _this.columnResizingData = { prefixCls: _this.props.prefixCls, rtl: rtl, offsetLeft: left, offsetTop: top, knobSize: knobSize, adjustKnob: adjustKnob, initialWidth: column.width, height: headerHeight + bodyHeight, minWidth: column.minWidth || 0, maxWidth: column.maxWidth || _Number$MAX_SAFE_INTEGER, columnKey: column.key, initialEvent: { clientX: e.clientX, clientY: e.clientY, preventDefault: function preventDefault() {} }, onColumnResizing: _this.onColumnResizing, onColumnResized: _this.onColumnResized }; if (_this.props.onColumnResize) { _this.props.onColumnResize(column.key, column.width); } _this.setNextState({ columnResizingKey: column.key }); }, _this.onColumnResizing = function (columnWidth, columnKey) { if (_this.props.onColumnResizing) { _this.props.onColumnResizing(columnKey, columnWidth); } }, _this.onColumnResized = function (columnWidth, columnKey) { if (_this.props.onColumnResized) { _this.props.onColumnResized(columnKey, columnWidth); } if (!_this.columnWidthMap) { _this.columnWidthMap = {}; } _this.columnWidthMap[columnKey] = columnWidth; _this.columnResizingData = null; var nextState = _this.calculateState(_this.props, _this.state); _this.setNextState(_extends({}, nextState, _this.getStateAfterHorizontalScroll(nextState.scrollX, false), { columnResizingKey: null })); }, _this.onColumnReorder = function (_ref2, e) { var column = _ref2.column; _this.columnReorderingData = { column: column, initialEvent: { clientX: e.clientX, clientY: e.clientY, preventDefault: function preventDefault() {} }, onColumnReordering: _this.onColumnReordering, onColumnReordered: _this.onColumnReordered }; if (_this.props.onColumnReorder) { _this.props.onColumnReorder(column.key); } _this.setNextState({ columnReorderingKey: column.key }); }, _this.onColumnReordering = function (_ref3) { var targetKey = _ref3.targetKey, movingLeft = _ref3.movingLeft, position = _ref3.position; var column = _this.columnReorderingData.column; if (!column.fixed) { var _this$props = _this.props, dragScrollSpeed = _this$props.dragScrollSpeed, dragScrollBuffer = _this$props.dragScrollBuffer; var _this$state2 = _this.state, bodyWidth = _this$state2.bodyWidth, scrollX = _this$state2.scrollX, maxScrollX = _this$state2.maxScrollX, columnData = _this$state2.columnData; var leftFixedColumns = columnData.leftFixedColumns, rightFixedColumns = columnData.rightFixedColumns; // auto scroll on moving var scrollTo = scrollX; if (movingLeft) { if (scrollX > 0 && position < getColumnsWidth(leftFixedColumns) + dragScrollBuffer) { scrollTo = Math.max(scrollX - dragScrollSpeed, 0); } } else if (scrollX < maxScrollX && position + column.width > bodyWidth - getColumnsWidth(rightFixedColumns) - dragScrollBuffer) { scrollTo = Math.min(scrollX + dragScrollSpeed, maxScrollX); } if (scrollTo !== scrollX) { _this.doHorizontalScroll(scrollTo, false); } } if (_this.props.onColumnReordering) { _this.props.onColumnReordering(column.key, targetKey); } }, _this.onColumnReordered = function (targetColumnKey) { if (!_this.columnOrderMap) { _this.columnOrderMap = {}; } var column = _this.columnReorderingData.column; var siblings = _this.getColumnSiblings(column); var sourceColumnKey = column.key; siblings.forEach(function (_ref4, index) { var key = _ref4.key; if (key === targetColumnKey) { _this.columnOrderMap[sourceColumnKey] = index; } else if (key === sourceColumnKey) { _this.columnOrderMap[targetColumnKey] = index; } }); if (_this.props.onColumnReordered) { _this.props.onColumnReordered(sourceColumnKey, targetColumnKey); } if (_this.props.onHorizontalScroll && _this.columnReorderingData.scrollX !== _this.state.scrollX) { _this.props.onHorizontalScroll(_this.state.scrollX); } _this.setNextState(_extends({}, _this.calculateState(_this.props, _this.state), { columnReorderingKey: null })); _this.columnReorderingData = null; }, _this.onColumnSort = function (column, type) { if (_this.props.onColumnSort) { _this.props.onColumnSort(column, type); } }, _temp), _possibleConstructorReturn(_this, _ret); } FlexiGrid.prototype.componentWillMount = function componentWillMount() { this.didScrollStop = debounce(this.didScrollStopSync, 200, this); this.wheelHandler = new WheelHandler(this.onScroll, this.shouldHandleWheelX, this.shouldHandleWheelY, this.props.stopScrollPropagation); this.touchHandler = new TouchHandler(this.onScroll, this.shouldHandleTouchX, this.shouldHandleTouchY, this.props.stopScrollPropagation); this.setNextState(this.calculateState(this.props)); }; FlexiGrid.prototype.componentDidMount = function componentDidMount() { this.reportContentHeight(); }; FlexiGrid.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { if (this.props.ownerHeight !== nextProps.ownerHeight || this.props.scrollTop !== nextProps.scrollTop || this.props.scrollLeft !== nextProps.scrollLeft) { this.didScrollStart(); } this.didScrollStop.reset(); this.didScrollStopSync(); this.setNextState(this.calculateState(nextProps, this.state)); }; FlexiGrid.prototype.componentDidUpdate = function componentDidUpdate() { this.reportContentHeight(); }; FlexiGrid.prototype.componentWillUnmount = function componentWillUnmount() { this.wheelHandler = null; this.touchHandler = null; // cancel any pending debounced scroll handling and handle immediately this.didScrollStop.reset(); this.didScrollStopSync(); }; FlexiGrid.prototype.getStateAfterHorizontalScroll = function getStateAfterHorizontalScroll(scrollX, relative) { var scrollState = relative ? this.horizontalScrollHelper.scrollBy(Math.round(scrollX)) : this.horizontalScrollHelper.scrollTo(Math.round(scrollX)); var onHorizontalScroll = this.props.onHorizontalScroll; if (onHorizontalScroll) { onHorizontalScroll(scrollState.position); } var columnData = this.state.columnData; var contentWidth = columnData.leftFixedColumnsWidth + columnData.rightFixedColumnsWidth + scrollState.contentWidth; var maxScrollX = Math.max(0, contentWidth - this.state.bodyWidth); var scrollableColumnsToRender = this.columnBuffer.getColumns(scrollState.index, scrollState.offset); return { firstColumnIndex: scrollState.index, firstColumnOffset: scrollState.offset, scrollX: scrollState.position, maxScrollX: maxScrollX, scrollableColumnsToRender: scrollableColumnsToRender }; }; FlexiGrid.prototype.doHorizontalScroll = function doHorizontalScroll(scrollX, relative) { // eslint-disable-line this.setNextState(this.getStateAfterHorizontalScroll(scrollX, relative)); }; FlexiGrid.prototype.doVerticalScroll = function doVerticalScroll(scrollY, relative) { // eslint-disable-line var scrollState = relative ? this.verticalScrollHelper.scrollBy(Math.round(scrollY)) : this.verticalScrollHelper.scrollTo(Math.round(scrollY)); var onVerticalScroll = this.props.onVerticalScroll; if (onVerticalScroll) { onVerticalScroll(scrollState.position); } var maxScrollY = Math.max(0, scrollState.contentHeight - this.state.bodyHeight); this.setNextState({ firstRowIndex: scrollState.index, firstRowOffset: scrollState.offset, contentHeight: scrollState.contentHeight, scrollY: scrollState.position, maxScrollY: maxScrollY }); }; FlexiGrid.prototype.didScrollStart = function didScrollStart() { // eslint-disable-line if (this.scrolling) { return; } this.scrolling = true; if (this.props.onScrollStart) { this.props.onScrollStart(this.state.scrollX, this.state.scrollY, this.state.firstRowIndex); } }; FlexiGrid.prototype.didScrollStopSync = function didScrollStopSync() { if (!this.scrolling) { return; } this.scrolling = false; this.setNextState({ redraw: true }); if (this.props.onScrollEnd) { this.props.onScrollEnd(this.state.scrollX, this.state.scrollY, this.state.firstRowIndex); } }; FlexiGrid.prototype.reportContentHeight = function reportContentHeight() { var requiredHeight = this.state.contentHeight + this.state.reservedHeight; var contentHeight = void 0; if (this.state.useMaxHeight && this.props.maxHeight > requiredHeight) { contentHeight = requiredHeight; } else if (this.state.height > requiredHeight && this.props.ownerHeight) { contentHeight = Math.max(requiredHeight, this.props.ownerHeight); } else { contentHeight = this.state.height + this.state.maxScrollY; } if (contentHeight !== this.contentHeight && this.props.onContentHeightChange) { this.props.onContentHeightChange(contentHeight); } this.contentHeight = contentHeight; }; FlexiGrid.prototype.isColumnResizing = function isColumnResizing() { return this.state.columnResizingKey != null; }; FlexiGrid.prototype.isColumnReordering = function isColumnReordering() { return this.state.columnReorderingKey != null; }; FlexiGrid.prototype.setNextState = function setNextState(nextState) { var _this2 = this; var oldColumnData = this.state && this.state.columnData; var scrollableColumnsToRender = nextState.scrollableColumnsToRender, columnData = nextState.columnData; var leftFixedColumnsUpdated = false; var scrollableColumnsUpdated = false; var rightFixedColumnsUpdated = false; var scrollableColumnsToRenderUpdated = false; if (columnData && oldColumnData) { leftFixedColumnsUpdated = !(columnData.leftFixedColumns === oldColumnData.leftFixedColumns || deepEqual(columnData.leftFixedColumns, oldColumnData.leftFixedColumns)); scrollableColumnsUpdated = !(columnData.scrollableColumns === oldColumnData.scrollableColumns || deepEqual(columnData.scrollableColumns, oldColumnData.scrollableColumns)); rightFixedColumnsUpdated = !(columnData.rightFixedColumns === oldColumnData.rightFixedColumns || deepEqual(columnData.rightFixedColumns, oldColumnData.rightFixedColumns)); } else if (columnData && !oldColumnData) { leftFixedColumnsUpdated = true; scrollableColumnsUpdated = true; rightFixedColumnsUpdated = true; } if (this.state) { scrollableColumnsToRenderUpdated = !(scrollableColumnsToRender === this.state.scrollableColumnsToRender || deepEqual(scrollableColumnsToRender, this.state.scrollableColumnsToRender)); } else { scrollableColumnsToRenderUpdated = true; } var state = _extends({}, nextState, { leftFixedColumnsUpdated: leftFixedColumnsUpdated, scrollableColumnsUpdated: scrollableColumnsUpdated, rightFixedColumnsUpdated: rightFixedColumnsUpdated, scrollableColumnsToRenderUpdated: scrollableColumnsToRenderUpdated }); if (scrollableColumnsToRender) { var scrollableLeafColumns = columnData ? columnData.scrollableLeafColumns : oldColumnData.scrollableLeafColumns; var leafColumnsToRender = scrollableColumnsToRender.map(function (index) { return _extends({}, scrollableLeafColumns[index], { offsetLeft: _this2.horizontalScrollHelper.getColumnPosition(index) }); }); var parents = leafColumnsToRender.map(function (item) { var result = item; var parent = item.parent; while (parent) { result = parent; parent = result.parent; } return result; }); var columnsToRender = []; parents.forEach(function (item) { if (!columnsToRender.includes(item)) { columnsToRender.push(item); } }); state.scrollableColumnsToRender = columnsToRender; state.scrollableLeafColumnsToRender = leafColumnsToRender; } this.setState(state); }; FlexiGrid.prototype.calculateState = function calculateState() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var oldState = arguments[1]; invariant(props.height !== undefined || props.maxHeight !== undefined, 'Either height or maxHeight should be specified'); var borderSize = props.bordered ? props.borderSize : 0; var reservedBorderSize = props.bordered ? 2 * borderSize : 0; // the width of viewport includes scrollbars var viewportWidth = props.width - reservedBorderSize; var columnConfig = { widthMap: this.columnWidthMap || {}, orderMap: this.columnOrderMap || {}, viewportWidth: viewportWidth }; if (oldState) { columnConfig.resizingKey = oldState.columnResizingKey; columnConfig.reorderingKey = oldState.columnReorderingKey; } var columnData = parseColumns(props.columns, columnConfig); var rowCount = props.data.length; var rowHeight = props.rowHeight; var headerRowHeight = props.headerRowHeight; var headerHeight = columnData.depth * headerRowHeight; var useMaxHeight = props.height === undefined; var realUseHeight = useMaxHeight ? props.maxHeight : props.height; // the height of viewport includes scrollbars var viewportHeight = realUseHeight - (headerHeight || 0) - (props.footerHeight || 0) - reservedBorderSize; var firstRowIndex = oldState && oldState.firstRowIndex || 0; var firstRowOffset = oldState && oldState.firstRowOffset || 0; var firstColumnIndex = oldState && oldState.firstColumnIndex || 0; var firstColumnOffset = oldState && oldState.firstColumnOffset || 0; var scrollX = oldState ? oldState.scrollX : 0; var scrollY = oldState ? oldState.scrollY : 0; if (!this.verticalScrollHelper) { this.verticalScrollHelper = new VerticalScrollHelper(rowCount, props.rowHeight, viewportHeight, props.getRowHeight, props.subRowHeight, props.getSubRowHeight); } var oldViewportHeight = this.verticalScrollHelper.viewportHeight; if (oldState && (rowCount !== oldState.rowCount || props.rowHeight !== oldState.rowHeight || props.height !== oldState.height)) { this.verticalScrollHelper = new VerticalScrollHelper(rowCount, props.rowHeight, viewportHeight, props.getRowHeight, props.subRowHeight, props.getSubRowHeight); var scrollState = this.verticalScrollHelper.scrollToRow(firstRowIndex, firstRowOffset); scrollY = scrollState.position; firstRowIndex = scrollState.index; firstRowOffset = scrollState.offset; } else if (oldState) { if (props.getRowHeight !== oldState.getRowHeight) { this.verticalScrollHelper.setRowHeightGetter(props.getRowHeight); } if (props.getSubRowHeight !== oldState.getSubRowHeight) { this.verticalScrollHelper.setSubRowHeightGetter(props.getSubRowHeight); } } // scrollToRow var oldScrollToRow = oldState ? oldState.scrollToRow : undefined; if (props.scrollToRow !== undefined && (props.scrollToRow !== oldScrollToRow || viewportHeight !== oldViewportHeight)) { var _scrollState = this.verticalScrollHelper.scrollRowIntoView(props.scrollToRow); scrollY = _scrollState.position; firstRowIndex = _scrollState.index; firstRowOffset = _scrollState.offset; } // scrollTop var oldScrollTop = oldState ? oldState.scrollTop : undefined; if (props.scrollTop !== undefined && props.scrollTop !== oldScrollTop) { var _scrollState2 = this.verticalScrollHelper.scrollTo(props.scrollTop); scrollY = _scrollState2.position; firstRowIndex = _scrollState2.index; firstRowOffset = _scrollState2.offset; } // size for content var contentWidth = getColumnsWidth(columnData.columns); var contentHeight = this.verticalScrollHelper.getContentHeight(); var isJustFullfill = contentWidth === viewportWidth; var showScrollbarX = contentWidth > viewportWidth + borderSize; var showScrollbarY = contentHeight > viewportHeight; var reservedHeight = props.footerHeight + headerHeight + reservedBorderSize + (showScrollbarX ? Scrollbar.SIZE : 0); var requiredHeight = contentHeight + reservedHeight; var reservedColumnWidth = columnData.leftFixedColumnsWidth + columnData.rightFixedColumnsWidth; var height = Math.round(realUseHeight); if (useMaxHeight && !showScrollbarY) { height = requiredHeight; } if (showScrollbarY && isJustFullfill) { shrinkColumnsWidth(columnData, Scrollbar.SIZE); } // body's size excludes scrollbars var bodyWidth = viewportWidth - (showScrollbarY ? Scrollbar.SIZE : 0); var bodyHeight = height - reservedHeight; var maxScrollX = Math.max(0, contentWidth - bodyWidth); var maxScrollY = Math.max(0, contentHeight - bodyHeight); scrollX = Math.min(scrollX, maxScrollX); scrollY = Math.min(scrollY, maxScrollY); this.verticalScrollHelper.setViewportHeight(bodyHeight); var getScrollableColumnWidth = function getScrollableColumnWidth(index) { return columnData.scrollableLeafColumns[index].width; }; var scrollableViewportWidth = bodyWidth - reservedColumnWidth; if (!this.horizontalScrollHelper) { this.horizontalScrollHelper = new HorizontalScrollHelper(columnData.scrollableLeafColumns.length, scrollableViewportWidth, getScrollableColumnWidth); } else { this.horizontalScrollHelper.setViewportWidth(scrollableViewportWidth); this.horizontalScrollHelper.setColumnWidthGetter(getScrollableColumnWidth); } // scrollToColumn var oldScrollToColumn = oldState ? oldState.scrollToColumn : undefined; var scrollToColumn = props.scrollToColumn; if (scrollToColumn !== undefined && scrollToColumn !== oldScrollToColumn) { var leftFixedCount = columnData.leftFixedLeafColumns.length; var scrollableCount = columnData.scrollableLeafColumns.length; var columnIndex = clamp(scrollToColumn - leftFixedCount, 0, scrollableCount - 1); var _scrollState3 = this.horizontalScrollHelper.scrollToColumn(columnIndex); scrollX = _scrollState3.position; firstColumnIndex = _scrollState3.index; firstColumnOffset = _scrollState3.offset; } // scrollLeft var oldScrollLeft = oldState ? oldState.scrollLeft : undefined; if (props.scrollLeft !== undefined && props.scrollLeft !== oldScrollLeft) { var _scrollState4 = this.horizontalScrollHelper.scrollTo(props.scrollLeft); scrollX = _scrollState4.position; firstColumnIndex = _scrollState4.index; firstColumnOffset = _scrollState4.offset; } if (!this.columnBuffer || !oldState || !deepEqual(columnData.scrollableColumns, oldState.scrollableColumns)) { this.columnBuffer = new FlexiGridColumnBuffer(columnData.scrollableLeafColumns.length, scrollableViewportWidth, getScrollableColumnWidth, props.bufferColumnCount); } var scrollableColumnsToRender = this.columnBuffer.getColumns(firstColumnIndex, firstColumnOffset); // The order of elements in this object metters and bringing bodyHeight, // height or useGroupHeader to the top can break various features var newState = { rowCount: rowCount, columnData: columnData, scrollableColumnsToRender: scrollableColumnsToRender, columnResizingKey: oldState && oldState.columnResizingKey || null, columnReorderingKey: oldState && oldState.columnReorderingKey || null, width: props.width, height: height, rowHeight: rowHeight, useMaxHeight: useMaxHeight, headerHeight: headerHeight, reservedHeight: reservedHeight, viewportWidth: viewportWidth, viewportHeight: viewportHeight, bodyWidth: bodyWidth, bodyHeight: bodyHeight, contentWidth: contentWidth, contentHeight: contentHeight, firstRowIndex: firstRowIndex, firstRowOffset: firstRowOffset, firstColumnIndex: firstColumnIndex, firstColumnOffset: firstColumnOffset, scrollX: scrollX, scrollY: scrollY, maxScrollX: maxScrollX, maxScrollY: maxScrollY, showScrollbarX: showScrollbarX, showScrollbarY: showScrollbarY, isJustFullfill: isJustFullfill, // store these props for next compare scrollTop: props.scrollTop, scrollLeft: props.scrollLeft, scrollToRow: props.scrollToRow, scrollToColumn: props.scrollToColumn, getRowHeight: props.getRowHeight, getSubRowHeight: props.getSubRowHeight }; return newState; }; FlexiGrid.prototype.getColumnReorderingData = function getColumnReorderingData() { var raw = this.columnReorderingData; if (raw) { var column = raw.column; var _props = this.props, prefixCls = _props.prefixCls, headerRowHeight = _props.headerRowHeight, borderSize = _props.borderSize, reorderFactor = _props.reorderFactor, reorderKnobSize = _props.reorderKnobSize; var _state = this.state, bodyWidth = _state.bodyWidth, headerHeight = _state.headerHeight, bodyHeight = _state.bodyHeight, columnData = _state.columnData, scrollX = _state.scrollX; var leftFixedColumnsWidth = columnData.leftFixedColumnsWidth, rightFixedColumnsWidth = columnData.rightFixedColumnsWidth; var maxRight = bodyWidth - rightFixedColumnsWidth; var offsetTop = (column.depth - 1) * headerRowHeight; var offsetLeft = column.left; if (this.state.showScrollbarX) { if (!column.fixed) { offsetLeft -= scrollX; } else if (column.fixed === 'right') { offsetLeft += bodyWidth - rightFixedColumnsWidth; } } var siblings = this.getColumnSiblings(column); var targets = []; var siblingLeft = offsetLeft; siblings.some(function (item) { if (item === column) { return true; } siblingLeft -= item.width; return false; }); siblings.forEach(function (item) { targets.push({ left: siblingLeft, top: offsetTop, height: headerHeight - offsetTop, width: item.width, key: item.key, leftSideVisible: siblingLeft >= leftFixedColumnsWidth, rightSideVisible: siblingLeft + item.width <= maxRight }); siblingLeft += item.width; }); return _extends({}, raw, { prefixCls: prefixCls, width: bodyWidth, height: headerHeight + bodyHeight, offsetLeft: offsetLeft, offsetTop: offsetTop, targets: targets, headerRowHeight: headerRowHeight, columnHeight: headerHeight - offsetTop, borderSize: borderSize, scrollX: scrollX, factor: reorderFactor, knobSize: reorderKnobSize }); } return raw; }; FlexiGrid.prototype.getColumnSiblings = function getColumnSiblings(column) { var siblings = column.depth > 1 ? column.parent.children : null; if (!siblings) { var columnData = this.state.columnData; if (column.fixed === 'left') { siblings = columnData.leftFixedColumns; } else if (column.fixed === 'right') { siblings = columnData.rightFixedColumns; } else { siblings = columnData.scrollableColumns; } } return siblings; }; FlexiGrid.prototype.getHeaderAndBodyCommonProps = function getHeaderAndBodyCommonProps() { var _props2 = this.props, prefixCls = _props2.prefixCls, rowHeight = _props2.rowHeight, bordered = _props2.bordered; var _state2 = this.state, columnData = _state2.columnData, scrollX = _state2.scrollX, showScrollbarX = _state2.showScrollbarX, showScrollbarY = _state2.showScrollbarY, isJustFullfill = _state2.isJustFullfill, scrollableColumnsToRender = _state2.scrollableColumnsToRender, scrollableLeafColumnsToRender = _state2.scrollableLeafColumnsToRender, leftFixedColumnsUpdated = _state2.leftFixedColumnsUpdated, scrollableColumnsUpdated = _state2.scrollableColumnsUpdated, rightFixedColumnsUpdated = _state2.rightFixedColumnsUpdated, scrollableColumnsToRenderUpdated = _state2.scrollableColumnsToRenderUpdated; var leftFixedColumns = columnData.leftFixedColumns, scrollableColumns = columnData.scrollableColumns, rightFixedColumns = columnData.rightFixedColumns, leftFixedLeafColumns = columnData.leftFixedLeafColumns, scrollableLeafColumns = columnData.scrollableLeafColumns, rightFixedLeafColumns = columnData.rightFixedLeafColumns, leftFixedColumnsWidth = columnData.leftFixedColumnsWidth, scrollableColumnsWidth = columnData.scrollableColumnsWidth, rightFixedColumnsWidth = columnData.rightFixedColumnsWidth; return { prefixCls: prefixCls, rowHeight: rowHeight, bordered: bordered, scrollX: scrollX, showScrollbarX: showScrollbarX, showScrollbarY: showScrollbarY, isJustFullfill: isJustFullfill, leftFixedColumns: leftFixedColumns, scrollableColumns: scrollableColumns, rightFixedColumns: rightFixedColumns, leftFixedLeafColumns: leftFixedLeafColumns, scrollableLeafColumns: scrollableLeafColumns, rightFixedLeafColumns: rightFixedLeafColumns, scrollableColumnsToRender: scrollableColumnsToRender, scrollableLeafColumnsToRender: scrollableLeafColumnsToRender, leftFixedColumnsWidth: leftFixedColumnsWidth, scrollableColumnsWidth: scrollableColumnsWidth, rightFixedColumnsWidth: rightFixedColumnsWidth, leftFixedColumnsUpdated: leftFixedColumnsUpdated, scrollableColumnsUpdated: scrollableColumnsUpdated, rightFixedColumnsUpdated: rightFixedColumnsUpdated, scrollableColumnsToRenderUpdated: scrollableColumnsToRenderUpdated }; }; FlexiGrid.prototype.renderHeader = function renderHeader() { var _state3 = this.state, viewportWidth = _state3.viewportWidth, headerHeight = _state3.headerHeight; var props = _extends({}, this.getHeaderAndBodyCommonProps(), { rowHeight: this.props.headerRowHeight, scrollbarSize: Scrollbar.SIZE, width: viewportWidth, height: headerHeight }); return React.createElement(FlexiGridHeader, props); }; FlexiGrid.prototype.renderBody = function renderBody() { var props = _extends({}, this.getHeaderAndBodyCommonProps(), { width: this.state.bodyWidth, height: this.state.bodyHeight, firstRowIndex: this.state.firstRowIndex, firstRowOffset: this.state.firstRowOffset, data: this.props.data, rowKey: this.props.rowKey, scrolling: this.scrolling, subRow: this.props.subRow, bufferRowCount: this.props.bufferRowCount, getRowPosition: this.verticalScrollHelper.getRowPosition, getRowHeight: this.props.getRowHeight, getSubRowHeight: this.props.getSubRowHeight, getRowClassName: this.props.getRowClassName, onRowClick: this.props.onRowClick, onRowDoubleClick: this.props.onRowDoubleClick, onRowMouseDown: this.props.onRowMouseDown, onRowMouseUp: this.props.onRowMouseUp, onRowMouseEnter: this.props.onRowMouseEnter, onRowMouseLeave: this.props.onRowMouseLeave, onRowTouchStart: this.props.onRowTouchStart, onRowTouchEnd: this.props.onRowTouchEnd, onRowTouchMove: this.props.onRowTouchMove }); return React.createElement(FlexiGridBody, props); }; FlexiGrid.prototype.renderFooter = function renderFooter() { var _props3 = this.props, prefixCls = _props3.prefixCls, footerHeight = _props3.footerHeight, footer = _props3.footer; var viewportWidth = this.state.viewportWidth; var style = { width: viewportWidth, height: footerHeight }; return React.createElement( 'div', { className: prefixCls + '-footer', style: style }, footer ); }; FlexiGrid.prototype.renderShadowTop = function renderShadowTop() { var props = { prefixCls: this.props.prefixCls, display: this.state.showScrollbarY, visible: this.state.scrollY > 0, width: this.state.bodyWidth, top: this.state.headerHeight }; return React.createElement(FlexiGridShadowTop, props); }; FlexiGrid.prototype.renderShadowBottom = function renderShadowBottom() { var props = { prefixCls: this.props.prefixCls, display: this.state.showScrollbarY, visible: this.state.scrollY !== this.state.maxScrollY, width: this.state.bodyWidth, bottom: this.props.footerHeight }; return React.createElement(FlexiGridShadowBottom, props); }; FlexiGrid.prototype.renderShadowLeft = function renderShadowLeft() { var _state$columnData = this.state.columnData, leftFixedColumns = _state$columnData.leftFixedColumns, leftFixedColumnsWidth = _state$columnData.leftFixedColumnsWidth; var props = { prefixCls: this.props.prefixCls, display: leftFixedColumns.length > 0, visible: this.state.scrollX > 0, height: this.state.headerHeight + this.state.bodyHeight, left: leftFixedColumnsWidth }; return React.createElement(FlexiGridShadowLeft, props); }; FlexiGrid.prototype.renderShadowRight = function renderShadowRight() { var _state$columnData2 = this.state.columnData, rightFixedColumns = _state$columnData2.rightFixedColumns, rightFixedColumnsWidth = _state$columnData2.rightFixedColumnsWidth; var props = { prefixCls: this.props.prefixCls, display: rightFixedColumns.length > 0, visible: this.state.scrollX !== this.state.maxScrollX, height: this.state.headerHeight + this.state.bodyHeight, right: rightFixedColumnsWidth + (this.state.showScrollbarY ? Scrollbar.SIZE : 0) }; return React.createElement(FlexiGridShadowRight, props); }; FlexiGrid.prototype.renderResizeKnobs = function renderResizeKnobs() { var columnData = this.state.columnData; var props = { prefixCls: this.props.prefixCls, knobSize: this.props.resizeKnobSize, headerRowHeight: this.props.headerRowHeight, headerHeight: this.state.headerHeight, bodyHeight: this.state.bodyHeight, bodyWidth: this.state.bodyWidth, scrollX: this.state.scrollX, showScrollbarX: this.state.showScrollbarX, isJustFullfill: this.state.isJustFullfill, leftFixedLeafColumns: columnData.leftFixedLeafColumns, scrollableLeafColumns: columnData.scrollableLeafColumns, rightFixedLeafColumns: columnData.rightFixedLeafColumns, leftFixedColumnsWidth: columnData.leftFixedColumnsWidth, scrollableColumnsWidth: columnData.scrollableColumnsWidth, rightFixedColumnsWidth: columnData.rightFixedColumnsWidth, onColumnResize: this.onColumnResize }; return React.createElement(FlexiGridColumnResizeKnobs, props); }; FlexiGrid.prototype.renderColumnResizeHandler = function renderColumnResizeHandler() { var props = this.columnResizingData || { prefixCls: this.props.prefixCls }; return React.createElement(FlexiGridColumnResizeHandler, _extends({}, props, { visible: this.isColumnResizing() })); }; FlexiGrid.prototype.renderReorderKnobs = function renderReorderKnobs() { var columnData = this.state.columnData; var props = { prefixCls: this.props.prefixCls, knobSize: this.props.reorderKnobSize, headerHeight: this.state.headerHeight, headerRowHeight: this.props.headerRowHeight, bodyWidth: this.state.bodyWidth, scrollX: this.state.scrollX, showScrollbarX: this.state.showScrollbarX, leftFixedColumns: columnData.leftFixedColumns, scrollableColumns: columnData.scrollableColumns, rightFixedColumns: columnData.rightFixedColumns, leftFixedColumnsWidth: columnData.leftFixedColumnsWidth, scrollableColumnsWidth: columnData.scrollableColumnsWidth, rightFixedColumnsWidth: columnData.rightFixedColumnsWidth, onColumnReorder: this.onColumnReorder }; return React.createElement(FlexiGridColumnReorderKnobs, props); }; FlexiGrid.prototype.renderColumnReorderHandler = function renderColumnReorderHandler() { var props = this.getColumnReorderingData() || { prefixCls: this.props.prefixCls }; return React.createElement(FlexiGridColumnReorderHandler, _extends({}, props, { sortable: this.props.sortable, visible: this.isColumnReordering() })); }; FlexiGrid.prototype.renderColumnSortKnobs = function renderColumnSortKnobs() { var columnData = this.state.columnData; var props = { prefixCls: this.props.prefixCls, knobSize: this.props.sortKnobSize, sortType: this.props.sortType, sortColumnKey: this.props.sortColumnKey, headerRowHeight: this.props.headerRowHeight, headerHeight: this.state.headerHeight, bodyWidth: this.state.bodyWidth, scrollX: this.state.scrollX, showScrollbarX: this.state.showScrollbarX, leftFixedColumns: columnData.leftFixedColumns, scrollableColumns: columnData.scrollableColumns, rightFixedColumns: columnData.rightFixedColumns, leftFixedColumnsWidth: columnData.leftFixedColumnsWidth, scrollableColumnsWidth: columnData.scrollableColumnsWidth, rightFixedColumnsWidth: columnData.rightFixedColumnsWidth, onSort: this.onColumnSort }; return React.createElement(FlexiGridSortKnobs, props); }; FlexiGrid.prototype.renderScrollbar = function renderScrollbar() { var state = this.state; var props = this.props; var result = {}; if (state.showScrollbarY) { result.verticalScrollbar = React.createElement(Scrollbar, { orientation: 'vertical', top: state.headerHeight, prefixCls: props.prefixCls, position: state.scrollY, size: state.bodyHeight, contentSize: state.contentHeight, onScroll: this.onVerticalScroll }); } if (state.showScrollbarX) { result.horizontalScrollbar = React.createElement(Scrollbar, { orientation: 'horizontal', prefixCls: props.prefixCls, position: state.scrollX, size: state.bodyWidth, contentSize: state.contentWidth, hasVerticalScrollbar: state.showScrollbarX, onScroll: this.onHorizontalScroll }); } return result; }; FlexiGrid.prototype.render = function render() { var state = this.state; var props = this.props; var prefixCls = props.prefixCls, className = props.className, bordered = props.bordered, reorderable = props.reorderable, sortable = props.sortable; var mainClassNames = classNames(prefixCls, className, { bordered: bordered, reorderable: reorderable, sortable: sortable }); var _renderScrollbar = this.renderScrollbar(), verticalScrollbar = _renderScrollbar.verticalScrollbar, horizontalScrollbar = _renderScrollbar.horizontalScrollbar; return React.createElement( 'div', { className: mainClassNames, onWheel: this.wheelHandler.onWheel, onTouchStart: this.touchHandler.onTouchStart, onTouchEnd: this.touchHandler.onTouchEnd, onTouchMove: this.touchHandler.onTouchMove, onTouchCancel: this.touchHandler.onTouchCancel, style: { width: state.width, height: state.height } }, React.createElement( 'div', { className: prefixCls + '-container', style: { width: state.viewportWidth, height: state.headerHeight + state.bodyHeight + props.footerHeight } }, this.renderHeader(), this.renderBody(), this.renderFooter(), this.renderShadowTop(), this.renderShadowRight(), this.renderShadowBottom(), this.renderShadowLeft(), this.props.resizable && this.renderResizeKnobs(), this.props.reorderable && this.renderReorderKnobs(), this.props.resizable && this.renderColumnResizeHandler(), this.props.reorderable && this.renderColumnReorderHandler(), this.props.sortable && this.renderColumnSortKnobs() ), verticalScrollbar, horizontalScrollbar ); }; return FlexiGrid; }(React.Component); FlexiGrid.propTypes = { prefixCls: PropTypes.string, className: PropTypes.string, columns: propTypes.columns.isRequired, data: propTypes.data.isRequired, rowKey: PropTypes.string.isRequired, bufferRowCount: PropTypes.number, bufferColumnCount: PropTypes.number, bordered: PropTypes.bool, borderSize: PropTypes.number, width: PropTypes.number.isRequired, height: PropTypes.number, maxHeight: PropTypes.number, ownerHeight: PropTypes.number, footerHeight: PropTypes.number, rowHeight: PropTypes.number, headerRowHeight: PropTypes.number, subRowHeight: PropTypes.number, getRowHeight: PropTypes.func, getSubRowHeight: PropTypes.func, getRowClassName: PropTypes.func, subRow: propTypes.render, footer: propTypes.render, scrollTop: PropTypes.number, scrollLeft: PropTypes.number, scrollToColumn: PropTypes.number, scrollToRow: PropTypes.number, showScrollbarX: PropTypes.bool, showScrollbarY: PropTypes.bool, touchScrollEnabled: PropTypes.bool, onHorizontalScroll: PropTypes.func, onVerticalScroll: PropTypes.func, onScrollStart: PropTypes.func, onScrollEnd: PropTypes.func, stopScrollPropagation: PropTypes.bool, onContentHeightChange: PropTypes.func, onRowTouchStart: PropTypes.func, onRowTouchEnd: PropTypes.func, onRowTouchMove: PropTypes.func, onRowClick: PropTypes.func, onRowDoubleClick: PropTypes.func, onRowMouseDown: PropTypes.func, onRowMouseUp: PropTypes.func, onRowMouseEnter: PropTypes.func, onRowMouseLeave: PropTypes.func, sortable: PropTypes.bool, sortType: PropTypes.oneOf(['asc', 'desc']), sortColumnKey: PropTypes.string, sortKnobSize: PropTypes.number, onColumnSort: PropTypes.func, resizable: PropTypes.bool, resizeKnobSize: PropTypes.number, onColumnResize: PropTypes.func, onColumnResizing: PropTypes.func, onColumnResized: PropTypes.func, reorderable: PropTypes.bool, reorderKnobSize: PropTypes.number, reorderFactor: PropTypes.number, dragScrollBuffer: PropTypes.number, dragScrollSpeed: PropTypes.number, onColumnReorder: PropTypes.func, onColumnReordering: PropTypes.func, onColumnReordered: PropTypes.func }; FlexiGrid.defaultProps = { prefixCls: 'flexi-grid', rowHeight: 32, headerRowHeight: 32, subRowHeight: 0, footerHeight: 0, bordered: true, borderSize: 1, showScrollbarX: true, showScrollbarY: true, touchScrollEnabled: false, stopScrollPropagation: false, sortable: false, sortType: 'asc', sortColumnKey: null, sortKnobSize: 12, resizable: false, resizeKnobSize: 13, reorderable: false, reorderKnobSize: 12, reorderFactor: 3 / 4, dragScrollBuffer: 50, dragScrollSpeed: 15 }; export default FlexiGrid;