UNPKG

zent

Version:

一套前端设计语言和基于React的实现

585 lines (484 loc) 18.5 kB
'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;