feat(tree): add switcherLoadingIcon prop (#49716)

* feat(tree): add switcherLoadingIcon prop

* refactor: lint

* Update components/tree/index.en-US.md

add version desc

Co-authored-by: lijianan <574980606@qq.com>
Signed-off-by: ice <49827327+coding-ice@users.noreply.github.com>

* docs: add version desc

---------

Signed-off-by: ice <49827327+coding-ice@users.noreply.github.com>
Co-authored-by: lijianan <574980606@qq.com>
This commit is contained in:
ice 2024-07-22 19:49:29 +08:00 committed by GitHub
parent 0681d6c7a2
commit 5a9a2d95ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 171 additions and 1 deletions

View File

@ -151,6 +151,7 @@ export interface TreeProps<T extends BasicDataNode = DataNode>
showIcon?: boolean;
icon?: TreeIcon;
switcherIcon?: SwitcherIcon;
switcherLoadingIcon?: React.ReactNode;
prefixCls?: string;
children?: React.ReactNode;
blockNode?: boolean;
@ -164,6 +165,7 @@ const Tree = React.forwardRef<RcTree, TreeProps>((props, ref) => {
showIcon = false,
showLine,
switcherIcon,
switcherLoadingIcon,
blockNode = false,
children,
checkable = false,
@ -226,6 +228,7 @@ const Tree = React.forwardRef<RcTree, TreeProps>((props, ref) => {
<SwitcherIconCom
prefixCls={prefixCls}
switcherIcon={switcherIcon}
switcherLoadingIcon={switcherLoadingIcon}
treeNodeProps={nodeProps}
showLine={showLine}
/>

View File

@ -495,6 +495,144 @@ exports[`Tree showLine is object type should render correctly 1`] = `
</div>
`;
exports[`Tree support switcherLoadingIcon prop when loadData 1`] = `
<div
class="ant-tree ant-tree-icon-hide"
role="tree"
>
<div>
<input
aria-label="for screen reader"
style="width: 0px; height: 0px; display: flex; overflow: hidden; opacity: 0; border: 0px; padding: 0px; margin: 0px;"
tabindex="0"
value=""
/>
</div>
<div
aria-hidden="true"
class="ant-tree-treenode"
style="position: absolute; pointer-events: none; visibility: hidden; height: 0px; overflow: hidden; border: 0px; padding: 0px;"
>
<div
class="ant-tree-indent"
>
<div
class="ant-tree-indent-unit"
/>
</div>
</div>
<div
class="ant-tree-list"
style="position: relative;"
>
<div
class="ant-tree-list-holder"
>
<div>
<div
class="ant-tree-list-holder-inner"
style="display: flex; flex-direction: column;"
>
<div
aria-grabbed="false"
class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"
draggable="false"
>
<span
aria-hidden="true"
class="ant-tree-indent"
/>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
switcherIcon
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="---"
>
<span
class="ant-tree-title"
>
---
</span>
</span>
</div>
<div
aria-grabbed="false"
class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-loading"
draggable="false"
>
<span
aria-hidden="true"
class="ant-tree-indent"
>
<span
class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"
/>
</span>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<div>
loading...
</div>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="node1"
>
<span
class="ant-tree-iconEle ant-tree-icon__open ant-tree-icon_loading"
/>
<span
class="ant-tree-title"
>
node1
</span>
</span>
</div>
<div
aria-grabbed="false"
class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-loading ant-tree-treenode-leaf-last"
draggable="false"
>
<span
aria-hidden="true"
class="ant-tree-indent"
>
<span
class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"
/>
</span>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<div>
loading...
</div>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="node2"
>
<span
class="ant-tree-iconEle ant-tree-icon__open ant-tree-icon_loading"
/>
<span
class="ant-tree-title"
>
node2
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`Tree switcherIcon in Tree could be string 1`] = `
<div
class="ant-tree ant-tree-icon-hide"

View File

@ -114,6 +114,29 @@ describe('Tree', () => {
expect(asFragment().firstChild).toMatchSnapshot();
});
it('support switcherLoadingIcon prop when loadData', () => {
const onLoadData = () =>
new Promise<void>((resolve) => {
setTimeout(() => {
resolve();
}, 1000);
});
const { asFragment } = render(
<Tree
switcherIcon="switcherIcon"
loadData={onLoadData}
defaultExpandAll
switcherLoadingIcon={<div>loading...</div>}
>
<TreeNode icon="icon">
<TreeNode title="node1" icon="icon" key="0-0-2" />
<TreeNode title="node2" key="0-0-3" />
</TreeNode>
</Tree>,
);
expect(asFragment().firstChild).toMatchSnapshot();
});
it('switcherIcon in Tree could be render prop function', () => {
const { container } = render(
<Tree

View File

@ -67,6 +67,7 @@ Common props ref[Common props](/docs/react/common-props)
| showIcon | Controls whether to display the `icon` node, no default style | boolean | false | |
| showLine | Shows a connecting line | boolean \| {showLeafIcon: ReactNode \| ((props: AntTreeNodeProps) => ReactNode)} | false | |
| switcherIcon | Customize expand/collapse icons for tree nodes (With default rotate angular style) | ReactNode \| ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.20.0 |
| switcherLoadingIcon | Customize loading icons for tree nodes | ReactNode | - | 5.20.0 |
| titleRender | Customize tree node title render | (nodeData) => ReactNode | - | 4.5.0 |
| treeData | The treeNodes data Array, if set it then you need not to construct children TreeNode. (key should be unique across the whole array) | array&lt;{ key, title, children, \[disabled, selectable] }> | - | |
| virtual | Disable virtual scroll when set to false | boolean | true | 4.1.0 |

View File

@ -69,6 +69,7 @@ demo:
| showIcon | 控制是否展示 `icon` 节点,没有默认样式 | boolean | false | |
| showLine | 是否展示连接线 | boolean \| { showLeafIcon: ReactNode \| ((props: AntTreeNodeProps) => ReactNode) } | false | |
| switcherIcon | 自定义树节点的展开/折叠图标(带有默认 rotate 角度样式) | ReactNode \| ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.20.0 |
| switcherLoadingIcon | 自定义树节点的加载图标 | ReactNode | - | 5.20.0 |
| titleRender | 自定义渲染节点 | (nodeData) => ReactNode | - | 4.5.0 |
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点key 在整个树范围内唯一) | array&lt;{key, title, children, \[disabled, selectable]}> | - | |
| virtual | 设置 false 时关闭虚拟滚动 | boolean | true | 4.1.0 |

View File

@ -13,15 +13,19 @@ interface SwitcherIconProps {
prefixCls: string;
treeNodeProps: AntTreeNodeProps;
switcherIcon?: SwitcherIcon;
switcherLoadingIcon?: React.ReactNode;
showLine?: boolean | { showLeafIcon: boolean | TreeLeafIcon };
}
const SwitcherIconCom: React.FC<SwitcherIconProps> = (props) => {
const { prefixCls, switcherIcon, treeNodeProps, showLine } = props;
const { prefixCls, switcherIcon, treeNodeProps, showLine, switcherLoadingIcon } = props;
const { isLeaf, expanded, loading } = treeNodeProps;
if (loading) {
if (React.isValidElement(switcherLoadingIcon)) {
return switcherLoadingIcon;
}
return <LoadingOutlined className={`${prefixCls}-switcher-loading-icon`} />;
}
let showLeafIcon: boolean | TreeLeafIcon;