mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 14:13:37 +08:00
feat: [Tree] Custom leaf icon (#37144)
* Add ability to customize leafIcon * Adapt docs * Update test snapshots * Update to single prop & adapt demo * Update tests * Rename icon type * Fix docs * Rename to .tsx and fix types * Remove useless id properties in test
This commit is contained in:
parent
668aa3a862
commit
24d165ab9b
@ -11,6 +11,7 @@ import dropIndicatorRender from './utils/dropIndicator';
|
||||
import renderSwitcherIcon from './utils/iconUtil';
|
||||
|
||||
export type SwitcherIcon = React.ReactNode | ((props: AntTreeNodeProps) => React.ReactNode);
|
||||
export type TreeLeafIcon = React.ReactNode | ((props: AntTreeNodeProps) => React.ReactNode);
|
||||
|
||||
export interface AntdTreeNodeAttribute {
|
||||
eventKey: string;
|
||||
@ -107,7 +108,7 @@ export interface TreeProps<T extends BasicDataNode = DataNode>
|
||||
RcTreeProps<T>,
|
||||
'prefixCls' | 'showLine' | 'direction' | 'draggable' | 'icon' | 'switcherIcon'
|
||||
> {
|
||||
showLine?: boolean | { showLeafIcon: boolean };
|
||||
showLine?: boolean | { showLeafIcon: boolean | TreeLeafIcon };
|
||||
className?: string;
|
||||
/** 是否支持多选 */
|
||||
multiple?: boolean;
|
||||
|
@ -1765,24 +1765,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -1861,24 +1845,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -1957,24 +1925,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -2146,24 +2098,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -2327,24 +2263,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -3152,19 +3072,164 @@ exports[`renders ./components/tree/demo/line.md extend context correctly 1`] = `
|
||||
<br />
|
||||
<br />
|
||||
showLeafIcon:
|
||||
<button
|
||||
aria-checked="true"
|
||||
class="ant-switch ant-switch-checked"
|
||||
role="switch"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-switch-handle"
|
||||
/>
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-activedescendant="undefined_list_0"
|
||||
aria-autocomplete="list"
|
||||
aria-controls="undefined_list"
|
||||
aria-haspopup="listbox"
|
||||
aria-owns="undefined_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity:0"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
title="True"
|
||||
>
|
||||
True
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-select-dropdown"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
id="undefined_list"
|
||||
role="listbox"
|
||||
style="height:0;width:0;overflow:hidden"
|
||||
>
|
||||
<div
|
||||
aria-label="True"
|
||||
aria-selected="true"
|
||||
id="undefined_list_0"
|
||||
role="option"
|
||||
>
|
||||
true
|
||||
</div>
|
||||
<div
|
||||
aria-label="False"
|
||||
aria-selected="false"
|
||||
id="undefined_list_1"
|
||||
role="option"
|
||||
>
|
||||
false
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rc-virtual-list"
|
||||
style="position:relative"
|
||||
>
|
||||
<div
|
||||
class="rc-virtual-list-holder"
|
||||
style="max-height:256px;overflow-y:auto;overflow-anchor:none"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="rc-virtual-list-holder-inner"
|
||||
style="display:flex;flex-direction:column"
|
||||
>
|
||||
<div
|
||||
aria-selected="true"
|
||||
class="ant-select-item ant-select-item-option ant-select-item-option-active ant-select-item-option-selected"
|
||||
title="True"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
True
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="False"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
False
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-selected="false"
|
||||
class="ant-select-item ant-select-item-option"
|
||||
title="Custom icon"
|
||||
>
|
||||
<div
|
||||
class="ant-select-item-option-content"
|
||||
>
|
||||
Custom icon
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="ant-select-item-option-state"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="ant-switch-inner"
|
||||
/>
|
||||
</button>
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tree ant-tree-icon-hide ant-tree-show-line"
|
||||
@ -3970,24 +4035,8 @@ exports[`renders ./components/tree/demo/switcher-icon.md extend context correctl
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -4020,24 +4069,8 @@ exports[`renders ./components/tree/demo/switcher-icon.md extend context correctl
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -4070,24 +4103,8 @@ exports[`renders ./components/tree/demo/switcher-icon.md extend context correctl
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
|
@ -1765,24 +1765,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -1861,24 +1845,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -1957,24 +1925,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -2146,24 +2098,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -2327,24 +2263,8 @@ Array [
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -3152,19 +3072,65 @@ exports[`renders ./components/tree/demo/line.md correctly 1`] = `
|
||||
<br />
|
||||
<br />
|
||||
showLeafIcon:
|
||||
<button
|
||||
aria-checked="true"
|
||||
class="ant-switch ant-switch-checked"
|
||||
role="switch"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-switch-handle"
|
||||
/>
|
||||
class="ant-select-selector"
|
||||
>
|
||||
<span
|
||||
class="ant-select-selection-search"
|
||||
>
|
||||
<input
|
||||
aria-activedescendant="undefined_list_0"
|
||||
aria-autocomplete="list"
|
||||
aria-controls="undefined_list"
|
||||
aria-haspopup="listbox"
|
||||
aria-owns="undefined_list"
|
||||
autocomplete="off"
|
||||
class="ant-select-selection-search-input"
|
||||
readonly=""
|
||||
role="combobox"
|
||||
style="opacity:0"
|
||||
type="search"
|
||||
unselectable="on"
|
||||
value=""
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-selection-item"
|
||||
title="True"
|
||||
>
|
||||
True
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
class="ant-switch-inner"
|
||||
/>
|
||||
</button>
|
||||
aria-hidden="true"
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="on"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down ant-select-suffix"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tree ant-tree-icon-hide ant-tree-show-line"
|
||||
@ -3970,24 +3936,8 @@ exports[`renders ./components/tree/demo/switcher-icon.md correctly 1`] = `
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -4020,24 +3970,8 @@ exports[`renders ./components/tree/demo/switcher-icon.md correctly 1`] = `
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
@ -4070,24 +4004,8 @@ exports[`renders ./components/tree/demo/switcher-icon.md correctly 1`] = `
|
||||
class="ant-tree-switcher ant-tree-switcher-noop"
|
||||
>
|
||||
<span
|
||||
aria-label="file"
|
||||
class="anticon anticon-file ant-tree-switcher-line-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="file"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
class="ant-tree-switcher-leaf-line"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '../../../tests/utils';
|
||||
import { render, screen } from '../../../tests/utils';
|
||||
import Tree from '../index';
|
||||
import type { AntTreeNodeProps } from '../Tree';
|
||||
|
||||
@ -36,20 +36,59 @@ describe('Tree', () => {
|
||||
const { container } = render(
|
||||
<Tree switcherIcon={<i className="switcherIcon" />} defaultExpandAll>
|
||||
<TreeNode icon="icon">
|
||||
<TreeNode id="node1" title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode id="node2" title="node2" key="0-0-3" />
|
||||
<TreeNode title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode title="node2" key="0-0-3" />
|
||||
</TreeNode>
|
||||
</Tree>,
|
||||
);
|
||||
expect(container.querySelectorAll('.switcherIcon').length).toBe(1);
|
||||
});
|
||||
|
||||
it('leaf nodes should render custom icons when provided', () => {
|
||||
const { container } = render(
|
||||
<Tree showLine={{ showLeafIcon: <i className="customLeafIcon" /> }} defaultExpandAll>
|
||||
<TreeNode icon="icon">
|
||||
<TreeNode title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode title="node2" key="0-0-3" />
|
||||
</TreeNode>
|
||||
</Tree>,
|
||||
);
|
||||
expect(container.querySelectorAll('.customLeafIcon').length).toBe(2);
|
||||
});
|
||||
|
||||
it('leaf nodes should render custom icons when provided as render function', () => {
|
||||
const { container } = render(
|
||||
<Tree showLine={{ showLeafIcon: () => <i className="customLeafIcon" /> }} defaultExpandAll>
|
||||
<TreeNode icon="icon">
|
||||
<TreeNode title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode title="node2" key="0-0-3" />
|
||||
</TreeNode>
|
||||
</Tree>,
|
||||
);
|
||||
|
||||
expect(container.querySelectorAll('.customLeafIcon').length).toBe(2);
|
||||
});
|
||||
|
||||
it('leaf nodes should render custom icons when provided as string', async () => {
|
||||
render(
|
||||
<Tree showLine={{ showLeafIcon: 'customLeafIcon' }} defaultExpandAll>
|
||||
<TreeNode icon="icon">
|
||||
<TreeNode title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode title="node2" key="0-0-3" />
|
||||
</TreeNode>
|
||||
</Tree>,
|
||||
);
|
||||
|
||||
const customIcons = await screen.findAllByText('customLeafIcon');
|
||||
expect(customIcons).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('switcherIcon in Tree could be string', () => {
|
||||
const { asFragment } = render(
|
||||
<Tree switcherIcon="switcherIcon" defaultExpandAll>
|
||||
<TreeNode icon="icon">
|
||||
<TreeNode id="node1" title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode id="node2" title="node2" key="0-0-3" />
|
||||
<TreeNode title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode title="node2" key="0-0-3" />
|
||||
</TreeNode>
|
||||
</Tree>,
|
||||
);
|
||||
@ -66,8 +105,8 @@ describe('Tree', () => {
|
||||
const { asFragment } = render(
|
||||
<Tree switcherIcon="switcherIcon" defaultExpandAll loadData={onLoadData}>
|
||||
<TreeNode icon="icon">
|
||||
<TreeNode id="node1" title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode id="node2" title="node2" key="0-0-3" />
|
||||
<TreeNode title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode title="node2" key="0-0-3" />
|
||||
</TreeNode>
|
||||
</Tree>,
|
||||
);
|
||||
@ -83,8 +122,8 @@ describe('Tree', () => {
|
||||
}
|
||||
>
|
||||
<TreeNode icon="icon">
|
||||
<TreeNode id="node1" title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode id="node2" title="node2" key="0-0-3" />
|
||||
<TreeNode title="node1" icon="icon" key="0-0-2" />
|
||||
<TreeNode title="node2" key="0-0-3" />
|
||||
</TreeNode>
|
||||
</Tree>,
|
||||
);
|
||||
|
@ -1,45 +0,0 @@
|
||||
import { calcRangeKeys } from '../utils/dictUtil';
|
||||
|
||||
describe('Tree util', () => {
|
||||
describe('calcRangeKeys', () => {
|
||||
const treeData = [
|
||||
{ key: '0-0', children: [{ key: '0-0-0' }, { key: '0-0-1' }] },
|
||||
{ key: '0-1', children: [{ key: '0-1-0' }, { key: '0-1-1' }] },
|
||||
{
|
||||
key: '0-2',
|
||||
children: [
|
||||
{ key: '0-2-0', children: [{ key: '0-2-0-0' }, { key: '0-2-0-1' }, { key: '0-2-0-2' }] },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
it('calc range keys', () => {
|
||||
const rangeKeys = calcRangeKeys({
|
||||
treeData,
|
||||
expandedKeys: ['0-0', '0-2', '0-2-0'],
|
||||
startKey: '0-2-0-1',
|
||||
endKey: '0-0-0',
|
||||
});
|
||||
const target = ['0-0-0', '0-0-1', '0-1', '0-2', '0-2-0', '0-2-0-0', '0-2-0-1'];
|
||||
expect(rangeKeys.sort()).toEqual(target.sort());
|
||||
});
|
||||
|
||||
it('return startKey when startKey === endKey', () => {
|
||||
const keys = calcRangeKeys({
|
||||
treeData,
|
||||
expandedKeys: ['0-0', '0-2', '0-2-0'],
|
||||
startKey: '0-0-0',
|
||||
endKey: '0-0-0',
|
||||
});
|
||||
expect(keys).toEqual(['0-0-0']);
|
||||
});
|
||||
|
||||
it('return empty array without startKey and endKey', () => {
|
||||
const keys = calcRangeKeys({
|
||||
treeData,
|
||||
expandedKeys: ['0-0', '0-2', '0-2-0'],
|
||||
});
|
||||
expect(keys).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
106
components/tree/__tests__/util.test.tsx
Normal file
106
components/tree/__tests__/util.test.tsx
Normal file
@ -0,0 +1,106 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { calcRangeKeys } from '../utils/dictUtil';
|
||||
import renderSwitcherIcon from '../utils/iconUtil';
|
||||
|
||||
describe('Tree util', () => {
|
||||
describe('calcRangeKeys', () => {
|
||||
const treeData = [
|
||||
{ key: '0-0', children: [{ key: '0-0-0' }, { key: '0-0-1' }] },
|
||||
{ key: '0-1', children: [{ key: '0-1-0' }, { key: '0-1-1' }] },
|
||||
{
|
||||
key: '0-2',
|
||||
children: [
|
||||
{ key: '0-2-0', children: [{ key: '0-2-0-0' }, { key: '0-2-0-1' }, { key: '0-2-0-2' }] },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
it('calc range keys', () => {
|
||||
const rangeKeys = calcRangeKeys({
|
||||
treeData,
|
||||
expandedKeys: ['0-0', '0-2', '0-2-0'],
|
||||
startKey: '0-2-0-1',
|
||||
endKey: '0-0-0',
|
||||
});
|
||||
const target = ['0-0-0', '0-0-1', '0-1', '0-2', '0-2-0', '0-2-0-0', '0-2-0-1'];
|
||||
expect(rangeKeys.sort()).toEqual(target.sort());
|
||||
});
|
||||
|
||||
it('return startKey when startKey === endKey', () => {
|
||||
const keys = calcRangeKeys({
|
||||
treeData,
|
||||
expandedKeys: ['0-0', '0-2', '0-2-0'],
|
||||
startKey: '0-0-0',
|
||||
endKey: '0-0-0',
|
||||
});
|
||||
expect(keys).toEqual(['0-0-0']);
|
||||
});
|
||||
|
||||
it('return empty array without startKey and endKey', () => {
|
||||
const keys = calcRangeKeys({
|
||||
treeData,
|
||||
expandedKeys: ['0-0', '0-2', '0-2-0'],
|
||||
});
|
||||
expect(keys).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('renderSwitcherIcon', () => {
|
||||
const prefixCls = 'tree';
|
||||
|
||||
it('returns a loading icon when loading', () => {
|
||||
const { container } = render(
|
||||
<>{renderSwitcherIcon(prefixCls, undefined, true, { loading: true })}</>,
|
||||
);
|
||||
expect(container.getElementsByClassName(`${prefixCls}-switcher-loading-icon`)).toHaveLength(
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it('returns nothing when node is a leaf without showLine', () => {
|
||||
const { container } = render(
|
||||
<>{renderSwitcherIcon(prefixCls, undefined, false, { loading: false, isLeaf: true })}</>,
|
||||
);
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
it('returns a custom leaf icon when provided', () => {
|
||||
const testId = 'custom-icon';
|
||||
const customLeafIcon = <div data-testid={testId} />;
|
||||
const { container } = render(
|
||||
<>
|
||||
{renderSwitcherIcon(
|
||||
prefixCls,
|
||||
undefined,
|
||||
{ showLeafIcon: customLeafIcon },
|
||||
{ loading: false, isLeaf: true },
|
||||
)}
|
||||
</>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId(testId)).toBeVisible();
|
||||
expect(
|
||||
container.getElementsByClassName(`${prefixCls}-switcher-line-custom-icon`),
|
||||
).toHaveLength(1);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[`${prefixCls}-switcher-line-icon`, true],
|
||||
[`${prefixCls}-switcher-leaf-line`, false],
|
||||
])('returns %p element when showLeafIcon is %p', (expectedClassName, showLeafIcon) => {
|
||||
const { container } = render(
|
||||
<>
|
||||
{renderSwitcherIcon(
|
||||
prefixCls,
|
||||
undefined,
|
||||
{ showLeafIcon },
|
||||
{ loading: false, isLeaf: true },
|
||||
)}
|
||||
</>,
|
||||
);
|
||||
|
||||
expect(container.getElementsByClassName(expectedClassName)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
@ -14,8 +14,8 @@ title:
|
||||
Tree with connected line between nodes, turn on by `showLine`, customize the preseted icon by `switcherIcon`.
|
||||
|
||||
```tsx
|
||||
import { CarryOutOutlined, FormOutlined } from '@ant-design/icons';
|
||||
import { Switch, Tree } from 'antd';
|
||||
import { CarryOutOutlined, CheckOutlined, FormOutlined } from '@ant-design/icons';
|
||||
import { Select, Switch, Tree } from 'antd';
|
||||
import type { DataNode } from 'antd/es/tree';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
@ -85,36 +85,44 @@ const treeData: DataNode[] = [
|
||||
];
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [showLine, setShowLine] = useState<boolean | { showLeafIcon: boolean }>(true);
|
||||
const [showLine, setShowLine] = useState<boolean>(true);
|
||||
const [showIcon, setShowIcon] = useState<boolean>(false);
|
||||
const [showLeafIcon, setShowLeafIcon] = useState<boolean>(true);
|
||||
const [showLeafIcon, setShowLeafIcon] = useState<boolean | React.ReactNode>(true);
|
||||
|
||||
const onSelect = (selectedKeys: React.Key[], info: any) => {
|
||||
console.log('selected', selectedKeys, info);
|
||||
};
|
||||
|
||||
const onSetLeafIcon = (checked: boolean) => {
|
||||
setShowLeafIcon(checked);
|
||||
setShowLine({ showLeafIcon: checked });
|
||||
};
|
||||
const handleLeafIconChange = (value: 'true' | 'false' | 'custom') => {
|
||||
if (value === 'custom') {
|
||||
return setShowLeafIcon(<CheckOutlined />);
|
||||
}
|
||||
|
||||
const onSetShowLine = (checked: boolean) => {
|
||||
setShowLine(checked ? { showLeafIcon } : false);
|
||||
if (value === 'true') {
|
||||
return setShowLeafIcon(true);
|
||||
}
|
||||
|
||||
return setShowLeafIcon(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
showLine: <Switch checked={!!showLine} onChange={onSetShowLine} />
|
||||
showLine: <Switch checked={!!showLine} onChange={setShowLine} />
|
||||
<br />
|
||||
<br />
|
||||
showIcon: <Switch checked={showIcon} onChange={setShowIcon} />
|
||||
<br />
|
||||
<br />
|
||||
showLeafIcon: <Switch checked={showLeafIcon} onChange={onSetLeafIcon} />
|
||||
showLeafIcon:{' '}
|
||||
<Select defaultValue="true" onChange={handleLeafIconChange}>
|
||||
<Select.Option value="true">True</Select.Option>
|
||||
<Select.Option value="false">False</Select.Option>
|
||||
<Select.Option value="custom">Custom icon</Select.Option>
|
||||
</Select>
|
||||
</div>
|
||||
<Tree
|
||||
showLine={showLine}
|
||||
showLine={showLine ? { showLeafIcon } : false}
|
||||
showIcon={showIcon}
|
||||
defaultExpandedKeys={['0-0-0']}
|
||||
onSelect={onSelect}
|
||||
|
@ -43,7 +43,7 @@ Almost anything can be represented in a tree structure. Examples include directo
|
||||
| selectable | Whether can be selected | boolean | true | |
|
||||
| selectedKeys | (Controlled) Specifies the keys of the selected treeNodes | string\[] | - | |
|
||||
| showIcon | Shows the icon before a TreeNode's title. There is no default style; you must set a custom style for it if set to true | boolean | false | |
|
||||
| showLine | Shows a connecting line | boolean \| {showLeafIcon: boolean} | false | |
|
||||
| showLine | Shows a connecting line | boolean \| {showLeafIcon: boolean \| ReactNode \| ((props: AntTreeNodeProps) => ReactNode)} | false | |
|
||||
| switcherIcon | Customize collapse/expand icon of tree node | ReactNode \| ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.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<{ key, title, children, \[disabled, selectable] }> | - | |
|
||||
|
@ -17,7 +17,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/Xh-oWqg9k/Tree.svg
|
||||
### Tree props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| allowDrop | 是否允许拖拽时放置在该节点 | ({ dropNode, dropPosition }) => boolean | - | |
|
||||
| autoExpandParent | 是否自动展开父节点 | boolean | false | |
|
||||
| blockNode | 是否节点占据一行 | boolean | false | |
|
||||
@ -44,7 +44,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/Xh-oWqg9k/Tree.svg
|
||||
| selectable | 是否可选中 | boolean | true | |
|
||||
| selectedKeys | (受控)设置选中的树节点 | string\[] | - | |
|
||||
| showIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true,需要自行定义图标相关样式 | boolean | false | |
|
||||
| showLine | 是否展示连接线 | boolean \| {showLeafIcon: boolean} | false | |
|
||||
| showLine | 是否展示连接线 | boolean \| {showLeafIcon: boolean \| ReactNode | ((props: AntTreeNodeProps) => ReactNode)} | false | |
|
||||
| switcherIcon | 自定义树节点的展开/折叠图标 | ReactNode \| ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.20.0 |
|
||||
| titleRender | 自定义渲染节点 | (nodeData) => ReactNode | - | 4.5.0 |
|
||||
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(key 在整个树范围内唯一) | array<{key, title, children, \[disabled, selectable]}> | - | |
|
||||
|
@ -6,12 +6,12 @@ import PlusSquareOutlined from '@ant-design/icons/PlusSquareOutlined';
|
||||
import classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import { cloneElement, isValidElement } from '../../_util/reactNode';
|
||||
import type { AntTreeNodeProps, SwitcherIcon } from '../Tree';
|
||||
import type { AntTreeNodeProps, TreeLeafIcon, SwitcherIcon } from '../Tree';
|
||||
|
||||
export default function renderSwitcherIcon(
|
||||
prefixCls: string,
|
||||
switcherIcon: SwitcherIcon,
|
||||
showLine: boolean | { showLeafIcon: boolean } | undefined,
|
||||
showLine: boolean | { showLeafIcon: boolean | TreeLeafIcon } | undefined,
|
||||
treeNodeProps: AntTreeNodeProps,
|
||||
): React.ReactNode {
|
||||
const { isLeaf, expanded, loading } = treeNodeProps;
|
||||
@ -19,18 +19,35 @@ export default function renderSwitcherIcon(
|
||||
if (loading) {
|
||||
return <LoadingOutlined className={`${prefixCls}-switcher-loading-icon`} />;
|
||||
}
|
||||
let showLeafIcon;
|
||||
let showLeafIcon: boolean | TreeLeafIcon;
|
||||
if (showLine && typeof showLine === 'object') {
|
||||
showLeafIcon = showLine.showLeafIcon;
|
||||
}
|
||||
|
||||
if (isLeaf) {
|
||||
if (showLine) {
|
||||
if (typeof showLine === 'object' && !showLeafIcon) {
|
||||
return <span className={`${prefixCls}-switcher-leaf-line`} />;
|
||||
}
|
||||
return <FileOutlined className={`${prefixCls}-switcher-line-icon`} />;
|
||||
if (!showLine) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
if (typeof showLeafIcon !== 'boolean' && !!showLeafIcon) {
|
||||
const leafIcon =
|
||||
typeof showLeafIcon === 'function' ? showLeafIcon(treeNodeProps) : showLeafIcon;
|
||||
const leafCls = `${prefixCls}-switcher-line-custom-icon`;
|
||||
|
||||
if (isValidElement(leafIcon)) {
|
||||
return cloneElement(leafIcon, {
|
||||
className: classNames(leafIcon.props.className || '', leafCls),
|
||||
});
|
||||
}
|
||||
|
||||
return leafIcon;
|
||||
}
|
||||
|
||||
return showLeafIcon ? (
|
||||
<FileOutlined className={`${prefixCls}-switcher-line-icon`} />
|
||||
) : (
|
||||
<span className={`${prefixCls}-switcher-leaf-line`} />
|
||||
);
|
||||
}
|
||||
|
||||
const switcherCls = `${prefixCls}-switcher-icon`;
|
||||
|
Loading…
Reference in New Issue
Block a user