UNPKG

19.2 kBJavaScriptView Raw
1'use strict';
2
3exports.__esModule = true;
4
5var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
6
7var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
8
9var _extends2 = require('babel-runtime/helpers/extends');
10
11var _extends3 = _interopRequireDefault(_extends2);
12
13var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
14
15var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
16
17var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
18
19var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
20
21var _inherits2 = require('babel-runtime/helpers/inherits');
22
23var _inherits3 = _interopRequireDefault(_inherits2);
24
25exports.default = stickyLock;
26
27var _react = require('react');
28
29var _react2 = _interopRequireDefault(_react);
30
31var _reactDom = require('react-dom');
32
33var _propTypes = require('prop-types');
34
35var _propTypes2 = _interopRequireDefault(_propTypes);
36
37var _classnames2 = require('classnames');
38
39var _classnames3 = _interopRequireDefault(_classnames2);
40
41var _shallowElementEquals = require('shallow-element-equals');
42
43var _shallowElementEquals2 = _interopRequireDefault(_shallowElementEquals);
44
45var _util = require('../util');
46
47var _row = require('./lock/row');
48
49var _row2 = _interopRequireDefault(_row);
50
51var _body = require('./lock/body');
52
53var _body2 = _interopRequireDefault(_body);
54
55var _header = require('./lock/header');
56
57var _header2 = _interopRequireDefault(_header);
58
59var _wrapper = require('./fixed/wrapper');
60
61var _wrapper2 = _interopRequireDefault(_wrapper);
62
63var _util2 = require('./util');
64
65function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
66
67function stickyLock(BaseComponent) {
68 var _class, _temp;
69
70 /** Table */
71 var LockTable = (_temp = _class = function (_React$Component) {
72 (0, _inherits3.default)(LockTable, _React$Component);
73
74 function LockTable(props, context) {
75 (0, _classCallCheck3.default)(this, LockTable);
76
77 var _this = (0, _possibleConstructorReturn3.default)(this, _React$Component.call(this, props));
78
79 _this.state = {};
80
81 _this.updateOffsetArr = function () {
82 var _ref = _this.splitChildren || {},
83 lockLeftChildren = _ref.lockLeftChildren,
84 lockRightChildren = _ref.lockRightChildren,
85 originChildren = _ref.originChildren;
86
87 var leftLen = _this.getFlatenChildren(lockLeftChildren).length;
88 var rightLen = _this.getFlatenChildren(lockRightChildren).length;
89 var totalLen = leftLen + rightLen + _this.getFlatenChildren(originChildren).length;
90
91 var hasLockLeft = leftLen > 0;
92 var hasLockRight = rightLen > 0;
93
94 var leftOffsetArr = _this.getStickyWidth(lockLeftChildren, 'left', totalLen);
95 var rightOffsetArr = _this.getStickyWidth(lockRightChildren, 'right', totalLen);
96
97 var state = {};
98
99 if ('' + leftOffsetArr !== '' + _this.state.leftOffsetArr) {
100 state.leftOffsetArr = leftOffsetArr;
101 }
102
103 if ('' + rightOffsetArr !== '' + _this.state.rightOffsetArr) {
104 state.rightOffsetArr = rightOffsetArr;
105 }
106
107 if (hasLockLeft !== _this.state.hasLockLeft) {
108 state.hasLockLeft = hasLockLeft;
109 }
110
111 if (hasLockRight !== _this.state.hasLockRight) {
112 state.hasLockRight = hasLockRight;
113 }
114
115 if (Object.keys(state).length > 0) {
116 _this.setState(state);
117 }
118 };
119
120 _this.onLockBodyScroll = function (e, forceSet) {
121 var _ref2 = e.currentTarget || {},
122 scrollLeft = _ref2.scrollLeft,
123 scrollWidth = _ref2.scrollWidth,
124 clientWidth = _ref2.clientWidth;
125
126 var pingRight = _this.pingRight,
127 pingLeft = _this.pingLeft;
128
129
130 var pingLeftNext = scrollLeft > 0 && _this.state.hasLockLeft;
131 var pingRightNext = scrollLeft < scrollWidth - clientWidth && _this.state.hasLockRight;
132
133 if (forceSet || pingLeft !== pingLeftNext || pingRight !== pingRightNext) {
134 var prefix = _this.props.prefix;
135
136 var table = _this.getTableNode();
137
138 _this.pingLeft = pingLeftNext;
139 _this.pingRight = pingRightNext;
140
141 var leftFunc = pingLeftNext ? 'addClass' : 'removeClass';
142 _util.dom[leftFunc](table, prefix + 'table-ping-left');
143 var rightFunc = pingRightNext ? 'addClass' : 'removeClass';
144 _util.dom[rightFunc](table, prefix + 'table-ping-right');
145 }
146 };
147
148 _this.getStickyWidth = function (lockChildren, dir, totalLen) {
149 var _this$props = _this.props,
150 dataSource = _this$props.dataSource,
151 scrollToRow = _this$props.scrollToRow;
152
153 var offsetArr = [];
154 var flatenChildren = _this.getFlatenChildren(lockChildren);
155 var len = flatenChildren.length;
156
157 flatenChildren.reduce(function (ret, col, index) {
158 var tag = dir === 'left' ? index : len - 1 - index;
159 var tagNext = dir === 'left' ? tag - 1 : tag + 1;
160 var nodeToGetWidth = dir === 'left' ? tag - 1 : totalLen - index;
161
162 if (dir === 'left' && tag === 0) {
163 ret[0] = 0;
164 return ret;
165 } else if (dir === 'right' && tag === len - 1) {
166 ret[tag] = 0;
167 return ret;
168 }
169
170 // header with no dataSource
171 var isEmpty = !(dataSource && dataSource.length > 0);
172 // no header
173 var node = isEmpty ? _this.getHeaderCellNode(0, nodeToGetWidth) : _this.getCellNode(scrollToRow || dataSource[0] && dataSource[0].__rowIndex || 0, nodeToGetWidth);
174 var colWidth = node && parseFloat(getComputedStyle(node).width) || 0;
175
176 ret[tag] = (ret[tagNext] || 0) + colWidth;
177 return ret;
178 }, offsetArr);
179
180 return offsetArr;
181 };
182
183 _this.getTableInstance = function (type, instance) {
184 type = '';
185 _this['table' + type + 'Inc'] = instance;
186 };
187
188 _this.getNode = function (type, node) {
189 _this[type + 'Node'] = node;
190 };
191
192 _this.getFlatenChildren = function () {
193 var children = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
194
195 var loop = function loop(arr) {
196 var newArray = [];
197 arr.forEach(function (child) {
198 if (child.children) {
199 newArray.push.apply(newArray, loop(child.children));
200 } else {
201 newArray.push(child);
202 }
203 });
204 return newArray;
205 };
206
207 return loop(children);
208 };
209
210 _this.state = {
211 hasLockLeft: true,
212 hasLockRight: true
213 };
214
215 _this.pingLeft = false;
216 _this.pingRight = false;
217 return _this;
218 }
219
220 LockTable.prototype.getChildContext = function getChildContext() {
221 return {
222 getTableInstance: this.getTableInstance,
223 getLockNode: this.getNode,
224 onLockBodyScroll: this.onLockBodyScroll
225 };
226 };
227
228 LockTable.prototype.componentDidMount = function componentDidMount() {
229 var dataSource = this.props.dataSource;
230
231 var isEmpty = !(dataSource && dataSource.length > 0);
232
233 this.updateOffsetArr();
234 this.onLockBodyScroll(isEmpty ? { currentTarget: this.headerNode } : { currentTarget: this.bodyNode });
235 this.forceUpdate();
236
237 _util.events.on(window, 'resize', this.updateOffsetArr);
238 };
239
240 LockTable.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState, nextContext) {
241 if (nextProps.pure) {
242 var isEqual = (0, _shallowElementEquals2.default)(nextProps, this.props);
243 return !(isEqual && _util.obj.shallowEqual(nextContext, this.context));
244 }
245
246 return true;
247 };
248
249 LockTable.prototype.componentDidUpdate = function componentDidUpdate() {
250 this.updateOffsetArr();
251 this.onLockBodyScroll(this.bodyNode ? { currentTarget: this.bodyNode } : { currentTarget: this.headerNode }, true);
252 };
253
254 LockTable.prototype.componentWillUnmount = function componentWillUnmount() {
255 this.pingLeft = false;
256 this.pingRight = false;
257 _util.events.off(window, 'resize', this.updateOffsetArr);
258 };
259
260 LockTable.prototype.normalizeChildrenState = function normalizeChildrenState(props) {
261 var columns = this.normalizeChildren(props);
262
263 this.splitChildren = this.splitFromNormalizeChildren(columns);
264
265 return this.mergeFromSplitLockChildren(this.splitChildren, props.prefix);
266 };
267
268 // 将React结构化数据提取props转换成数组
269
270
271 LockTable.prototype.normalizeChildren = function normalizeChildren(props) {
272 var children = props.children,
273 columns = props.columns;
274
275 var isLock = false,
276 ret = void 0;
277 var getChildren = function getChildren(children) {
278 var ret = [];
279 _react.Children.forEach(children, function (child) {
280 if (child) {
281 var _props = (0, _extends3.default)({}, child.props);
282 if ([true, 'left', 'right'].indexOf(_props.lock) > -1) {
283 isLock = true;
284 if (!('width' in _props)) {
285 _util.log.warning('Should config width for lock column named [ ' + _props.dataIndex + ' ].');
286 }
287 }
288 ret.push(_props);
289 if (child.props.children) {
290 _props.children = getChildren(child.props.children);
291 }
292 }
293 });
294 return ret;
295 };
296
297 if (columns && !children) {
298 ret = columns;
299 isLock = columns.find(function (record) {
300 return [true, 'left', 'right'].indexOf(record.lock) > -1;
301 });
302 } else {
303 ret = getChildren(children);
304 }
305 ret.forEach(function (child) {
306 // 为自定义的列特殊处理
307 if (child.__normalized && isLock) {
308 // users can set lock type for column selection now, so its origin lock type comes first
309 child.lock = child.lock || 'left';
310 delete child.__normalized;
311 }
312 });
313 return ret;
314 };
315
316 /**
317 * 从数组中分离出lock的列和正常的列
318 * @param {Array} children
319 * @return {Object} { lockLeftChildren, lockRightChildren, originChildren } 锁左列, 锁左列, 剩余列
320 */
321
322
323 LockTable.prototype.splitFromNormalizeChildren = function splitFromNormalizeChildren(children) {
324 var originChildren = deepCopy(children);
325 var lockLeftChildren = deepCopy(children);
326 var lockRightChildren = deepCopy(children);
327 var loop = function loop(lockChildren, condition) {
328 var ret = [];
329 lockChildren.forEach(function (child) {
330 if (child.children) {
331 var res = loop(child.children, condition);
332 if (!res.length) {
333 ret.push(child);
334 }
335 } else {
336 var order = condition(child);
337 if (!order) {
338 ret.push(child);
339 }
340 }
341 });
342 ret.forEach(function (res) {
343 var index = lockChildren.indexOf(res);
344 lockChildren.splice(index, 1);
345 });
346 return lockChildren;
347 };
348 loop(lockLeftChildren, function (child) {
349 if (child.lock === true || child.lock === 'left') {
350 return 'left';
351 }
352 });
353 loop(lockRightChildren, function (child) {
354 if (child.lock === 'right') {
355 return 'right';
356 }
357 });
358 loop(originChildren, function (child) {
359 return child.lock !== true && child.lock !== 'left' && child.lock !== 'right';
360 });
361 return {
362 lockLeftChildren: lockLeftChildren,
363 lockRightChildren: lockRightChildren,
364 originChildren: originChildren
365 };
366 };
367
368 /**
369 * 将左侧的锁列树和中间的普通树及右侧的锁列树进行合并
370 * 会在原始 originChildren 上做改动
371 * @param {Object} splitChildren { lockLeftChildren, lockRightChildren, originChildren }
372 * @return {Array} originChildren
373 */
374
375
376 LockTable.prototype.mergeFromSplitLockChildren = function mergeFromSplitLockChildren(splitChildren, prefix) {
377 var lockLeftChildren = splitChildren.lockLeftChildren,
378 lockRightChildren = splitChildren.lockRightChildren;
379 var originChildren = splitChildren.originChildren;
380
381
382 var flatenLeftChildren = this.getFlatenChildren(lockLeftChildren);
383 var flatenRightChildren = this.getFlatenChildren(lockRightChildren);
384
385 (0, _util2.setStickyStyle)(lockLeftChildren, flatenLeftChildren, 'left', this.state.leftOffsetArr, prefix);
386 (0, _util2.setStickyStyle)(lockRightChildren, flatenRightChildren, 'right', this.state.rightOffsetArr, prefix);
387
388 return [].concat(lockLeftChildren, originChildren, lockRightChildren);
389 };
390
391 LockTable.prototype.getCellNode = function getCellNode(index, i) {
392 var table = this.tableInc;
393
394 try {
395 // in case of finding an unmounted component due to cached data
396 // need to clear refs of table when dataSource Changed
397 // use try catch for temporary
398 return (0, _reactDom.findDOMNode)(table.getCellRef(index, i));
399 } catch (error) {
400 return null;
401 }
402 };
403
404 LockTable.prototype.getTableNode = function getTableNode() {
405 var table = this.tableInc;
406 try {
407 // in case of finding an unmounted component due to cached data
408 // need to clear refs of table when dataSource Changed
409 // use try catch for temporary
410 return (0, _reactDom.findDOMNode)(table.tableEl);
411 } catch (error) {
412 return null;
413 }
414 };
415
416 LockTable.prototype.getHeaderCellNode = function getHeaderCellNode(index, i) {
417 var table = this.tableInc;
418
419 try {
420 // in case of finding an unmounted component due to cached data
421 // need to clear refs of table when dataSource Changed
422 // use try catch for temporary
423 return (0, _reactDom.findDOMNode)(table.getHeaderCellRef(index, i));
424 } catch (error) {
425 return null;
426 }
427 };
428
429 LockTable.prototype.render = function render() {
430 var _classnames;
431
432 /* eslint-disable no-unused-vars, prefer-const */
433 var _props2 = this.props,
434 children = _props2.children,
435 columns = _props2.columns,
436 prefix = _props2.prefix,
437 components = _props2.components,
438 scrollToRow = _props2.scrollToRow,
439 className = _props2.className,
440 dataSource = _props2.dataSource,
441 others = (0, _objectWithoutProperties3.default)(_props2, ['children', 'columns', 'prefix', 'components', 'scrollToRow', 'className', 'dataSource']);
442
443
444 var normalizedChildren = this.normalizeChildrenState(this.props);
445
446 components = (0, _extends3.default)({}, components);
447 components.Body = components.Body || _body2.default;
448 components.Header = components.Header || _header2.default;
449 components.Wrapper = components.Wrapper || _wrapper2.default;
450 components.Row = components.Row || _row2.default;
451 className = (0, _classnames3.default)((_classnames = {}, _classnames[prefix + 'table-lock'] = true, _classnames[prefix + 'table-stickylock'] = true, _classnames[prefix + 'table-wrap-empty'] = !dataSource.length, _classnames[className] = className, _classnames));
452
453 return _react2.default.createElement(BaseComponent, (0, _extends3.default)({}, others, {
454 dataSource: dataSource,
455 columns: normalizedChildren,
456 prefix: prefix,
457 components: components,
458 className: className
459 }));
460 };
461
462 return LockTable;
463 }(_react2.default.Component), _class.LockRow = _row2.default, _class.LockBody = _body2.default, _class.LockHeader = _header2.default, _class.propTypes = (0, _extends3.default)({
464 scrollToCol: _propTypes2.default.number,
465 /**
466 * 指定滚动到某一行,仅在`useVirtual`的时候生效
467 */
468 scrollToRow: _propTypes2.default.number
469 }, BaseComponent.propTypes), _class.defaultProps = (0, _extends3.default)({}, BaseComponent.defaultProps), _class.childContextTypes = {
470 getTableInstance: _propTypes2.default.func,
471 getLockNode: _propTypes2.default.func,
472 onLockBodyScroll: _propTypes2.default.func
473 }, _temp);
474 LockTable.displayName = 'LockTable';
475
476 (0, _util2.statics)(LockTable, BaseComponent);
477 return LockTable;
478}
479
480function deepCopy(arr) {
481 var copy = function copy(arr) {
482 return arr.map(function (item) {
483 var newItem = (0, _extends3.default)({}, item);
484 if (item.children) {
485 item.children = copy(item.children);
486 }
487 return newItem;
488 });
489 };
490 return copy(arr);
491}
492module.exports = exports['default'];
\No newline at end of file