Skip to content

Commit 29e48bf

Browse files
authored
Merge pull request #346 from CrazyFork/dev
update tree component
2 parents d8f470b + ae47b3b commit 29e48bf

File tree

8 files changed

+1157
-260
lines changed

8 files changed

+1157
-260
lines changed

site/docs/zh-CN/tree.md

Lines changed: 497 additions & 26 deletions
Large diffs are not rendered by default.

src/tree/CollapseTransition.jsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ export default class CollapseTransition extends Component {
2828
this.leave();
2929
}
3030

31-
triggerChange(): void {
31+
componentWillReceiveProps(nextProps: any){
32+
if (this.props.isShow !== nextProps.isShow) this.triggerChange(nextProps.isShow);
33+
}
34+
35+
triggerChange(isShow: boolean): void {
3236
clearTimeout(this.enterTimer);
3337
clearTimeout(this.leaveTimer);
34-
if (this.props.isShow) {
38+
if (isShow) {
3539
this.beforeEnter();
3640
this.enter();
3741
} else {
@@ -102,6 +106,7 @@ export default class CollapseTransition extends Component {
102106

103107
afterLeave(): void {
104108
const el = this.selfRef;
109+
if (!el) return ;
105110

106111
el.style.display = 'none';
107112
el.style.height = '';

src/tree/Node.jsx

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,23 @@ import { watchPropertyChange, IDGenerator } from '../../libs/utils';
88
import CollapseTransition from './CollapseTransition';
99
import Checkbox from '../checkbox';
1010

11-
type Props = {
12-
nodeModel: Object,
13-
renderContent?: Function,
14-
context: Object
15-
};
1611

17-
function NodeContent(props: Props) {
18-
const { nodeModel, renderContent, context } = props;
12+
function NodeContent({context, renderContent}) {
13+
const {nodeModel, treeNode} = context.props;
1914

2015
if (typeof renderContent === 'function') {
21-
return renderContent(Object.freeze(context));
16+
return renderContent(nodeModel, nodeModel.data, treeNode.store);
2217
} else {
2318
return <span className="el-tree-node__label">{nodeModel.label}</span>;
2419
}
2520
}
2621

2722
NodeContent.propTypes = {
28-
nodeModel: PropTypes.object.isRequired,
2923
renderContent: PropTypes.func,
3024
context: PropTypes.object.isRequired
3125
};
3226

3327
type State = {
34-
expanded: boolean,
3528
childNodeRendered: boolean,
3629
isShowCheckbox: boolean
3730
};
@@ -43,7 +36,6 @@ export default class Node extends Component {
4336
super(props);
4437

4538
this.state = {
46-
expanded: false,
4739
childNodeRendered: false,
4840
isShowCheckbox: false
4941
};
@@ -128,40 +120,64 @@ export default class Node extends Component {
128120
this.oldIndeterminate = indeterminate;
129121
}
130122

131-
handleClick(): void {
132-
this.props.treeNode.setCurrentNode(this);
123+
getNodeKey(node: any, otherwise: number) {
124+
const nodeKey = this.props.nodeKey;
125+
if (nodeKey && node) {
126+
return node.data[nodeKey];
127+
}
128+
return otherwise;
133129
}
134130

135-
handleExpandIconClick(event: SyntheticEvent): void {
136-
let target = event.target;
137-
const { nodeModel, onNodeClicked } = this.props;
138-
if (target instanceof HTMLElement) {
139-
if (
140-
(target.tagName.toUpperCase() !== 'DIV' &&
141-
target.parentNode &&
142-
target.parentNode.nodeName.toUpperCase() !== 'DIV') ||
143-
target.nodeName.toUpperCase() === 'LABEL'
144-
)
145-
return;
146-
if (this.state.expanded) {
147-
nodeModel.collapse();
148-
this.setState({ expanded: false }, () =>
149-
this.refs.collapse.triggerChange());
150-
} else {
151-
nodeModel.expand(() => {
152-
this.setState({ expanded: true, childNodeRendered: true }, () =>
153-
this.refs.collapse.triggerChange());
154-
});
155-
}
156131

157-
onNodeClicked(nodeModel.data, nodeModel, this);
132+
handleClick(evt: ?SyntheticEvent): void {
133+
if (evt) evt.stopPropagation();
134+
const { nodeModel, treeNode } = this.props;
135+
136+
treeNode.setCurrentNode(this);
137+
if (treeNode.props.expandOnClickNode){
138+
this.handleExpandIconClick()
158139
}
159140
}
160141

142+
handleExpandIconClick(evt: ?SyntheticEvent): void {
143+
if (evt) evt.stopPropagation();
144+
145+
const { nodeModel, parent } = this.props;
146+
const {onNodeCollapse, onNodeExpand} = this.props.treeNode.props;
147+
148+
if (nodeModel.isLeaf) return;
149+
150+
if (nodeModel.expanded) {
151+
nodeModel.collapse()
152+
this.refresh()
153+
onNodeCollapse(nodeModel.data, nodeModel, this)
154+
} else {
155+
nodeModel.expand(() => {
156+
this.setState({childNodeRendered: true }, () => {
157+
onNodeExpand(nodeModel.data, nodeModel, this)
158+
});
159+
parent.closeSiblings(nodeModel)
160+
});
161+
}
162+
}
163+
164+
closeSiblings(exclude: any){
165+
const {treeNode, nodeModel} = this.props;
166+
if (!treeNode.props.accordion) return;
167+
if (nodeModel.isLeaf || !nodeModel.childNodes || !nodeModel.childNodes.length) return;
168+
169+
nodeModel.childNodes.filter(e=> e !== exclude).forEach(e=>e.collapse());
170+
this.refresh();
171+
}
172+
173+
refresh(){
174+
this.setState({})
175+
}
176+
161177
handleUserClick(): void {
162-
const nodeModel = this.props.nodeModel;
178+
let {nodeModel, checkStrictly} = this.props.treeNode;
163179
if (nodeModel.indeterminate) {
164-
nodeModel.setChecked(nodeModel.checked, true);
180+
nodeModel.setChecked(nodeModel.checked, !checkStrictly);
165181
}
166182
}
167183

@@ -170,47 +186,52 @@ export default class Node extends Component {
170186
}
171187

172188
render(): React.Element<any> {
173-
const { childNodeRendered, expanded } = this.state;
189+
const { childNodeRendered } = this.state;
174190
const { treeNode, nodeModel, renderContent, isShowCheckbox } = this.props;
175191

192+
let expanded = nodeModel.expanded;
193+
176194
return (
177195
<div
178196
onClick={this.handleClick.bind(this)}
179197
className={this.classNames('el-tree-node', {
180198
expanded: childNodeRendered && expanded,
181-
'is-current': treeNode.getCurrentNode() === this
199+
'is-current': treeNode.getCurrentNode() === this,
200+
'is-hidden': !nodeModel.visible
182201
})}
202+
style={{display: nodeModel.visible ? '': 'none'}}
183203
>
184204
<div
185205
className="el-tree-node__content"
186-
style={{ paddingLeft: `${nodeModel.level * 16}px` }}
187-
onClick={this.handleExpandIconClick.bind(this)}
206+
style={{ paddingLeft: `${(nodeModel.level - 1) * treeNode.props.indent}px` }}
188207
>
189208
<span
190209
className={this.classNames('el-tree-node__expand-icon', {
191210
'is-leaf': nodeModel.isLeaf,
192211
expanded: !nodeModel.isLeaf && expanded
193212
})}
213+
onClick={this.handleExpandIconClick.bind(this)}
194214
/>
195215
{isShowCheckbox &&
196216
<Checkbox
197217
checked={nodeModel.checked}
198218
onChange={this.handleCheckChange.bind(this)}
199219
indeterminate={nodeModel.indeterminate}
220+
onClick={this.handleUserClick.bind(this)}
200221
/>}
201222
{nodeModel.loading &&
202-
<span className="el-tree-node__icon el-icon-loading"> </span>}
223+
<span className="el-tree-node__loading-icon el-icon-loading"> </span>}
203224
<NodeContent
204225
nodeModel={nodeModel}
205-
renderContent={renderContent}
226+
renderContent={treeNode.props.renderContent}
206227
context={this}
207228
/>
208229
</div>
209230
<CollapseTransition isShow={expanded} ref="collapse">
210231
<div className="el-tree-node__children">
211232
{nodeModel.childNodes.map((e, idx) => {
212-
let props = Object.assign({}, this.props, { nodeModel: e });
213-
return <Node {...props} key={idx} />;
233+
let props = Object.assign({}, this.props, { nodeModel: e, parent: this });
234+
return <Node {...props} key={this.getNodeKey(e, idx)} />;
214235
})}
215236
</div>
216237
</CollapseTransition>
@@ -222,16 +243,13 @@ export default class Node extends Component {
222243
Node.propTypes = {
223244
nodeModel: PropTypes.object,
224245
options: PropTypes.object,
225-
renderContent: PropTypes.func,
226246
treeNode: PropTypes.object.isRequired,
227247
isShowCheckbox: PropTypes.bool,
228248
onCheckChange: PropTypes.func,
229-
onNodeClicked: PropTypes.func
230249
};
231250

232251
Node.defaultProps = {
233252
nodeModel: {},
234253
options: {},
235254
onCheckChange() {},
236-
onNodeClicked() {}
237255
};

0 commit comments

Comments
 (0)