UNPKG

8.52 kBJavaScriptView Raw
1import _extends from 'babel-runtime/helpers/extends';
2import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
3import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
4import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
5import _inherits from 'babel-runtime/helpers/inherits';
6import React from 'react';
7import PropTypes from 'prop-types';
8import { polyfill } from 'react-lifecycles-compat';
9import RowComponent from './tree/row';
10import CellComponent from './tree/cell';
11import { statics } from './util';
12
13var noop = function noop() {};
14
15export default function tree(BaseComponent) {
16 var _class, _temp;
17
18 var TreeTable = (_temp = _class = function (_React$Component) {
19 _inherits(TreeTable, _React$Component);
20
21 function TreeTable(props, context) {
22 _classCallCheck(this, TreeTable);
23
24 var _this = _possibleConstructorReturn(this, _React$Component.call(this, props, context));
25
26 _this.onTreeNodeClick = function (record) {
27 var primaryKey = _this.props.primaryKey,
28 id = record[primaryKey],
29 dataSource = _this.ds,
30 openRowKeys = [].concat(_this.state.openRowKeys),
31 index = openRowKeys.indexOf(id),
32 getChildrenKeyById = function getChildrenKeyById(id) {
33 var ret = [id];
34 var loop = function loop(data) {
35 data.forEach(function (item) {
36 ret.push(item[primaryKey]);
37 if (item.children) {
38 loop(item.children);
39 }
40 });
41 };
42 dataSource.forEach(function (item) {
43 if (item[primaryKey] === id) {
44 if (item.children) {
45 loop(item.children);
46 }
47 }
48 });
49 return ret;
50 };
51
52
53 if (index > -1) {
54 // 不仅要删除当前的openRowKey,还需要删除关联子节点的openRowKey
55 var ids = getChildrenKeyById(id);
56 ids.forEach(function (id) {
57 var i = openRowKeys.indexOf(id);
58 if (i > -1) {
59 openRowKeys.splice(i, 1);
60 }
61 });
62 } else {
63 openRowKeys.push(id);
64 }
65
66 if (!('openRowKeys' in _this.props)) {
67 _this.setState({
68 openRowKeys: openRowKeys
69 });
70 }
71 _this.props.onRowOpen(openRowKeys, id, index === -1, record);
72 };
73
74 _this.state = {
75 openRowKeys: props.openRowKeys || props.defaultOpenRowKeys || []
76 };
77 return _this;
78 }
79
80 TreeTable.prototype.getChildContext = function getChildContext() {
81 return {
82 openTreeRowKeys: this.state.openRowKeys,
83 indent: this.props.indent,
84 treeStatus: this.getTreeNodeStatus(this.ds),
85 onTreeNodeClick: this.onTreeNodeClick,
86 isTree: this.props.isTree
87 };
88 };
89
90 TreeTable.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps) {
91 if ('openRowKeys' in nextProps) {
92 return {
93 openRowKeys: nextProps.openRowKeys || []
94 };
95 }
96
97 return null;
98 };
99
100 TreeTable.prototype.normalizeDataSource = function normalizeDataSource(dataSource) {
101 var openRowKeys = this.state.openRowKeys;
102 var primaryKey = this.props.primaryKey;
103
104 var ret = [],
105 loop = function loop(dataSource, level) {
106 var parentId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
107
108 dataSource.forEach(function (item) {
109 item.__level = level;
110
111 if (level === 0 || openRowKeys.indexOf(parentId) > -1) {
112 item.__hidden = false;
113 } else {
114 item.__hidden = true;
115 }
116 ret.push(item);
117
118 if (item.children) {
119 loop(item.children, level + 1, item[primaryKey]);
120 }
121 });
122 };
123 loop(dataSource, 0);
124 this.ds = ret;
125 return ret;
126 };
127
128 TreeTable.prototype.getTreeNodeStatus = function getTreeNodeStatus() {
129 var dataSource = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
130 var openRowKeys = this.state.openRowKeys,
131 primaryKey = this.props.primaryKey,
132 ret = [];
133
134
135 openRowKeys.forEach(function (openKey) {
136 dataSource.forEach(function (item) {
137 if (item[primaryKey] === openKey) {
138 if (item.children) {
139 item.children.forEach(function (child) {
140 ret.push(child[primaryKey]);
141 });
142 }
143 }
144 });
145 });
146 return ret;
147 };
148
149 TreeTable.prototype.render = function render() {
150 /* eslint-disable no-unused-vars, prefer-const */
151 var _props = this.props,
152 components = _props.components,
153 isTree = _props.isTree,
154 dataSource = _props.dataSource,
155 indent = _props.indent,
156 others = _objectWithoutProperties(_props, ['components', 'isTree', 'dataSource', 'indent']);
157
158 if (isTree) {
159 components = _extends({}, components);
160 if (!components.Row) {
161 components.Row = RowComponent;
162 }
163 if (!components.Cell) {
164 components.Cell = CellComponent;
165 }
166
167 dataSource = this.normalizeDataSource(dataSource);
168 }
169 return React.createElement(BaseComponent, _extends({}, others, { dataSource: dataSource, components: components }));
170 };
171
172 return TreeTable;
173 }(React.Component), _class.TreeRow = RowComponent, _class.TreeCell = CellComponent, _class.propTypes = _extends({
174 /**
175 * 默认情况下展开的树形表格,传入了此属性代表tree的展开为受控操作
176 */
177 openRowKeys: PropTypes.array,
178 /**
179 * 默认情况下展开的 Expand行 或者 Tree行,非受控模式
180 * @version 1.23.22
181 */
182 defaultOpenRowKeys: PropTypes.array,
183 /**
184 * 点击tree展开或者关闭的时候触发的事件
185 * @param {Array} openRowKeys tree模式下展开的key
186 * @param {String} currentRowKey 当前点击行的key
187 * @param {Boolean} opened 当前点击是展开还是收起
188 * @param {Object} currentRecord 当前点击行的记录
189 */
190 onRowOpen: PropTypes.func,
191 /**
192 * dataSource当中数据的主键,如果给定的数据源中的属性不包含该主键,会造成选择状态全部选中
193 */
194 primaryKey: PropTypes.oneOfType([PropTypes.symbol, PropTypes.string]),
195 /**
196 * 在tree模式下的缩进尺寸, 仅在isTree为true时候有效
197 */
198 indent: PropTypes.number,
199 /**
200 * 开启Table的tree模式, 接收的数据格式中包含children则渲染成tree table
201 */
202 isTree: PropTypes.bool,
203 locale: PropTypes.object
204 }, BaseComponent.propTypes), _class.defaultProps = _extends({}, BaseComponent.defaultProps, {
205 primaryKey: 'id',
206 onRowOpen: noop,
207 components: {},
208 indent: 12
209 }), _class.childContextTypes = {
210 openTreeRowKeys: PropTypes.array,
211 indent: PropTypes.number,
212 treeStatus: PropTypes.array,
213 onTreeNodeClick: PropTypes.func,
214 isTree: PropTypes.bool
215 }, _temp);
216 TreeTable.displayName = 'TreeTable';
217
218 statics(TreeTable, BaseComponent);
219 return polyfill(TreeTable);
220}
\No newline at end of file