zent
Version:
一套前端设计语言和基于React的实现
585 lines (484 loc) • 18.5 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _loading = require('../loading');
var _loading2 = _interopRequireDefault(_loading);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _isBrowser = require('../utils/isBrowser');
var _isBrowser2 = _interopRequireDefault(_isBrowser);
var _throttle = require('lodash/throttle');
var _throttle2 = _interopRequireDefault(_throttle);
var _intersection = require('lodash/intersection');
var _intersection2 = _interopRequireDefault(_intersection);
var _uniq = require('lodash/uniq');
var _uniq2 = _interopRequireDefault(_uniq);
var _uniqBy = require('lodash/uniqBy');
var _uniqBy2 = _interopRequireDefault(_uniqBy);
var _pullAll = require('lodash/pullAll');
var _pullAll2 = _interopRequireDefault(_pullAll);
var _pullAllBy = require('lodash/pullAllBy');
var _pullAllBy2 = _interopRequireDefault(_pullAllBy);
var _Head = require('./modules/Head');
var _Head2 = _interopRequireDefault(_Head);
var _Body = require('./modules/Body');
var _Body2 = _interopRequireDefault(_Body);
var _Foot = require('./modules/Foot');
var _Foot2 = _interopRequireDefault(_Foot);
var _helper = require('./helper');
var _helper2 = _interopRequireDefault(_helper);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var func = _propTypes2['default'].func,
bool = _propTypes2['default'].bool,
string = _propTypes2['default'].string,
array = _propTypes2['default'].array,
oneOf = _propTypes2['default'].oneOf,
object = _propTypes2['default'].object; /* eslint-disable no-lonely-if */
var Table = function (_ref) {
(0, _inherits3['default'])(Table, _ref);
function Table(props) {
(0, _classCallCheck3['default'])(this, Table);
var _this = (0, _possibleConstructorReturn3['default'])(this, (Table.__proto__ || Object.getPrototypeOf(Table)).call(this, props));
_this.selectedRowKeys = [];
_this.selectedRows = [];
_this.onChange = function (conf) {
_this.setState(conf);
_this.wrapPropsOnChange(conf);
};
_this.onSort = function (conf) {
// 排序的时候也要触发
_this.wrapPropsOnChange(conf);
};
_this.onPageChange = function (current) {
_this.wrapPropsOnChange({
current: current
});
if (_this.props.autoScroll) {
_this.scrollToTop(400);
}
};
_this.onSelectAllRows = function (isSelect) {
var rowKeysCurrentPage = [];
var rowsCurrentPage = [];
var _this$props = _this.props,
rowKey = _this$props.rowKey,
datasets = _this$props.datasets,
selection = _this$props.selection,
_this$props$getRowCon = _this$props.getRowConf,
getRowConf = _this$props$getRowCon === undefined ? function () {
return { canSelect: true };
} : _this$props$getRowCon;
_this.setSelection();
var allRowKeys = _this.selectedRowKeys;
var allRows = _this.selectedRows;
// 找出所有canSelect为true的row
for (var i = 0, len = datasets.length; i < len; i++) {
var _getRowConf = getRowConf(datasets[i], i),
_getRowConf$canSelect = _getRowConf.canSelect,
canSelect = _getRowConf$canSelect === undefined ? true : _getRowConf$canSelect;
if (canSelect) {
rowKeysCurrentPage.push(datasets[i][rowKey]);
rowsCurrentPage.push(datasets[i]);
}
}
if (isSelect) {
if (_this.props.selection.needCrossPage) {
allRowKeys = (0, _uniq2['default'])(allRowKeys.concat(rowKeysCurrentPage));
allRows = (0, _uniqBy2['default'])(allRows.concat(rowsCurrentPage), rowKey);
} else {
allRowKeys = rowKeysCurrentPage;
allRows = rowsCurrentPage;
}
} else {
if (_this.props.selection.needCrossPage) {
allRowKeys = (0, _pullAll2['default'])(allRowKeys, rowKeysCurrentPage);
allRows = (0, _pullAllBy2['default'])(allRows, rowsCurrentPage, rowKey);
} else {
allRowKeys = [];
allRows = [];
}
}
_this.selectedRowKeys = allRowKeys;
_this.selectedRows = allRows;
selection.onSelect(_this.selectedRowKeys, _this.selectedRows, null);
};
_this.onSelectOneRow = function (rowKey, isSelect) {
var selection = _this.props.selection;
_this.setSelection();
var index = _this.selectedRowKeys.indexOf(rowKey);
var isSingleSelection = selection.isSingleSelection || false;
if (isSingleSelection) {
// radio的isSelect永远是true,所以一旦选择了,则不能取消
if (isSelect) {
_this.selectedRowKeys = [rowKey];
} else {
_this.selectedRowKeys = [];
}
} else if (isSelect && index === -1) {
_this.selectedRowKeys.push(rowKey);
} else if (index !== -1) {
_this.selectedRowKeys.splice(index, 1);
}
if (!selection.needCrossPage) {
_this.selectedRowKeys = (0, _intersection2['default'])(_this.selectedRowKeys, _this.props.datasets.map(function (item) {
return item[_this.props.rowKey];
}));
}
var selectedRows = _this.getSelectedRowsByKeys(_this.selectedRowKeys);
var currentRow = isSelect ? _this.getCurrentRow(rowKey) : null;
selection.onSelect(_this.selectedRowKeys, selectedRows, currentRow);
};
_this.state = {
current: props.pageInfo ? props.pageInfo.current : 1,
batchComponentsFixed: false,
placeHolderHeight: false,
fixStyle: {}
};
_this.tableRect = null;
_this.relativeTop = 0;
return _this;
}
// 一个global的selectedRowKeys用于保存所有选中的选项
(0, _createClass3['default'])(Table, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var toggleListener = _helper2['default'].toggleEventListener(this.props, nextProps);
toggleListener && this[toggleListener](nextProps);
this.setState({
current: nextProps.pageInfo ? nextProps.pageInfo.current : 1
});
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
this.addEventListener(this.props);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.removeEventListener(this.props);
}
}, {
key: 'addEventListener',
value: function addEventListener(props) {
var _this2 = this;
if (props.batchComponentsAutoFixed) {
var batchComponents = props.batchComponents;
this.setRectParam();
if (batchComponents && batchComponents.length > 0) {
this.throttleSetBatchComponents = (0, _throttle2['default'])(function () {
_this2.setRectParam();
_this2.toggleBatchComponents();
}, 100, {
leading: true
});
window.addEventListener('scroll', this.throttleSetBatchComponents, true);
window.addEventListener('resize', this.throttleSetBatchComponents, true);
}
}
}
}, {
key: 'removeEventListener',
value: function removeEventListener(props) {
if (props.batchComponentsAutoFixed) {
window.removeEventListener('scroll', this.throttleSetBatchComponents, true);
window.removeEventListener('resize', this.throttleSetBatchComponents, true);
}
}
}, {
key: 'setRectParam',
value: function setRectParam() {
this.tableRectTop = _reactDom2['default'].findDOMNode(this).getBoundingClientRect().top;
this.tableRectHeight = _reactDom2['default'].findDOMNode(this).getBoundingClientRect().height;
this.relativeTop = this.tableRectTop - document.documentElement.getBoundingClientRect().top;
}
}, {
key: 'toggleBatchComponents',
value: function toggleBatchComponents() {
var needFixedBatchComps = _helper2['default'].needFixBatchComps(this.isTableInView(), this.isFootInView(), this.props.selection.selectedRowKeys.length > 0, this.state.batchComponentsFixed);
if (typeof needFixedBatchComps === 'boolean') {
this.setState({
batchComponentsFixed: needFixedBatchComps
});
}
}
// 对外部传进来的onChange进行封装
}, {
key: 'wrapPropsOnChange',
value: function wrapPropsOnChange(conf) {
if (typeof this.props.onChange !== 'function') {
throw new Error('请传入一个onChange方法');
}
this.props.onChange(conf);
}
}, {
key: 'setSelection',
/**
* 设置内部属性,cached选中结果
*/
value: function setSelection() {
var selection = this.props.selection;
this.selectedRowKeys = selection.selectedRowKeys.slice(0); // copy 一份数组
this.selectedRows = this.getSelectedRowsByKeys(this.selectedRowKeys);
}
/*
* Head上的选中会全选所有的行
* @param isSelect {Boolean} 表示是否全选
*/
/**
* 选了一行
* @param rowKey {String} 某一行的key
* @param isSelect {Boolean} 是否被选中
*/
}, {
key: 'getCurrentRow',
value: function getCurrentRow(key) {
var currentRow = void 0;
var self = this;
if (key) {
this.props.datasets.forEach(function (item) {
if (item[self.props.rowKey] === key) {
currentRow = item;
}
});
}
return currentRow;
}
}, {
key: 'isTableInView',
value: function isTableInView() {
var tableY = this.tableRectTop - document.documentElement.getBoundingClientRect().top;
return tableY + this.tableRectHeight > window.pageYOffset && tableY <= window.pageYOffset + window.innerHeight;
}
}, {
key: 'isFootInView',
value: function isFootInView() {
var footRect = _reactDom2['default'].findDOMNode(this.foot).getBoundingClientRect();
var footY = footRect.top - document.documentElement.getBoundingClientRect().top;
return footY + footRect.height > window.pageYOffset && footY <= window.pageYOffset + window.innerHeight;
}
/**
* 根据选择的keys拼装一个选好的列
* @param rowKeys Array 一个keys的数组
* @return rows Array 一个每行的数据的数组
*/
}, {
key: 'getSelectedRowsByKeys',
value: function getSelectedRowsByKeys(rowKeys) {
var rows = [];
var self = this;
// 之前缓存的rows和本页的总datasets整个作为搜索的区间
var allRows = (0, _uniqBy2['default'])(this.selectedRows.concat(this.props.datasets), this.props.rowKey);
allRows.forEach(function (item) {
if (rowKeys.indexOf(item[self.props.rowKey]) >= 0) {
rows.push(item);
}
});
return rows;
}
}, {
key: 'scrollToTop',
value: function scrollToTop(scrollDuration) {
var _this3 = this;
if (!_isBrowser2['default']) return;
var scrollHeight = window.scrollY;
var scrollStep = Math.PI / (scrollDuration / 15);
var cosParameter = scrollHeight / 2;
var scrollCount = 0;
var scrollMargin = void 0;
var scrollInterval = setInterval(function () {
if (window.scrollY > _this3.relativeTop) {
scrollCount += 1;
scrollMargin = cosParameter - cosParameter * Math.cos(scrollCount * scrollStep);
window.scrollTo(0, scrollHeight - scrollMargin);
} else {
clearInterval(scrollInterval);
}
}, 16);
}
}, {
key: 'render',
value: function render() {
var _this4 = this;
var _props = this.props,
selection = _props.selection,
prefix = _props.prefix,
columns = _props.columns,
className = _props.className,
sortBy = _props.sortBy,
autoStick = _props.autoStick,
sortType = _props.sortType,
datasets = _props.datasets,
rowKey = _props.rowKey,
pageInfo = _props.pageInfo,
emptyLabel = _props.emptyLabel,
_props$getRowConf = _props.getRowConf,
getRowConf = _props$getRowConf === undefined ? function () {
return { canSelect: true, rowClass: '' };
} : _props$getRowConf,
_props$expandation = _props.expandation,
expandation = _props$expandation === undefined ? null : _props$expandation,
_props$batchComponent = _props.batchComponents,
batchComponents = _props$batchComponent === undefined ? null : _props$batchComponent;
var needSelect = selection !== null;
var isSingleSelection = void 0;
if (selection) {
isSingleSelection = selection.isSingleSelection || false;
}
var selectedRowKeys = [];
var canSelectAll = false;
var isSelectAll = false;
var isSelectPart = false;
var canRowSelect = false;
var needExpand = false;
var isExpanded = void 0;
var expandRender = void 0;
if (expandation) {
needExpand = true;
isExpanded = expandation.isExpanded;
expandRender = expandation.expandRender;
}
if (needSelect) {
var canSelectRowKeysArr = [];
datasets.forEach(function (item, index) {
var _getRowConf2 = getRowConf(item, index),
_getRowConf2$canSelec = _getRowConf2.canSelect,
canSelect = _getRowConf2$canSelec === undefined ? true : _getRowConf2$canSelec;
if (canSelect) {
canSelectRowKeysArr.push(item[rowKey]);
}
});
selectedRowKeys = selection.selectedRowKeys || [];
canSelectAll = canSelectRowKeysArr.length > 0;
canRowSelect = selection.canRowSelect;
isSelectAll = canSelectRowKeysArr.length > 0 && _helper2['default'].isSelectAll(selectedRowKeys, canSelectRowKeysArr);
isSelectPart = canSelectRowKeysArr.length > 0 && !isSelectAll && _helper2['default'].isSelectPart(selectedRowKeys, canSelectRowKeysArr);
}
return _react2['default'].createElement(
'div',
{ className: prefix + '-table-container' },
_react2['default'].createElement(
_loading2['default'],
{ show: this.props.loading, 'static': true },
columns && _react2['default'].createElement(
'div',
{ className: prefix + '-table ' + className },
this.state.placeHolderHeight && _react2['default'].createElement(
'div',
{ className: 'thead place-holder' },
_react2['default'].createElement(
'div',
{ className: 'tr' },
this.cloneHeaderContent()
)
),
_react2['default'].createElement(_Head2['default'], {
ref: function ref(c) {
return _this4.head = c;
},
columns: columns,
sortBy: sortBy,
sortType: sortType,
onSort: this.onSort,
selection: {
needSelect: needSelect,
onSelectAll: this.onSelectAllRows,
isSingleSelection: isSingleSelection,
canSelectAll: canSelectAll,
isSelectAll: isSelectAll,
isSelectPart: isSelectPart
},
needExpand: needExpand,
autoStick: autoStick,
style: this.state.fixStyle
}),
_react2['default'].createElement(_Body2['default'], {
datasets: datasets,
columns: columns,
emptyLabel: emptyLabel,
rowKey: rowKey,
getRowConf: getRowConf,
selection: {
needSelect: needSelect,
selectedRowKeys: selectedRowKeys,
isSingleSelection: isSingleSelection,
onSelect: this.onSelectOneRow,
canRowSelect: canRowSelect
},
needExpand: needExpand,
isExpanded: isExpanded,
expandRender: expandRender
}),
_react2['default'].createElement(_Foot2['default'], {
ref: function ref(c) {
return _this4.foot = c;
},
batchComponents: batchComponents,
pageInfo: pageInfo,
batchComponentsFixed: this.state.batchComponentsFixed,
selection: {
needSelect: needSelect,
isSingleSelection: isSingleSelection,
onSelectAll: this.onSelectAllRows,
selectedRows: this.getSelectedRowsByKeys(selectedRowKeys),
isSelectAll: isSelectAll,
isSelectPart: isSelectPart
},
current: this.state.current,
onPageChange: this.onPageChange
})
)
)
);
}
}]);
return Table;
}(_react.PureComponent || _react.Component);
Table.propTypes = {
className: string,
prefix: string,
columns: array,
datasets: array,
onChange: func,
sortBy: string,
sortType: oneOf(['desc', 'asc']),
pageInfo: object,
rowKey: string,
loading: bool,
autoScroll: bool,
autoStick: bool,
selection: object,
expandation: object,
batchComponentsAutoFixed: bool,
batchComponents: array
};
Table.defaultProps = {
prefix: 'zent',
pageSize: 10,
className: '',
datasets: [],
columns: [],
emptyLabel: '没有更多数据了',
rowKey: 'id',
sortType: 'desc',
loading: false,
autoScroll: false,
autoStick: false,
selection: null,
batchComponentsAutoFixed: true,
batchComponents: null
};
exports['default'] = Table;