UNPKG

17.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 = selection;
26
27var _react = require('react');
28
29var _react2 = _interopRequireDefault(_react);
30
31var _propTypes = require('prop-types');
32
33var _propTypes2 = _interopRequireDefault(_propTypes);
34
35var _reactLifecyclesCompat = require('react-lifecycles-compat');
36
37var _checkbox = require('../checkbox');
38
39var _checkbox2 = _interopRequireDefault(_checkbox);
40
41var _radio = require('../radio');
42
43var _radio2 = _interopRequireDefault(_radio);
44
45var _util = require('../util');
46
47var _zhCn = require('../locale/zh-cn');
48
49var _zhCn2 = _interopRequireDefault(_zhCn);
50
51var _row = require('./selection/row');
52
53var _row2 = _interopRequireDefault(_row);
54
55var _column = require('./column');
56
57var _column2 = _interopRequireDefault(_column);
58
59var _util2 = require('./util');
60
61function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
62
63var makeChain = _util.func.makeChain;
64
65
66var unique = function unique(arr) {
67 var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'this';
68
69 var temp = {},
70 ret = [];
71 arr.forEach(function (item) {
72 var value = void 0;
73 if (key === 'this') {
74 value = item;
75 } else {
76 value = item[key];
77 }
78 if (!temp[value]) {
79 ret.push(item);
80 temp[value] = true;
81 }
82 });
83 return ret;
84};
85
86function selection(BaseComponent) {
87 var _class, _temp;
88
89 /** Table */
90 var SelectionTable = (_temp = _class = function (_React$Component) {
91 (0, _inherits3.default)(SelectionTable, _React$Component);
92
93 function SelectionTable(props, context) {
94 (0, _classCallCheck3.default)(this, SelectionTable);
95
96 var _this = (0, _possibleConstructorReturn3.default)(this, _React$Component.call(this, props, context));
97
98 _this.addSelection = function (columns) {
99 var _this$props = _this.props,
100 prefix = _this$props.prefix,
101 rowSelection = _this$props.rowSelection,
102 size = _this$props.size;
103
104 var attrs = rowSelection.columnProps && rowSelection.columnProps() || {};
105
106 if (!columns.find(function (record) {
107 return record.key === 'selection';
108 })) {
109 columns.unshift((0, _extends3.default)({
110 key: 'selection',
111 title: _this.renderSelectionHeader.bind(_this),
112 cell: _this.renderSelectionBody.bind(_this),
113 width: size === 'small' ? 34 : 50,
114 className: prefix + 'table-selection ' + prefix + 'table-prerow',
115 __normalized: true
116 }, attrs));
117 }
118 };
119
120 _this.renderSelectionHeader = function () {
121 var onChange = _this.selectAllRow,
122 attrs = {},
123 _this$props2 = _this.props,
124 rowSelection = _this$props2.rowSelection,
125 primaryKey = _this$props2.primaryKey,
126 dataSource = _this$props2.dataSource,
127 entireDataSource = _this$props2.entireDataSource,
128 locale = _this$props2.locale,
129 selectedRowKeys = _this.state.selectedRowKeys,
130 mode = rowSelection.mode ? rowSelection.mode : 'multiple';
131
132
133 var checked = !!selectedRowKeys.length;
134 var indeterminate = false;
135
136 var source = entireDataSource || dataSource;
137
138 _this.flatDataSource(source).filter(function (record, index) {
139 if (!rowSelection.getProps) {
140 return true;
141 } else {
142 return !(rowSelection.getProps(record, index) || {}).disabled;
143 }
144 }).map(function (record) {
145 return record[primaryKey];
146 }).forEach(function (id) {
147 if (selectedRowKeys.indexOf(id) === -1) {
148 checked = false;
149 } else {
150 indeterminate = true;
151 }
152 });
153 attrs.onClick = makeChain(function (e) {
154 e.stopPropagation();
155 }, attrs.onClick);
156
157 var userAttrs = rowSelection.titleProps && rowSelection.titleProps() || {};
158
159 if (checked) {
160 indeterminate = false;
161 }
162 return [mode === 'multiple' ? _react2.default.createElement(_checkbox2.default, (0, _extends3.default)({
163 key: '_total',
164 indeterminate: indeterminate,
165 'aria-label': locale.selectAll,
166 checked: checked,
167 onChange: onChange
168 }, attrs, userAttrs)) : null, rowSelection.titleAddons && rowSelection.titleAddons()];
169 };
170
171 _this.renderSelectionBody = function (value, index, record) {
172 var _this$props3 = _this.props,
173 rowSelection = _this$props3.rowSelection,
174 primaryKey = _this$props3.primaryKey;
175 var selectedRowKeys = _this.state.selectedRowKeys;
176
177 var mode = rowSelection.mode ? rowSelection.mode : 'multiple';
178 var checked = selectedRowKeys.indexOf(record[primaryKey]) > -1;
179 var onChange = _this.selectOneRow.bind(_this, index, record);
180 var attrs = rowSelection.getProps ? rowSelection.getProps(record, index) || {} : {};
181
182 attrs.onClick = makeChain(function (e) {
183 e.stopPropagation();
184 }, attrs.onClick);
185 return mode === 'multiple' ? _react2.default.createElement(_checkbox2.default, (0, _extends3.default)({ checked: checked, onChange: onChange }, attrs)) : _react2.default.createElement(_radio2.default, (0, _extends3.default)({ checked: checked, onChange: onChange }, attrs));
186 };
187
188 _this.selectAllRow = function (checked, e) {
189 var ret = [].concat(_this.state.selectedRowKeys),
190 _this$props4 = _this.props,
191 rowSelection = _this$props4.rowSelection,
192 primaryKey = _this$props4.primaryKey,
193 dataSource = _this$props4.dataSource,
194 entireDataSource = _this$props4.entireDataSource,
195 selectedRowKeys = _this.state.selectedRowKeys,
196 getProps = rowSelection.getProps;
197
198 var attrs = {},
199 records = [];
200
201 var source = entireDataSource ? entireDataSource : dataSource;
202
203 _this.flatDataSource(source).forEach(function (record, index) {
204 var id = record[primaryKey];
205 if (getProps) {
206 attrs = getProps(record, index) || {};
207 }
208 // 反选和全选的时候不要丢弃禁用项的选中状态
209 if (checked && (!attrs.disabled || selectedRowKeys.indexOf(id) > -1)) {
210 ret.push(id);
211 records.push(record);
212 } else if (attrs.disabled && selectedRowKeys.indexOf(id) > -1) {
213 ret.push(id);
214 records.push(record);
215 } else {
216 var i = ret.indexOf(id);
217 i > -1 && ret.splice(i, 1);
218 }
219 });
220
221 records = unique(records, primaryKey);
222 if (typeof rowSelection.onSelectAll === 'function') {
223 rowSelection.onSelectAll(checked, records);
224 }
225 _this.triggerSelection(rowSelection, unique(ret), records);
226 e.stopPropagation();
227 };
228
229 _this.state = {
230 selectedRowKeys: props.rowSelection && 'selectedRowKeys' in props.rowSelection ? props.rowSelection.selectedRowKeys || [] : []
231 };
232 return _this;
233 }
234
235 SelectionTable.prototype.getChildContext = function getChildContext() {
236 return {
237 rowSelection: this.props.rowSelection,
238 selectedRowKeys: this.state.selectedRowKeys
239 };
240 };
241
242 SelectionTable.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps) {
243 if (nextProps.rowSelection && 'selectedRowKeys' in nextProps.rowSelection) {
244 var selectedRowKeys = nextProps.rowSelection.selectedRowKeys || [];
245 return {
246 selectedRowKeys: selectedRowKeys
247 };
248 }
249
250 return null;
251 };
252
253 SelectionTable.prototype.normalizeChildren = function normalizeChildren(children) {
254 var _props = this.props,
255 prefix = _props.prefix,
256 rowSelection = _props.rowSelection,
257 size = _props.size;
258
259 if (rowSelection) {
260 children = _react.Children.map(children, function (child, index) {
261 return _react2.default.cloneElement(child, {
262 key: index
263 });
264 });
265
266 var attrs = rowSelection.columnProps && rowSelection.columnProps() || {};
267
268 children.unshift(_react2.default.createElement(_column2.default, (0, _extends3.default)({
269 key: 'selection',
270 title: this.renderSelectionHeader.bind(this),
271 cell: this.renderSelectionBody.bind(this),
272 width: size === 'small' ? 34 : 50,
273 className: prefix + 'table-selection ' + prefix + 'table-prerow',
274 __normalized: true
275 }, attrs)));
276 return children;
277 }
278 return children;
279 };
280
281 SelectionTable.prototype.selectOneRow = function selectOneRow(index, record, checked, e) {
282 var selectedRowKeys = [].concat(this.state.selectedRowKeys),
283 i = void 0;
284 var _props2 = this.props,
285 primaryKey = _props2.primaryKey,
286 rowSelection = _props2.rowSelection,
287 dataSource = _props2.dataSource,
288 entireDataSource = _props2.entireDataSource,
289 mode = rowSelection.mode ? rowSelection.mode : 'multiple',
290 id = record[primaryKey];
291
292 if (!id) {
293 _util.log.warning('Can\'t get value from record using given ' + primaryKey + ' as primaryKey.');
294 }
295 if (mode === 'multiple') {
296 if (checked) {
297 selectedRowKeys.push(id);
298 } else {
299 i = selectedRowKeys.indexOf(id);
300 selectedRowKeys.splice(i, 1);
301 }
302 } else if (checked) {
303 selectedRowKeys = [id];
304 }
305 var totalDS = dataSource;
306 if (Array.isArray(entireDataSource) && entireDataSource.length > dataSource.length) {
307 totalDS = entireDataSource;
308 }
309 var records = unique(totalDS.filter(function (item) {
310 return selectedRowKeys.indexOf(item[primaryKey]) > -1;
311 }), primaryKey);
312 if (typeof rowSelection.onSelect === 'function') {
313 rowSelection.onSelect(checked, record, records);
314 }
315
316 this.triggerSelection(rowSelection, selectedRowKeys, records);
317
318 e.stopPropagation();
319 };
320
321 SelectionTable.prototype.triggerSelection = function triggerSelection(rowSelection, selectedRowKeys, records) {
322 if (!('selectedRowKeys' in rowSelection)) {
323 this.setState({
324 selectedRowKeys: selectedRowKeys
325 });
326 }
327 if (typeof rowSelection.onChange === 'function') {
328 rowSelection.onChange(selectedRowKeys, records);
329 }
330 };
331
332 SelectionTable.prototype.flatDataSource = function flatDataSource(dataSource) {
333 var ret = dataSource;
334 var listHeader = this.context.listHeader;
335
336
337 if (listHeader) {
338 ret = [];
339 var hasChildrenSelection = listHeader.hasChildrenSelection,
340 hasSelection = listHeader.hasSelection;
341
342 dataSource.forEach(function (item) {
343 var children = item.children;
344 // 如果需要渲染selection才将这条记录插入到dataSource
345 // 或者没有孩子节点
346 if (hasSelection) {
347 ret.push(item);
348 }
349 if (children && hasChildrenSelection) {
350 ret = ret.concat(children);
351 }
352 });
353 }
354 return ret;
355 };
356
357 SelectionTable.prototype.render = function render() {
358 /* eslint-disable prefer-const */
359 var _props3 = this.props,
360 rowSelection = _props3.rowSelection,
361 components = _props3.components,
362 children = _props3.children,
363 columns = _props3.columns,
364 others = (0, _objectWithoutProperties3.default)(_props3, ['rowSelection', 'components', 'children', 'columns']);
365
366 var useColumns = columns && !children;
367
368 if (rowSelection) {
369 if (useColumns) {
370 this.addSelection(columns);
371 } else {
372 children = this.normalizeChildren(children || []);
373 }
374 components = (0, _extends3.default)({}, components);
375 components.Row = components.Row || _row2.default;
376 }
377 return _react2.default.createElement(BaseComponent, (0, _extends3.default)({}, others, { columns: columns, components: components, children: children }));
378 };
379
380 return SelectionTable;
381 }(_react2.default.Component), _class.SelectionRow = _row2.default, _class.propTypes = (0, _extends3.default)({
382 /**
383 * 是否启用选择模式
384 * @property {Function} getProps `Function(record, index)=>Object` 获取selection的默认属性
385 * @property {Function} onChange `Function(selectedRowKeys:Array, records:Array)` 选择改变的时候触发的事件,**注意:** 其中records只会包含当前dataSource的数据,很可能会小于selectedRowKeys的长度。
386 * @property {Function} onSelect `Function(selected:Boolean, record:Object, records:Array)` 用户手动选择/取消选择某行的回调
387 * @property {Function} onSelectAll `Function(selected:Boolean, records:Array)` 用户手动选择/取消选择所有行的回调
388 * @property {Array} selectedRowKeys 设置了此属性,将rowSelection变为受控状态,接收值为该行数据的primaryKey的值
389 * @property {String} mode 选择selection的模式, 可选值为`single`, `multiple`,默认为`multiple`
390 * @property {Function} columnProps `Function()=>Object` 选择列 的props,例如锁列、对齐等,可使用`Table.Column` 的所有参数
391 * @property {Function} titleProps `Function()=>Object` 选择列 表头的props,仅在 `multiple` 模式下生效
392 */
393 rowSelection: _propTypes2.default.object,
394 primaryKey: _propTypes2.default.oneOfType([_propTypes2.default.symbol, _propTypes2.default.string]),
395 dataSource: _propTypes2.default.array,
396 entireDataSource: _propTypes2.default.array
397 }, BaseComponent.propTypes), _class.defaultProps = (0, _extends3.default)({}, BaseComponent.defaultProps, {
398 locale: _zhCn2.default.Table,
399 primaryKey: 'id',
400 prefix: 'next-'
401 }), _class.contextTypes = {
402 listHeader: _propTypes2.default.any
403 }, _class.childContextTypes = {
404 rowSelection: _propTypes2.default.object,
405 selectedRowKeys: _propTypes2.default.array
406 }, _temp);
407 SelectionTable.displayName = 'SelectionTable';
408
409 (0, _util2.statics)(SelectionTable, BaseComponent);
410 return (0, _reactLifecyclesCompat.polyfill)(SelectionTable);
411}
412module.exports = exports['default'];
\No newline at end of file