Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/common
2 changes: 1 addition & 1 deletion packages/components/tree/Tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ const Tree = forwardRef<TreeInstanceFunctions<TreeOptionData>, TreeProps>((origi
if (!node || disabled || node.disabled) {
return;
}
setChecked(node, !node.isChecked(), { ...ctx, trigger: 'node-click' });
setChecked(node, !node.isChecked() && !node.isIndeterminate(), { ...ctx, trigger: 'node-click' });
};
const handleScrollToElement = useCallback(
(params: ComponentScrollToElementParams) => {
Expand Down
17 changes: 2 additions & 15 deletions packages/components/tree/TreeItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ const TreeItem = forwardRef(
expandOnClickNode,
activable,
checkProps,
disableCheck,
operations,
onClick,
onChange,
Expand Down Expand Up @@ -242,32 +241,20 @@ const TreeItem = forwardRef(
});

if (node.isCheckable()) {
let checkboxDisabled: boolean;
if (typeof disableCheck === 'function') {
checkboxDisabled = disableCheck(node.getModel());
} else {
checkboxDisabled = !!disableCheck;
}

if (node.isDisabled()) {
checkboxDisabled = true;
}

let checkboxProps: CheckboxProps;
if (typeof checkProps === 'function') {
checkboxProps = checkProps(node.getModel());
} else {
checkboxProps = checkProps;
}

return (
<Checkbox
ref={setRefCurrent}
checked={node.checked}
indeterminate={node.indeterminate}
disabled={checkboxDisabled}
disabled={node.disabled}
name={String(node.value)}
onChange={(checked, ctx) => onChange(node, ctx)}
onChange={(_, ctx) => onChange(node, ctx)}
className={labelClasses}
stopLabelTrigger={expandOnClickNode && !!node.children}
{...checkboxProps}
Expand Down
27 changes: 24 additions & 3 deletions packages/components/tree/_example/lazy.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Tree } from 'tdesign-react';
import React, { useState } from 'react';
import { Space, Switch, Tree } from 'tdesign-react';
import type { TreeProps } from 'tdesign-react';

const items = [
Expand All @@ -14,6 +14,9 @@ const items = [
];

export default () => {
const [checkable, setCheckable] = useState(true);
const [strictly, setStrictly] = useState(false);

const load: TreeProps['load'] = (node) =>
new Promise((resolve) => {
setTimeout(() => {
Expand All @@ -38,5 +41,23 @@ export default () => {
console.log('on load:', state);
};

return <Tree data={items} hover expandAll load={load} onLoad={handleLoad} />;
return (
<Space direction="vertical">
<Space>
可选: <Switch value={checkable} onChange={(value) => setCheckable(value)} />
</Space>
<Space>
严格模式: <Switch value={checkable} onChange={(value) => setStrictly(value)} />
</Space>
<Tree
hover
valueMode="all"
data={items}
checkable={checkable}
checkStrictly={strictly}
load={load}
onLoad={handleLoad}
/>
</Space>
);
};
125 changes: 65 additions & 60 deletions packages/components/tree/_example/operations.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
import React, { useRef, useState } from 'react';
import {
InputAdornment,
Button,
Input,
Tree,
Form,
Switch,
Space,
TreeNodeModel,
TreeInstanceFunctions,
} from 'tdesign-react';

import type { TreeProps, TreeNodeValue } from 'tdesign-react';

import type { TreeInstanceFunctions, TreeNodeModel } from 'tdesign-react';
import { Button, Input, InputAdornment, Space, Switch, Tree, TreeNodeValue, TreeProps } from 'tdesign-react';

const items = [
{
value: 'node1',
},
{
value: 'node2',
disabled: true,
},
];

let index = 2;

export default () => {
const treeRef = useRef<TreeInstanceFunctions<{ value: string; label?: string }>>(null);

const [useActived, setUseActived] = useState(false);
const [expandParent, setExpandParent] = useState(false);
const [filterText, setFilterText] = useState('');
Expand All @@ -45,8 +38,6 @@ export default () => {
return label;
};

const renderOperations: TreeProps['operations'] = (node) => `value: ${node.value}`;

const handleInputChange = (value: string) => {
setFilterText(value);
console.info('on input:', value);
Expand All @@ -72,9 +63,6 @@ export default () => {
setActiveId(vals[0] || '');
};

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

const setLabel = (value: string) => {
const node = treeRef.current.getItem(value);
const label = getLabelContent(node);
Expand All @@ -96,6 +84,7 @@ export default () => {
};
return item;
};

const append = (node?: TreeNodeModel) => {
const item = getInsertItem();
if (item) {
Expand All @@ -104,7 +93,6 @@ export default () => {
} else {
treeRef.current.appendTo(node.value, item);
}
// setLabel(item.value);
if (useActived) {
setActiveIds((v) => [...v, item.value]);
}
Expand All @@ -127,28 +115,52 @@ export default () => {
}
};

const canToggleDisable = (node: TreeNodeModel) => {
const parent = node.getParent?.();
const isCheckStrictly = false; // 默认关闭
if (!isCheckStrictly && parent?.disabled) {
return false; // 父节点被禁用时,子节点状态不支持手动改变
}
return true;
};

const toggleDisable = (node: TreeNodeModel) => {
treeRef.current.setItem(node.value, {
disabled: !node.disabled,
});
console.log(treeRef.current.getItems(node.value));
};

const remove = (node: TreeNodeModel) => {
treeRef.current.remove(node.value);
};

const renderOperations2 = (node: TreeNodeModel) => (
<>
<Button style={{ marginLeft: '10px' }} size="small" variant="base" onClick={() => append(node)}>
const renderOperations = (node: TreeNodeModel) => (
<Space>
<Button size="small" theme="primary" variant="base" onClick={() => append(node)}>
添加子节点
</Button>
<Button style={{ marginLeft: '10px' }} size="small" variant="outline" onClick={() => insertBefore(node)}>
<Button size="small" theme="primary" variant="outline" onClick={() => insertBefore(node)}>
前插节点
</Button>
<Button style={{ marginLeft: '10px' }} size="small" variant="outline" onClick={() => insertAfter(node)}>
<Button size="small" theme="primary" variant="outline" onClick={() => insertAfter(node)}>
后插节点
</Button>
<Button style={{ marginLeft: '10px' }} size="small" variant="base" theme="danger" onClick={() => remove(node)}>
<Button
size="small"
variant="base"
theme={node.disabled ? 'success' : 'warning'}
disabled={!canToggleDisable(node)}
onClick={() => toggleDisable(node)}
>
{node.disabled ? 'enable' : 'disable'}
</Button>
<Button size="small" theme="danger" variant="base" onClick={() => remove(node)}>
删除
</Button>
</>
</Space>
);

/* ======== API ======= */
const getItem = () => {
const node = treeRef.current.getItem('node1');
console.info('getItem:', node.value);
Expand Down Expand Up @@ -279,24 +291,17 @@ export default () => {

return (
<Space direction="vertical">
<h3 className="title">render:</h3>
<Tree hover expandAll data={items} label={getLabel} operations={renderOperations} />
<h3 className="title">api:</h3>
<div className="operations">
<Form labelWidth={200}>
<Form.FormItem label="插入节点使用高亮节点" initialData={useActived}>
<Switch<boolean> onChange={setUseActived} />
</Form.FormItem>
<Form.FormItem label="子节点展开触发父节点展开" initialData={expandParent}>
<Switch<boolean> onChange={setExpandParent} />
</Form.FormItem>
</Form>
</div>
<div className="operations">
<InputAdornment prepend="filter:">
<Input value={filterText} onChange={handleInputChange} />
</InputAdornment>
</div>
<Space>
插入节点使用高亮节点
<Switch<boolean> onChange={setUseActived} />
</Space>
<Space>
子节点展开触发父节点展开
<Switch<boolean> onChange={setExpandParent} />
</Space>
<InputAdornment prepend="filter:">
<Input value={filterText} onChange={handleInputChange} />
</InputAdornment>
<Tree
ref={treeRef}
hover
Expand All @@ -311,50 +316,50 @@ export default () => {
label={getLabel}
expandParent={expandParent}
filter={filterByText}
operations={renderOperations2}
operations={renderOperations}
onExpand={handleExpand}
onChange={handleChange}
onActive={handleActive}
/>
<h3 className="title">api:</h3>
<Space breakLine>
<Button theme="primary" onClick={getItem}>
{"获取 value 为 'node1' 的单个节点"}
<Button theme="primary" variant="outline" onClick={getItem}>
获取 value 为 node1 的单个节点
</Button>
<Button theme="primary" onClick={getAllItems}>
<Button theme="primary" variant="outline" onClick={getAllItems}>
获取所有节点
</Button>
<Button theme="primary" onClick={getActiveChildren}>
<Button theme="primary" variant="outline" onClick={getActiveChildren}>
获取高亮节点的所有子节点
</Button>
<Button theme="primary" onClick={getAllActived}>
<Button theme="primary" variant="outline" onClick={getAllActived}>
获取所有高亮节点
</Button>
<Button theme="primary" onClick={getActiveChecked}>
<Button theme="primary" variant="outline" onClick={getActiveChecked}>
获取高亮节点下的选中节点
</Button>
<Button theme="primary" onClick={() => append()}>
<Button theme="primary" variant="outline" onClick={() => append()}>
插入一个根节点
</Button>
<Button theme="primary" onClick={getActiveParent}>
<Button theme="primary" variant="outline" onClick={getActiveParent}>
获取高亮节点的父节点
</Button>
<Button theme="primary" onClick={getActiveParents}>
<Button theme="primary" variant="outline" onClick={getActiveParents}>
获取高亮节点的所有父节点
</Button>
<Button theme="primary" onClick={getActiveIndex}>
<Button theme="primary" variant="outline" onClick={getActiveIndex}>
获取高亮节点在子节点中的位置
</Button>
<Button theme="primary" onClick={setActiveChecked}>
<Button theme="primary" variant="outline" onClick={setActiveChecked}>
选中高亮节点
</Button>
<Button theme="primary" onClick={setActiveExpanded}>
<Button theme="primary" variant="outline" onClick={setActiveExpanded}>
展开高亮节点
</Button>
<Button theme="primary" onClick={getActivePlainData}>
<Button theme="primary" variant="outline" onClick={getActivePlainData}>
获取高亮节点与其子节点的数据
</Button>
</Space>
<Space>* 相关信息通过控制台输出</Space>
</Space>
);
};
4 changes: 4 additions & 0 deletions packages/components/tree/hooks/useStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function useStore(
activeMultiple,
actived,
disabled,
disableCheck,
draggable,
checkable,
value,
Expand Down Expand Up @@ -109,6 +110,7 @@ export function useStore(
expandMutex,
expandParent,
disabled,
disableCheck,
draggable,
load,
lazy,
Expand Down Expand Up @@ -185,6 +187,7 @@ export function useStore(
activable,
activeMultiple,
disabled,
disableCheck,
checkable,
draggable,
checkStrictly,
Expand All @@ -201,6 +204,7 @@ export function useStore(
draggable,
checkable,
disabled,
disableCheck,
expandAll,
expandLevel,
expandMutex,
Expand Down
9 changes: 6 additions & 3 deletions packages/tdesign-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,13 @@ spline: explain
- 按需加载方式使用的图标资源支持多色填充功能,通过 `strokeColor` 和 `fillColor` 属性进行配置
- `DatePicker`: 支持通过覆盖 `popupProps`,使点击 `preset` 时不关闭弹窗 @RylanBot ([#3798](https://github.com/Tencent/tdesign-react/pull/3798))
### 🐞 Bug Fixes
- `Tree`: 修复拖拽后展开收起图标展示异常的问题 @RylanBot ([#3756](https://github.com/Tencent/tdesign-react/pull/3756))
- `TreeItem`: 修正节点属性 `date-target` 单词拼写为 `data-target`,之前有使用该属性的业务请注意此变更 ⚠️ @RylanBot ([#3756](https://github.com/Tencent/tdesign-react/pull/3756))
- `Tree`: @RylanBot ([#3756](https://github.com/Tencent/tdesign-react/pull/3756))
- 修正节点属性 `date-target` 单词拼写为 `data-target`,之前有使用该属性的业务请注意此变更 ⚠️
- 修复拖拽后展开收起图标展示异常的问题
- `MessagePlugin`: 修复 `content` 为 `''` / `undefined` / `null` 时产生的报错 @RylanBot ([#3778](https://github.com/Tencent/tdesign-react/pull/3778))
- `Table`: 修复未开启 `<React.StrictMode>` 时,`Loading` 挂载导致的页面闪烁问题 @RylanBot ([#3775](https://github.com/Tencent/tdesign-react/pull/3775))
- `Table`:
- 修复未开启 `<React.StrictMode>` 时,`Loading` 挂载导致的页面闪烁问题 @RylanBot ([#3775](https://github.com/Tencent/tdesign-react/pull/3775))
- 修复 `size='small'` 的 `firstFullRow` 尺寸比 `size='medium'` 大的异常 ([#common2253](https://github.com/Tencent/tdesign-common/pull/2253))
- `Upload`: 修复拖拽模式下 `status` 更新错误 @RSS1102 ([#3801](https://github.com/Tencent/tdesign-react/pull/3801))
- `Input`: 修复在开启 `readonly` 或者禁用 `allowInput` 情况下没有触发 `onFocus` 和 `onBlur` 的问题 @RylanBot ([#3800](https://github.com/Tencent/tdesign-react/pull/3800))
- `Cascader`:
Expand Down
Loading
Loading