Skip to content

Commit b1ac033

Browse files
authored
fix(TreeItem): prevent click event from propagating on operations span (#3889)
1 parent cc50e07 commit b1ac033

File tree

4 files changed

+226
-191
lines changed

4 files changed

+226
-191
lines changed

packages/components/tree/TreeItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ const TreeItem = forwardRef(
308308

309309
if (operationsView) {
310310
return (
311-
<span className={treeClassNames.treeOperations} data-target="operations">
311+
<span className={treeClassNames.treeOperations} data-target="operations" onClick={stopPropagation}>
312312
{operationsView}
313313
</span>
314314
);

packages/components/tree/_example/operations.tsx

Lines changed: 104 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
import React, { useRef, useState } from 'react';
2-
import {
3-
InputAdornment,
4-
Button,
5-
Input,
6-
Tree,
7-
Form,
8-
Switch,
9-
Space,
10-
TreeNodeModel,
11-
TreeInstanceFunctions,
12-
} from 'tdesign-react';
13-
14-
import type { TreeProps, TreeNodeValue } from 'tdesign-react';
2+
import { Button, Input, InputAdornment, Space, Switch, Tree } from 'tdesign-react';
3+
import type { TreeInstanceFunctions, TreeNodeModel, TreeProps } from 'tdesign-react';
154

165
const items = [
176
{
@@ -25,10 +14,12 @@ const items = [
2514
let index = 2;
2615

2716
export default () => {
17+
const treeRef = useRef<TreeInstanceFunctions<{ value: string; label?: string }>>(null);
18+
19+
const [activeMultiple, setActiveMultiple] = useState(false);
2820
const [useActived, setUseActived] = useState(false);
2921
const [expandParent, setExpandParent] = useState(false);
3022
const [filterText, setFilterText] = useState('');
31-
const [activeId, setActiveId] = useState<TreeNodeValue>('');
3223
const [activeIds, setActiveIds] = useState([]);
3324

3425
const getLabelContent = (node: TreeNodeModel) => {
@@ -45,8 +36,6 @@ export default () => {
4536
return label;
4637
};
4738

48-
const renderOperations: TreeProps['operations'] = (node) => `value: ${node.value}`;
49-
5039
const handleInputChange = (value: string) => {
5140
setFilterText(value);
5241
console.info('on input:', value);
@@ -69,11 +58,9 @@ export default () => {
6958
const handleActive: TreeProps['onActive'] = (vals, state) => {
7059
console.info('on active:', vals, state);
7160
setActiveIds(vals);
72-
setActiveId(vals[0] || '');
7361
};
7462

7563
/* ======== 操作 api ======= */
76-
const treeRef = useRef<TreeInstanceFunctions<{ value: string; label?: string }>>(null);
7764

7865
const setLabel = (value: string) => {
7966
const node = treeRef.current.getItem(value);
@@ -82,10 +69,7 @@ export default () => {
8269
data.label = label;
8370
};
8471

85-
const getActivedNode = () => {
86-
const activeNode = treeRef.current.getItem(activeId);
87-
return activeNode;
88-
};
72+
const getActivedNodes = () => activeIds.map((id) => treeRef.current.getItem(id));
8973

9074
const getInsertItem = () => {
9175
let item = null;
@@ -96,17 +80,20 @@ export default () => {
9680
};
9781
return item;
9882
};
83+
9984
const append = (node?: TreeNodeModel) => {
10085
const item = getInsertItem();
101-
if (item) {
102-
if (!node) {
103-
treeRef.current.appendTo('', item);
104-
} else {
105-
treeRef.current.appendTo(node.value, item);
106-
}
107-
// setLabel(item.value);
108-
if (useActived) {
86+
if (!item) return;
87+
if (!node) {
88+
treeRef.current.appendTo('', item);
89+
} else {
90+
treeRef.current.appendTo(node.value, item);
91+
}
92+
if (useActived) {
93+
if (activeMultiple) {
10994
setActiveIds((v) => [...v, item.value]);
95+
} else {
96+
setActiveIds([item.value]);
11097
}
11198
}
11299
};
@@ -164,21 +151,18 @@ export default () => {
164151

165152
const getActiveChildren = () => {
166153
console.log(activeIds);
167-
const node = getActivedNode();
168-
if (!node) return;
169-
let nodes: Array<TreeNodeModel> = [];
170-
if (node) {
154+
const nodes = getActivedNodes();
155+
if (!nodes.length) return;
156+
const allChildren: Array<TreeNodeModel> = [];
157+
nodes.forEach((node) => {
171158
const child = node.getChildren(true);
172-
if (typeof child === 'boolean') {
173-
// getChildren will never return true value.
174-
nodes = [];
175-
} else {
176-
nodes = child;
159+
if (Array.isArray(child)) {
160+
allChildren.push(...child);
177161
}
178-
}
162+
});
179163
console.info(
180164
'getActiveChildren:',
181-
nodes.map((node) => node.value),
165+
allChildren.map((node) => node.value),
182166
);
183167
};
184168

@@ -187,52 +171,75 @@ export default () => {
187171
};
188172

189173
const getActiveChecked = () => {
190-
const node = getActivedNode();
191-
if (!node) return;
192-
const nodes = treeRef.current.getItems(node.value);
174+
const nodes = getActivedNodes();
175+
if (!nodes.length) return;
176+
const allCheckedNodes: Array<TreeNodeModel> = [];
177+
nodes.forEach((node) => {
178+
const nodeItems = treeRef.current.getItems(node.value);
179+
allCheckedNodes.push(...nodeItems.filter((item) => item.checked));
180+
});
193181
console.info(
194182
'getChecked:',
195-
nodes.filter((node) => node.checked).map((node) => node.value),
183+
allCheckedNodes.map((node) => node.value),
196184
);
197185
};
198186

199187
const getActiveParent = () => {
200-
const node = getActivedNode();
201-
if (!node) return;
202-
const parent = treeRef.current.getParent(node.value);
203-
console.info('getParent', parent?.value);
188+
const nodes = getActivedNodes();
189+
if (!nodes.length) return;
190+
const parents = nodes
191+
.map((node) => {
192+
const parent = treeRef.current.getParent(node.value);
193+
return parent;
194+
})
195+
.filter(Boolean);
196+
console.info(
197+
'getParent',
198+
parents.map((parent) => parent.value),
199+
);
204200
};
205201

206202
const getActiveParents = () => {
207-
const node = getActivedNode();
208-
if (!node) return;
209-
const parents = treeRef.current.getParents(node.value);
203+
const nodes = getActivedNodes();
204+
if (!nodes.length) return;
205+
const allParents: Array<TreeNodeModel> = [];
206+
nodes.forEach((node) => {
207+
const parents = treeRef.current.getParents(node.value);
208+
allParents.push(...parents);
209+
});
210210
console.info(
211211
'getParents',
212-
parents.map((node) => node.value),
212+
allParents.map((node) => node.value),
213213
);
214214
};
215215

216216
const getActiveIndex = () => {
217-
const node = getActivedNode();
218-
if (!node) return;
219-
const index = treeRef.current.getIndex(node.value);
220-
console.info('getIndex', index);
217+
const nodes = getActivedNodes();
218+
if (!nodes.length) return;
219+
const indexes = nodes.map((node) => {
220+
const index = treeRef.current.getIndex(node.value);
221+
return { value: node.value, index };
222+
});
223+
console.info('getIndex', indexes);
221224
};
222225

223226
const setActiveChecked = () => {
224-
const node = getActivedNode();
225-
if (!node) return;
226-
treeRef.current.setItem(node.value, {
227-
checked: true,
227+
const nodes = getActivedNodes();
228+
if (!nodes.length) return;
229+
nodes.forEach((node) => {
230+
treeRef.current.setItem(node.value, {
231+
checked: true,
232+
});
228233
});
229234
};
230235

231236
const setActiveExpanded = () => {
232-
const node = getActivedNode();
233-
if (!node) return;
234-
treeRef.current.setItem(node?.value, {
235-
expanded: true,
237+
const nodes = getActivedNodes();
238+
if (!nodes.length) return;
239+
nodes.forEach((node) => {
240+
treeRef.current.setItem(node.value, {
241+
expanded: true,
242+
});
236243
});
237244
};
238245

@@ -270,44 +277,51 @@ export default () => {
270277
};
271278

272279
const getActivePlainData = () => {
273-
const node = getActivedNode();
274-
if (!node) return;
275-
const data = getPlainData(node);
276-
console.log('getActivePlainData:', data);
277-
return data;
280+
const nodes = getActivedNodes();
281+
if (!nodes.length) return;
282+
const allData = nodes.map((node) => {
283+
const data = getPlainData(node);
284+
return { nodeValue: node.value, data };
285+
});
286+
console.log('getActivePlainData:', allData);
287+
return allData;
278288
};
279289

280290
return (
281291
<Space direction="vertical">
282-
<h3 className="title">render:</h3>
283-
<Tree hover expandAll data={items} label={getLabel} operations={renderOperations} />
284-
<h3 className="title">api:</h3>
285-
<div className="operations">
286-
<Form labelWidth={200}>
287-
<Form.FormItem label="插入节点使用高亮节点" initialData={useActived}>
288-
<Switch<boolean> onChange={setUseActived} />
289-
</Form.FormItem>
290-
<Form.FormItem label="子节点展开触发父节点展开" initialData={expandParent}>
291-
<Switch<boolean> onChange={setExpandParent} />
292-
</Form.FormItem>
293-
</Form>
294-
</div>
295-
<div className="operations">
292+
<style>{`.tdesign-tree-operations .t-is-active .t-tree__label { background-color: rgba(0, 0, 255, 0.2);}`}</style>
293+
<Space direction="vertical">
294+
<Space>
295+
<span>允许多个节点同时高亮</span>
296+
<Switch<boolean> value={activeMultiple} onChange={setActiveMultiple} />
297+
</Space>
298+
<Space>
299+
<span>插入节点使用高亮节点</span>
300+
<Switch<boolean> value={useActived} onChange={setUseActived} />
301+
</Space>
302+
<Space>
303+
<span>子节点展开触发父节点展开</span>
304+
<Switch<boolean> value={expandParent} onChange={setExpandParent} />
305+
</Space>
306+
</Space>
307+
<Space>
296308
<InputAdornment prepend="filter:">
297309
<Input value={filterText} onChange={handleInputChange} />
298310
</InputAdornment>
299-
</div>
311+
</Space>
300312
<Tree
301313
ref={treeRef}
314+
className="tdesign-tree-operations"
302315
hover
303316
expandAll
304317
activable
305318
checkable
319+
checkStrictly
306320
line
321+
allowFoldNodeOnFilter
307322
data={items}
308323
actived={activeIds}
309-
activeMultiple
310-
allowFoldNodeOnFilter
324+
activeMultiple={activeMultiple}
311325
label={getLabel}
312326
expandParent={expandParent}
313327
filter={filterByText}
@@ -316,7 +330,6 @@ export default () => {
316330
onChange={handleChange}
317331
onActive={handleActive}
318332
/>
319-
<h3 className="title">api:</h3>
320333
<Space breakLine>
321334
<Button theme="primary" onClick={getItem}>
322335
{"获取 value 为 'node1' 的单个节点"}
@@ -355,6 +368,9 @@ export default () => {
355368
获取高亮节点与其子节点的数据
356369
</Button>
357370
</Space>
371+
<Space>
372+
<strong>* 相关信息通过控制台输出</strong>
373+
</Space>
358374
</Space>
359375
);
360376
};

0 commit comments

Comments
 (0)