mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-01 22:10:27 +00:00
323 lines
12 KiB
JavaScript
323 lines
12 KiB
JavaScript
import _extends from 'babel-runtime/helpers/extends';
|
|
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
|
|
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
|
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
|
import _inherits from 'babel-runtime/helpers/inherits';
|
|
import React from 'react';
|
|
import { findDOMNode } from 'react-dom';
|
|
import PropTypes from 'prop-types';
|
|
import { dom } from '../util';
|
|
import VirtualBody from './virtual/body';
|
|
import { statics } from './util';
|
|
|
|
var noop = function noop() {};
|
|
export default function virtual(BaseComponent) {
|
|
var _class, _temp2;
|
|
|
|
var VirtualTable = (_temp2 = _class = function (_React$Component) {
|
|
_inherits(VirtualTable, _React$Component);
|
|
|
|
function VirtualTable() {
|
|
var _temp, _this, _ret;
|
|
|
|
_classCallCheck(this, VirtualTable);
|
|
|
|
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.state = {
|
|
rowHeight: _this.props.rowHeight,
|
|
scrollToRow: _this.props.scrollToRow,
|
|
height: _this.props.maxBodyHeight
|
|
}, _this.onScroll = function () {
|
|
// 避免横向滚动带来的性能问题
|
|
var scrollTop = _this.bodyNode.scrollTop;
|
|
if (scrollTop === _this.lastScrollTop) {
|
|
return;
|
|
}
|
|
var start = _this.computeScrollToRow(scrollTop);
|
|
if (!('scrollToRow' in _this.props)) {
|
|
_this.setState({
|
|
scrollToRow: start
|
|
});
|
|
}
|
|
_this.props.onBodyScroll(start);
|
|
_this.lastScrollTop = scrollTop;
|
|
}, _this.getBodyNode = function (node, lockType) {
|
|
lockType = lockType ? lockType.charAt(0).toUpperCase() + lockType.substr(1) : '';
|
|
_this['body' + lockType + 'Node'] = node;
|
|
}, _this.getTableInstance = function (type, instance) {
|
|
type = type ? type.charAt(0).toUpperCase() + type.substr(1) : '';
|
|
_this['table' + type + 'Inc'] = instance;
|
|
}, _temp), _possibleConstructorReturn(_this, _ret);
|
|
}
|
|
|
|
VirtualTable.prototype.getChildContext = function getChildContext() {
|
|
return {
|
|
onVirtualScroll: this.onScroll,
|
|
bodyHeight: this.computeBodyHeight(),
|
|
innerTop: this.computeInnerTop(),
|
|
getBodyNode: this.getBodyNode,
|
|
getTableInstanceForVirtual: this.getTableInstance,
|
|
rowSelection: this.rowSelection
|
|
};
|
|
};
|
|
|
|
VirtualTable.prototype.componentWillMount = function componentWillMount() {
|
|
var _props = this.props,
|
|
useVirtual = _props.useVirtual,
|
|
dataSource = _props.dataSource;
|
|
|
|
|
|
this.hasVirtualData = useVirtual && dataSource && dataSource.length > 0;
|
|
};
|
|
|
|
VirtualTable.prototype.componentDidMount = function componentDidMount() {
|
|
if (this.hasVirtualData) {
|
|
this.lastScrollTop = this.bodyNode.scrollTop;
|
|
}
|
|
|
|
this.adjustScrollTop();
|
|
this.adjustSize();
|
|
this.reComputeSize();
|
|
};
|
|
|
|
VirtualTable.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
|
|
var useVirtual = nextProps.useVirtual,
|
|
dataSource = nextProps.dataSource;
|
|
|
|
|
|
this.hasVirtualData = useVirtual && dataSource && dataSource.length > 0;
|
|
|
|
if ('maxBodyHeight' in nextProps) {
|
|
if (this.state.height !== nextProps.maxBodyHeight) {
|
|
this.setState({
|
|
height: nextProps.maxBodyHeight
|
|
});
|
|
}
|
|
}
|
|
|
|
if ('scrollToRow' in nextProps) {
|
|
this.setState({
|
|
scrollToRow: nextProps.scrollToRow
|
|
});
|
|
}
|
|
|
|
if (this.state.rowHeight && 'rowHeight' in nextProps) {
|
|
var row = this.getRowNode();
|
|
var rowClientHeight = row && row.clientHeight;
|
|
if (rowClientHeight && rowClientHeight !== this.state.rowHeight) {
|
|
this.setState({
|
|
rowHeight: rowClientHeight
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
VirtualTable.prototype.componentDidUpdate = function componentDidUpdate() {
|
|
this.adjustScrollTop();
|
|
this.adjustSize();
|
|
this.reComputeSize();
|
|
};
|
|
|
|
VirtualTable.prototype.reComputeSize = function reComputeSize() {
|
|
var rowHeight = this.state.rowHeight;
|
|
|
|
if (typeof rowHeight === 'function' && this.hasVirtualData) {
|
|
var row = this.getRowNode();
|
|
var rowClientHeight = row && row.clientHeight;
|
|
if (rowClientHeight !== this.state.rowHeight) {
|
|
this.setState({
|
|
rowHeight: rowClientHeight
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
VirtualTable.prototype.computeBodyHeight = function computeBodyHeight() {
|
|
var rowHeight = this.state.rowHeight;
|
|
var dataSource = this.props.dataSource;
|
|
|
|
if (typeof rowHeight === 'function') {
|
|
return 0;
|
|
}
|
|
return dataSource.length * rowHeight;
|
|
};
|
|
|
|
VirtualTable.prototype.computeInnerTop = function computeInnerTop() {
|
|
var rowHeight = this.state.rowHeight;
|
|
|
|
if (typeof rowHeight === 'function') {
|
|
return 0;
|
|
}
|
|
|
|
return this.start * rowHeight;
|
|
};
|
|
|
|
VirtualTable.prototype.getVisibleRange = function getVisibleRange(ExpectStart) {
|
|
var _state = this.state,
|
|
height = _state.height,
|
|
rowHeight = _state.rowHeight;
|
|
|
|
var len = this.props.dataSource.length;
|
|
|
|
var end = void 0,
|
|
visibleCount = 0;
|
|
var start = 0;
|
|
if (typeof rowHeight === 'function') {
|
|
// try get cell height;
|
|
end = 1;
|
|
} else {
|
|
visibleCount = parseInt(dom.getPixels(height) / rowHeight, 10);
|
|
|
|
if ('number' === typeof ExpectStart) {
|
|
start = ExpectStart < len ? ExpectStart : 0;
|
|
}
|
|
|
|
end = Math.min(+start + 1 + visibleCount + 10, len);
|
|
}
|
|
this.end = end;
|
|
this.visibleCount = visibleCount;
|
|
return {
|
|
start: start,
|
|
end: end
|
|
};
|
|
};
|
|
|
|
VirtualTable.prototype.adjustScrollTop = function adjustScrollTop() {
|
|
if (this.hasVirtualData) {
|
|
this.bodyNode.scrollTop = this.lastScrollTop % this.state.rowHeight + this.state.rowHeight * this.state.scrollToRow;
|
|
}
|
|
};
|
|
|
|
VirtualTable.prototype.adjustSize = function adjustSize() {
|
|
if (this.hasVirtualData) {
|
|
var body = this.bodyNode;
|
|
var virtualScrollNode = body.querySelector('div');
|
|
var clientHeight = body.clientHeight,
|
|
clientWidth = body.clientWidth;
|
|
|
|
|
|
var tableInc = this.tableInc;
|
|
var tableNode = findDOMNode(tableInc);
|
|
var prefix = this.props.prefix;
|
|
|
|
var headerNode = tableNode.querySelector('.' + prefix + 'table-header table');
|
|
var headerClientWidth = headerNode && headerNode.clientWidth;
|
|
|
|
if (clientWidth < headerClientWidth) {
|
|
dom.setStyle(virtualScrollNode, 'min-width', headerClientWidth);
|
|
var leftNode = this.bodyLeftNode;
|
|
var rightNode = this.bodyRightNode;
|
|
leftNode && dom.setStyle(leftNode, 'max-height', clientHeight);
|
|
rightNode && dom.setStyle(rightNode, 'max-height', clientHeight);
|
|
this.hasScrollbar = true;
|
|
} else {
|
|
dom.setStyle(virtualScrollNode, 'min-width', 'auto');
|
|
this.hasScrollbar = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
VirtualTable.prototype.computeScrollToRow = function computeScrollToRow(offset) {
|
|
var rowHeight = this.state.rowHeight;
|
|
|
|
var start = parseInt(offset / rowHeight);
|
|
this.start = start;
|
|
return start;
|
|
};
|
|
|
|
VirtualTable.prototype.getRowNode = function getRowNode() {
|
|
try {
|
|
// in case of finding an unmounted component due to cached data
|
|
// need to clear refs of this.tableInc when dataSource Changed
|
|
// use try catch for temporary
|
|
return findDOMNode(this.tableInc.getRowRef(0));
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
VirtualTable.prototype.render = function render() {
|
|
/* eslint-disable no-unused-vars, prefer-const */
|
|
var _props2 = this.props,
|
|
useVirtual = _props2.useVirtual,
|
|
components = _props2.components,
|
|
dataSource = _props2.dataSource,
|
|
fixedHeader = _props2.fixedHeader,
|
|
rowHeight = _props2.rowHeight,
|
|
scrollToRow = _props2.scrollToRow,
|
|
onBodyScroll = _props2.onBodyScroll,
|
|
others = _objectWithoutProperties(_props2, ['useVirtual', 'components', 'dataSource', 'fixedHeader', 'rowHeight', 'scrollToRow', 'onBodyScroll']);
|
|
|
|
var entireDataSource = dataSource;
|
|
var newDataSource = dataSource;
|
|
|
|
this.rowSelection = this.props.rowSelection;
|
|
if (this.hasVirtualData) {
|
|
newDataSource = [];
|
|
components = _extends({}, components);
|
|
|
|
var _getVisibleRange = this.getVisibleRange(this.state.scrollToRow),
|
|
start = _getVisibleRange.start,
|
|
end = _getVisibleRange.end;
|
|
|
|
dataSource.forEach(function (current, index, record) {
|
|
if (index >= start && index < end) {
|
|
current.__rowIndex = index;
|
|
newDataSource.push(current);
|
|
}
|
|
});
|
|
|
|
if (!components.Body) {
|
|
components.Body = VirtualBody;
|
|
}
|
|
fixedHeader = true;
|
|
}
|
|
|
|
return React.createElement(BaseComponent, _extends({}, others, {
|
|
dataSource: newDataSource,
|
|
entireDataSource: entireDataSource,
|
|
components: components,
|
|
fixedHeader: fixedHeader
|
|
}));
|
|
};
|
|
|
|
return VirtualTable;
|
|
}(React.Component), _class.VirtualBody = VirtualBody, _class.propTypes = _extends({
|
|
/**
|
|
* 是否开启虚拟滚动
|
|
*/
|
|
useVirtual: PropTypes.bool,
|
|
/**
|
|
* 设置行高
|
|
*/
|
|
rowHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
|
|
maxBodyHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
primaryKey: PropTypes.string,
|
|
dataSource: PropTypes.array,
|
|
/**
|
|
* 在内容区域滚动的时候触发的函数
|
|
*/
|
|
onBodyScroll: PropTypes.func
|
|
}, BaseComponent.propTypes), _class.defaultProps = _extends({}, BaseComponent.defaultProps, {
|
|
primaryKey: 'id',
|
|
rowHeight: noop,
|
|
maxBodyHeight: 200,
|
|
components: {},
|
|
prefix: 'next-',
|
|
onBodyScroll: noop
|
|
}), _class.childContextTypes = {
|
|
onVirtualScroll: PropTypes.func,
|
|
bodyHeight: PropTypes.number,
|
|
innerTop: PropTypes.number,
|
|
getBodyNode: PropTypes.func,
|
|
getTableInstanceForVirtual: PropTypes.func,
|
|
rowSelection: PropTypes.object
|
|
}, _temp2);
|
|
VirtualTable.displayName = 'VirtualTable';
|
|
|
|
statics(VirtualTable, BaseComponent);
|
|
return VirtualTable;
|
|
} |