UNPKG

14.1 kBJavaScriptView Raw
1import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
2import _extends from 'babel-runtime/helpers/extends';
3import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
4import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
5import _inherits from 'babel-runtime/helpers/inherits';
6import React, { Children } from 'react';
7import { findDOMNode } from 'react-dom';
8import PropTypes from 'prop-types';
9import classnames from 'classnames';
10import { polyfill } from 'react-lifecycles-compat';
11import Icon from '../icon';
12import { KEYCODE, dom, events } from '../util';
13import RowComponent from './expanded/row';
14import Col from './column';
15import { statics } from './util';
16
17var noop = function noop() {};
18
19export default function expanded(BaseComponent, stickyLock) {
20 var _class, _temp2;
21
22 /** Table */
23 var ExpandedTable = (_temp2 = _class = function (_React$Component) {
24 _inherits(ExpandedTable, _React$Component);
25
26 function ExpandedTable() {
27 var _temp, _this, _ret;
28
29 _classCallCheck(this, ExpandedTable);
30
31 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
32 args[_key] = arguments[_key];
33 }
34
35 return _ret = (_temp = (_this = _possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.state = {
36 openRowKeys: _this.props.openRowKeys || _this.props.defaultOpenRowKeys || []
37 }, _this.saveExpandedRowRef = function (key, rowRef) {
38 if (!_this.expandedRowRefs) {
39 _this.expandedRowRefs = {};
40 }
41 _this.expandedRowRefs[key] = rowRef;
42 }, _this.setExpandedWidth = function () {
43 var prefix = _this.props.prefix;
44
45 var tableEl = _this.getTableNode();
46 var totalWidth = +(tableEl && tableEl.clientWidth) - 1 || '100%';
47 var bodyNode = tableEl && tableEl.querySelector('.' + prefix + 'table-body');
48
49 Object.keys(_this.expandedRowRefs || {}).forEach(function (key) {
50 dom.setStyle(_this.expandedRowRefs[key], { width: bodyNode && bodyNode.clientWidth || totalWidth });
51 });
52 }, _this.getTableInstance = function (instance) {
53 _this.tableInc = instance;
54 }, _this.expandedKeydown = function (value, record, index, e) {
55 e.preventDefault();
56 e.stopPropagation();
57
58 if (e.keyCode === KEYCODE.ENTER) {
59 _this.onExpandedClick(value, record, index, e);
60 }
61 }, _this.renderExpandedCell = function (value, index, record) {
62 var _classnames;
63
64 var _this$props = _this.props,
65 getExpandedColProps = _this$props.getExpandedColProps,
66 prefix = _this$props.prefix,
67 locale = _this$props.locale,
68 rowExpandable = _this$props.rowExpandable;
69
70
71 if (typeof rowExpandable === 'function' && !rowExpandable(record, index)) {
72 return '';
73 }
74
75 var openRowKeys = _this.state.openRowKeys,
76 primaryKey = _this.props.primaryKey,
77 hasExpanded = openRowKeys.indexOf(record[primaryKey]) > -1,
78 switchNode = hasExpanded ? React.createElement(Icon, { type: 'minus', size: 'xs', className: prefix + 'table-expand-unfold' }) : React.createElement(Icon, { type: 'add', size: 'xs', className: prefix + 'table-expand-fold' }),
79 attrs = getExpandedColProps(record, index) || {};
80
81 var cls = classnames((_classnames = {}, _classnames[prefix + 'table-expanded-ctrl'] = true, _classnames.disabled = attrs.disabled, _classnames[attrs.className] = attrs.className, _classnames));
82
83 if (!attrs.disabled) {
84 attrs.onClick = _this.onExpandedClick.bind(_this, value, record, index);
85 }
86 return React.createElement(
87 'span',
88 _extends({}, attrs, {
89 role: 'button',
90 tabIndex: '0',
91 onKeyDown: _this.expandedKeydown.bind(_this, value, record, index),
92 'aria-label': hasExpanded ? locale.expanded : locale.folded,
93 'aria-expanded': hasExpanded,
94 className: cls
95 }),
96 switchNode
97 );
98 }, _this.addExpandCtrl = function (columns) {
99 var _this$props2 = _this.props,
100 prefix = _this$props2.prefix,
101 size = _this$props2.size;
102
103
104 if (!columns.find(function (record) {
105 return record.key === 'expanded';
106 })) {
107 columns.unshift({
108 key: 'expanded',
109 title: '',
110 cell: _this.renderExpandedCell.bind(_this),
111 width: size === 'small' ? 34 : 50,
112 className: prefix + 'table-expanded ' + prefix + 'table-prerow',
113 __normalized: true
114 });
115 }
116 }, _temp), _possibleConstructorReturn(_this, _ret);
117 }
118
119 ExpandedTable.prototype.getChildContext = function getChildContext() {
120 return {
121 openRowKeys: this.state.openRowKeys,
122 expandedRowRender: this.props.expandedRowRender,
123 expandedIndexSimulate: this.props.expandedIndexSimulate,
124 expandedRowWidthEquals2Table: stickyLock,
125 getExpandedRowRef: this.saveExpandedRowRef,
126 getTableInstanceForExpand: this.getTableInstance,
127 expandedRowIndent: stickyLock ? [0, 0] : this.props.expandedRowIndent
128 };
129 };
130
131 ExpandedTable.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps) {
132 if ('openRowKeys' in nextProps) {
133 return {
134 openRowKeys: nextProps.openRowKeys || []
135 };
136 }
137
138 return null;
139 };
140
141 ExpandedTable.prototype.componentDidMount = function componentDidMount() {
142 this.setExpandedWidth();
143 events.on(window, 'resize', this.setExpandedWidth);
144 };
145
146 ExpandedTable.prototype.componentDidUpdate = function componentDidUpdate() {
147 this.setExpandedWidth();
148 };
149
150 ExpandedTable.prototype.componentWillUnmount = function componentWillUnmount() {
151 events.off(window, 'resize', this.setExpandedWidth);
152 };
153
154 ExpandedTable.prototype.getTableNode = function getTableNode() {
155 var table = this.tableInc;
156 try {
157 // in case of finding an unmounted component due to cached data
158 // need to clear refs of table when dataSource Changed
159 // use try catch for temporary
160 return findDOMNode(table.tableEl);
161 } catch (error) {
162 return null;
163 }
164 };
165
166 ExpandedTable.prototype.onExpandedClick = function onExpandedClick(value, record, i, e) {
167 var openRowKeys = [].concat(this.state.openRowKeys),
168 primaryKey = this.props.primaryKey,
169 id = record[primaryKey],
170 index = openRowKeys.indexOf(id);
171
172 if (index > -1) {
173 openRowKeys.splice(index, 1);
174 } else {
175 openRowKeys.push(id);
176 }
177 if (!('openRowKeys' in this.props)) {
178 this.setState({
179 openRowKeys: openRowKeys
180 });
181 }
182 this.props.onRowOpen(openRowKeys, id, index === -1, record);
183 e.stopPropagation();
184 };
185
186 ExpandedTable.prototype.normalizeChildren = function normalizeChildren(children) {
187 var _props = this.props,
188 prefix = _props.prefix,
189 size = _props.size;
190
191 var toArrayChildren = Children.map(children, function (child, index) {
192 return React.cloneElement(child, {
193 key: index
194 });
195 });
196 toArrayChildren.unshift(React.createElement(Col, {
197 title: '',
198 key: 'expanded',
199 cell: this.renderExpandedCell.bind(this),
200 width: size === 'small' ? 34 : 50,
201 className: prefix + 'table-expanded ' + prefix + 'table-prerow',
202 __normalized: true
203 }));
204 return toArrayChildren;
205 };
206
207 ExpandedTable.prototype.normalizeDataSource = function normalizeDataSource(ds) {
208 var ret = [];
209 ds.forEach(function (item) {
210 var itemCopy = _extends({}, item);
211 itemCopy.__expanded = true;
212 ret.push(item, itemCopy);
213 });
214 return ret;
215 };
216
217 ExpandedTable.prototype.render = function render() {
218 /* eslint-disable no-unused-vars, prefer-const */
219 var _props2 = this.props,
220 components = _props2.components,
221 openRowKeys = _props2.openRowKeys,
222 expandedRowRender = _props2.expandedRowRender,
223 rowExpandable = _props2.rowExpandable,
224 hasExpandedRowCtrl = _props2.hasExpandedRowCtrl,
225 children = _props2.children,
226 columns = _props2.columns,
227 dataSource = _props2.dataSource,
228 entireDataSource = _props2.entireDataSource,
229 getExpandedColProps = _props2.getExpandedColProps,
230 expandedRowIndent = _props2.expandedRowIndent,
231 onRowOpen = _props2.onRowOpen,
232 onExpandedRowClick = _props2.onExpandedRowClick,
233 others = _objectWithoutProperties(_props2, ['components', 'openRowKeys', 'expandedRowRender', 'rowExpandable', 'hasExpandedRowCtrl', 'children', 'columns', 'dataSource', 'entireDataSource', 'getExpandedColProps', 'expandedRowIndent', 'onRowOpen', 'onExpandedRowClick']);
234
235 if (expandedRowRender && !components.Row) {
236 components = _extends({}, components);
237 components.Row = RowComponent;
238 dataSource = this.normalizeDataSource(dataSource);
239 entireDataSource = this.normalizeDataSource(entireDataSource);
240 }
241 if (expandedRowRender && hasExpandedRowCtrl) {
242 var useColumns = columns && !children;
243
244 if (useColumns) {
245 this.addExpandCtrl(columns);
246 } else {
247 children = this.normalizeChildren(children || []);
248 }
249 }
250
251 return React.createElement(
252 BaseComponent,
253 _extends({}, others, {
254 columns: columns,
255 dataSource: dataSource,
256 entireDataSource: entireDataSource,
257 components: components
258 }),
259 children
260 );
261 };
262
263 return ExpandedTable;
264 }(React.Component), _class.ExpandedRow = RowComponent, _class.propTypes = _extends({
265 /**
266 * 额外渲染行的渲染函数
267 * @param {Object} record 该行所对应的数据
268 * @param {Number} index 该行所对应的序列
269 * @returns {Element}
270 */
271 expandedRowRender: PropTypes.func,
272 /**
273 * 设置行是否可展开,设置 false 为不可展开
274 * @param {Object} record 该行所对应的数据
275 * @param {Number} index 该行所对应的序列
276 * @returns {Boolean} 是否可展开
277 * @version 1.21
278 */
279 rowExpandable: PropTypes.func,
280 /**
281 * 额外渲染行的缩进
282 */
283 expandedRowIndent: PropTypes.array,
284 /**
285 * 默认情况下展开的渲染行或者Tree, 传入此属性为受控状态
286 */
287 openRowKeys: PropTypes.array,
288 /**
289 * 默认情况下展开的 Expand行 或者 Tree行,非受控模式
290 * @version 1.23.22
291 */
292 defaultOpenRowKeys: PropTypes.array,
293 /**
294 * 是否显示点击展开额外渲染行的+号按钮
295 */
296 hasExpandedRowCtrl: PropTypes.bool,
297 /**
298 * 设置额外渲染行的属性
299 */
300 getExpandedColProps: PropTypes.func,
301 /**
302 * 在额外渲染行或者Tree展开或者收起的时候触发的事件
303 * @param {Array} openRowKeys 展开的渲染行的key
304 * @param {String} currentRowKey 当前点击的渲染行的key
305 * @param {Boolean} expanded 当前点击是展开还是收起
306 * @param {Object} currentRecord 当前点击额外渲染行的记录
307 */
308 onRowOpen: PropTypes.func,
309 onExpandedRowClick: PropTypes.func,
310 locale: PropTypes.object
311 }, BaseComponent.propTypes), _class.defaultProps = _extends({}, BaseComponent.defaultProps, {
312 getExpandedColProps: noop,
313 onRowOpen: noop,
314 hasExpandedRowCtrl: true,
315 components: {},
316 expandedRowIndent: stickyLock ? [0, 0] : [1, 0],
317 prefix: 'next-'
318 }), _class.childContextTypes = {
319 openRowKeys: PropTypes.array,
320 expandedRowRender: PropTypes.func,
321 expandedIndexSimulate: PropTypes.bool,
322 expandedRowWidthEquals2Table: PropTypes.bool,
323 expandedRowIndent: PropTypes.array,
324 getExpandedRowRef: PropTypes.func,
325 getTableInstanceForExpand: PropTypes.func
326 }, _temp2);
327 ExpandedTable.displayName = 'ExpandedTable';
328
329 statics(ExpandedTable, BaseComponent);
330 return polyfill(ExpandedTable);
331}
\No newline at end of file