1 | import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
|
2 | import _extends from 'babel-runtime/helpers/extends';
|
3 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
4 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
5 | import _inherits from 'babel-runtime/helpers/inherits';
|
6 | import React, { Children } from 'react';
|
7 | import { findDOMNode } from 'react-dom';
|
8 | import PropTypes from 'prop-types';
|
9 | import classnames from 'classnames';
|
10 | import shallowElementEquals from 'shallow-element-equals';
|
11 | import { log, obj, dom, events } from '../util';
|
12 | import LockRow from './lock/row';
|
13 | import LockBody from './lock/body';
|
14 | import LockHeader from './lock/header';
|
15 | import LockWrapper from './fixed/wrapper';
|
16 | import { statics, setStickyStyle } from './util';
|
17 |
|
18 | export default function stickyLock(BaseComponent) {
|
19 | var _class, _temp;
|
20 |
|
21 |
|
22 | var LockTable = (_temp = _class = function (_React$Component) {
|
23 | _inherits(LockTable, _React$Component);
|
24 |
|
25 | function LockTable(props, context) {
|
26 | _classCallCheck(this, LockTable);
|
27 |
|
28 | var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
|
29 |
|
30 | _this.state = {};
|
31 |
|
32 | _this.updateOffsetArr = function () {
|
33 | var _ref = _this.splitChildren || {},
|
34 | lockLeftChildren = _ref.lockLeftChildren,
|
35 | lockRightChildren = _ref.lockRightChildren,
|
36 | originChildren = _ref.originChildren;
|
37 |
|
38 | var leftLen = _this.getFlatenChildren(lockLeftChildren).length;
|
39 | var rightLen = _this.getFlatenChildren(lockRightChildren).length;
|
40 | var totalLen = leftLen + rightLen + _this.getFlatenChildren(originChildren).length;
|
41 |
|
42 | var hasLockLeft = leftLen > 0;
|
43 | var hasLockRight = rightLen > 0;
|
44 |
|
45 | var leftOffsetArr = _this.getStickyWidth(lockLeftChildren, 'left', totalLen);
|
46 | var rightOffsetArr = _this.getStickyWidth(lockRightChildren, 'right', totalLen);
|
47 |
|
48 | var state = {};
|
49 |
|
50 | if ('' + leftOffsetArr !== '' + _this.state.leftOffsetArr) {
|
51 | state.leftOffsetArr = leftOffsetArr;
|
52 | }
|
53 |
|
54 | if ('' + rightOffsetArr !== '' + _this.state.rightOffsetArr) {
|
55 | state.rightOffsetArr = rightOffsetArr;
|
56 | }
|
57 |
|
58 | if (hasLockLeft !== _this.state.hasLockLeft) {
|
59 | state.hasLockLeft = hasLockLeft;
|
60 | }
|
61 |
|
62 | if (hasLockRight !== _this.state.hasLockRight) {
|
63 | state.hasLockRight = hasLockRight;
|
64 | }
|
65 |
|
66 | if (Object.keys(state).length > 0) {
|
67 | _this.setState(state);
|
68 | }
|
69 | };
|
70 |
|
71 | _this.onLockBodyScroll = function (e, forceSet) {
|
72 | var _ref2 = e.currentTarget || {},
|
73 | scrollLeft = _ref2.scrollLeft,
|
74 | scrollWidth = _ref2.scrollWidth,
|
75 | clientWidth = _ref2.clientWidth;
|
76 |
|
77 | var pingRight = _this.pingRight,
|
78 | pingLeft = _this.pingLeft;
|
79 |
|
80 |
|
81 | var pingLeftNext = scrollLeft > 0 && _this.state.hasLockLeft;
|
82 | var pingRightNext = scrollLeft < scrollWidth - clientWidth && _this.state.hasLockRight;
|
83 |
|
84 | if (forceSet || pingLeft !== pingLeftNext || pingRight !== pingRightNext) {
|
85 | var prefix = _this.props.prefix;
|
86 |
|
87 | var table = _this.getTableNode();
|
88 |
|
89 | _this.pingLeft = pingLeftNext;
|
90 | _this.pingRight = pingRightNext;
|
91 |
|
92 | var leftFunc = pingLeftNext ? 'addClass' : 'removeClass';
|
93 | dom[leftFunc](table, prefix + 'table-ping-left');
|
94 | var rightFunc = pingRightNext ? 'addClass' : 'removeClass';
|
95 | dom[rightFunc](table, prefix + 'table-ping-right');
|
96 | }
|
97 | };
|
98 |
|
99 | _this.getStickyWidth = function (lockChildren, dir, totalLen) {
|
100 | var _this$props = _this.props,
|
101 | dataSource = _this$props.dataSource,
|
102 | scrollToRow = _this$props.scrollToRow;
|
103 |
|
104 | var offsetArr = [];
|
105 | var flatenChildren = _this.getFlatenChildren(lockChildren);
|
106 | var len = flatenChildren.length;
|
107 |
|
108 | flatenChildren.reduce(function (ret, col, index) {
|
109 | var tag = dir === 'left' ? index : len - 1 - index;
|
110 | var tagNext = dir === 'left' ? tag - 1 : tag + 1;
|
111 | var nodeToGetWidth = dir === 'left' ? tag - 1 : totalLen - index;
|
112 |
|
113 | if (dir === 'left' && tag === 0) {
|
114 | ret[0] = 0;
|
115 | return ret;
|
116 | } else if (dir === 'right' && tag === len - 1) {
|
117 | ret[tag] = 0;
|
118 | return ret;
|
119 | }
|
120 |
|
121 |
|
122 | var isEmpty = !(dataSource && dataSource.length > 0);
|
123 |
|
124 | var node = isEmpty ? _this.getHeaderCellNode(0, nodeToGetWidth) : _this.getCellNode(scrollToRow || dataSource[0] && dataSource[0].__rowIndex || 0, nodeToGetWidth);
|
125 | var colWidth = node && parseFloat(getComputedStyle(node).width) || 0;
|
126 |
|
127 | ret[tag] = (ret[tagNext] || 0) + colWidth;
|
128 | return ret;
|
129 | }, offsetArr);
|
130 |
|
131 | return offsetArr;
|
132 | };
|
133 |
|
134 | _this.getTableInstance = function (type, instance) {
|
135 | type = '';
|
136 | _this['table' + type + 'Inc'] = instance;
|
137 | };
|
138 |
|
139 | _this.getNode = function (type, node) {
|
140 | _this[type + 'Node'] = node;
|
141 | };
|
142 |
|
143 | _this.getFlatenChildren = function () {
|
144 | var children = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
145 |
|
146 | var loop = function loop(arr) {
|
147 | var newArray = [];
|
148 | arr.forEach(function (child) {
|
149 | if (child.children) {
|
150 | newArray.push.apply(newArray, loop(child.children));
|
151 | } else {
|
152 | newArray.push(child);
|
153 | }
|
154 | });
|
155 | return newArray;
|
156 | };
|
157 |
|
158 | return loop(children);
|
159 | };
|
160 |
|
161 | _this.state = {
|
162 | hasLockLeft: true,
|
163 | hasLockRight: true
|
164 | };
|
165 |
|
166 | _this.pingLeft = false;
|
167 | _this.pingRight = false;
|
168 | return _this;
|
169 | }
|
170 |
|
171 | LockTable.prototype.getChildContext = function getChildContext() {
|
172 | return {
|
173 | getTableInstance: this.getTableInstance,
|
174 | getLockNode: this.getNode,
|
175 | onLockBodyScroll: this.onLockBodyScroll
|
176 | };
|
177 | };
|
178 |
|
179 | LockTable.prototype.componentDidMount = function componentDidMount() {
|
180 | var dataSource = this.props.dataSource;
|
181 |
|
182 | var isEmpty = !(dataSource && dataSource.length > 0);
|
183 |
|
184 | this.updateOffsetArr();
|
185 | this.onLockBodyScroll(isEmpty ? { currentTarget: this.headerNode } : { currentTarget: this.bodyNode });
|
186 | this.forceUpdate();
|
187 |
|
188 | events.on(window, 'resize', this.updateOffsetArr);
|
189 | };
|
190 |
|
191 | LockTable.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState, nextContext) {
|
192 | if (nextProps.pure) {
|
193 | var isEqual = shallowElementEquals(nextProps, this.props);
|
194 | return !(isEqual && obj.shallowEqual(nextContext, this.context));
|
195 | }
|
196 |
|
197 | return true;
|
198 | };
|
199 |
|
200 | LockTable.prototype.componentDidUpdate = function componentDidUpdate() {
|
201 | this.updateOffsetArr();
|
202 | this.onLockBodyScroll(this.bodyNode ? { currentTarget: this.bodyNode } : { currentTarget: this.headerNode }, true);
|
203 | };
|
204 |
|
205 | LockTable.prototype.componentWillUnmount = function componentWillUnmount() {
|
206 | this.pingLeft = false;
|
207 | this.pingRight = false;
|
208 | events.off(window, 'resize', this.updateOffsetArr);
|
209 | };
|
210 |
|
211 | LockTable.prototype.normalizeChildrenState = function normalizeChildrenState(props) {
|
212 | var columns = this.normalizeChildren(props);
|
213 |
|
214 | this.splitChildren = this.splitFromNormalizeChildren(columns);
|
215 |
|
216 | return this.mergeFromSplitLockChildren(this.splitChildren, props.prefix);
|
217 | };
|
218 |
|
219 |
|
220 |
|
221 |
|
222 | LockTable.prototype.normalizeChildren = function normalizeChildren(props) {
|
223 | var children = props.children,
|
224 | columns = props.columns;
|
225 |
|
226 | var isLock = false,
|
227 | ret = void 0;
|
228 | var getChildren = function getChildren(children) {
|
229 | var ret = [];
|
230 | Children.forEach(children, function (child) {
|
231 | if (child) {
|
232 | var _props = _extends({}, child.props);
|
233 | if ([true, 'left', 'right'].indexOf(_props.lock) > -1) {
|
234 | isLock = true;
|
235 | if (!('width' in _props)) {
|
236 | log.warning('Should config width for lock column named [ ' + _props.dataIndex + ' ].');
|
237 | }
|
238 | }
|
239 | ret.push(_props);
|
240 | if (child.props.children) {
|
241 | _props.children = getChildren(child.props.children);
|
242 | }
|
243 | }
|
244 | });
|
245 | return ret;
|
246 | };
|
247 |
|
248 | if (columns && !children) {
|
249 | ret = columns;
|
250 | isLock = columns.find(function (record) {
|
251 | return [true, 'left', 'right'].indexOf(record.lock) > -1;
|
252 | });
|
253 | } else {
|
254 | ret = getChildren(children);
|
255 | }
|
256 | ret.forEach(function (child) {
|
257 |
|
258 | if (child.__normalized && isLock) {
|
259 |
|
260 | child.lock = child.lock || 'left';
|
261 | delete child.__normalized;
|
262 | }
|
263 | });
|
264 | return ret;
|
265 | };
|
266 |
|
267 | |
268 |
|
269 |
|
270 |
|
271 |
|
272 |
|
273 |
|
274 | LockTable.prototype.splitFromNormalizeChildren = function splitFromNormalizeChildren(children) {
|
275 | var originChildren = deepCopy(children);
|
276 | var lockLeftChildren = deepCopy(children);
|
277 | var lockRightChildren = deepCopy(children);
|
278 | var loop = function loop(lockChildren, condition) {
|
279 | var ret = [];
|
280 | lockChildren.forEach(function (child) {
|
281 | if (child.children) {
|
282 | var res = loop(child.children, condition);
|
283 | if (!res.length) {
|
284 | ret.push(child);
|
285 | }
|
286 | } else {
|
287 | var order = condition(child);
|
288 | if (!order) {
|
289 | ret.push(child);
|
290 | }
|
291 | }
|
292 | });
|
293 | ret.forEach(function (res) {
|
294 | var index = lockChildren.indexOf(res);
|
295 | lockChildren.splice(index, 1);
|
296 | });
|
297 | return lockChildren;
|
298 | };
|
299 | loop(lockLeftChildren, function (child) {
|
300 | if (child.lock === true || child.lock === 'left') {
|
301 | return 'left';
|
302 | }
|
303 | });
|
304 | loop(lockRightChildren, function (child) {
|
305 | if (child.lock === 'right') {
|
306 | return 'right';
|
307 | }
|
308 | });
|
309 | loop(originChildren, function (child) {
|
310 | return child.lock !== true && child.lock !== 'left' && child.lock !== 'right';
|
311 | });
|
312 | return {
|
313 | lockLeftChildren: lockLeftChildren,
|
314 | lockRightChildren: lockRightChildren,
|
315 | originChildren: originChildren
|
316 | };
|
317 | };
|
318 |
|
319 | |
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 | LockTable.prototype.mergeFromSplitLockChildren = function mergeFromSplitLockChildren(splitChildren, prefix) {
|
328 | var lockLeftChildren = splitChildren.lockLeftChildren,
|
329 | lockRightChildren = splitChildren.lockRightChildren;
|
330 | var originChildren = splitChildren.originChildren;
|
331 |
|
332 |
|
333 | var flatenLeftChildren = this.getFlatenChildren(lockLeftChildren);
|
334 | var flatenRightChildren = this.getFlatenChildren(lockRightChildren);
|
335 |
|
336 | setStickyStyle(lockLeftChildren, flatenLeftChildren, 'left', this.state.leftOffsetArr, prefix);
|
337 | setStickyStyle(lockRightChildren, flatenRightChildren, 'right', this.state.rightOffsetArr, prefix);
|
338 |
|
339 | return [].concat(lockLeftChildren, originChildren, lockRightChildren);
|
340 | };
|
341 |
|
342 | LockTable.prototype.getCellNode = function getCellNode(index, i) {
|
343 | var table = this.tableInc;
|
344 |
|
345 | try {
|
346 |
|
347 |
|
348 |
|
349 | return findDOMNode(table.getCellRef(index, i));
|
350 | } catch (error) {
|
351 | return null;
|
352 | }
|
353 | };
|
354 |
|
355 | LockTable.prototype.getTableNode = function getTableNode() {
|
356 | var table = this.tableInc;
|
357 | try {
|
358 |
|
359 |
|
360 |
|
361 | return findDOMNode(table.tableEl);
|
362 | } catch (error) {
|
363 | return null;
|
364 | }
|
365 | };
|
366 |
|
367 | LockTable.prototype.getHeaderCellNode = function getHeaderCellNode(index, i) {
|
368 | var table = this.tableInc;
|
369 |
|
370 | try {
|
371 |
|
372 |
|
373 |
|
374 | return findDOMNode(table.getHeaderCellRef(index, i));
|
375 | } catch (error) {
|
376 | return null;
|
377 | }
|
378 | };
|
379 |
|
380 | LockTable.prototype.render = function render() {
|
381 | var _classnames;
|
382 |
|
383 |
|
384 | var _props2 = this.props,
|
385 | children = _props2.children,
|
386 | columns = _props2.columns,
|
387 | prefix = _props2.prefix,
|
388 | components = _props2.components,
|
389 | scrollToRow = _props2.scrollToRow,
|
390 | className = _props2.className,
|
391 | dataSource = _props2.dataSource,
|
392 | others = _objectWithoutProperties(_props2, ['children', 'columns', 'prefix', 'components', 'scrollToRow', 'className', 'dataSource']);
|
393 |
|
394 | var normalizedChildren = this.normalizeChildrenState(this.props);
|
395 |
|
396 | components = _extends({}, components);
|
397 | components.Body = components.Body || LockBody;
|
398 | components.Header = components.Header || LockHeader;
|
399 | components.Wrapper = components.Wrapper || LockWrapper;
|
400 | components.Row = components.Row || LockRow;
|
401 | className = classnames((_classnames = {}, _classnames[prefix + 'table-lock'] = true, _classnames[prefix + 'table-stickylock'] = true, _classnames[prefix + 'table-wrap-empty'] = !dataSource.length, _classnames[className] = className, _classnames));
|
402 |
|
403 | return React.createElement(BaseComponent, _extends({}, others, {
|
404 | dataSource: dataSource,
|
405 | columns: normalizedChildren,
|
406 | prefix: prefix,
|
407 | components: components,
|
408 | className: className
|
409 | }));
|
410 | };
|
411 |
|
412 | return LockTable;
|
413 | }(React.Component), _class.LockRow = LockRow, _class.LockBody = LockBody, _class.LockHeader = LockHeader, _class.propTypes = _extends({
|
414 | scrollToCol: PropTypes.number,
|
415 | |
416 |
|
417 |
|
418 | scrollToRow: PropTypes.number
|
419 | }, BaseComponent.propTypes), _class.defaultProps = _extends({}, BaseComponent.defaultProps), _class.childContextTypes = {
|
420 | getTableInstance: PropTypes.func,
|
421 | getLockNode: PropTypes.func,
|
422 | onLockBodyScroll: PropTypes.func
|
423 | }, _temp);
|
424 | LockTable.displayName = 'LockTable';
|
425 |
|
426 | statics(LockTable, BaseComponent);
|
427 | return LockTable;
|
428 | }
|
429 |
|
430 | function deepCopy(arr) {
|
431 | var copy = function copy(arr) {
|
432 | return arr.map(function (item) {
|
433 | var newItem = _extends({}, item);
|
434 | if (item.children) {
|
435 | item.children = copy(item.children);
|
436 | }
|
437 | return newItem;
|
438 | });
|
439 | };
|
440 | return copy(arr);
|
441 | } |
\ | No newline at end of file |