feat: Transfer actions prop supports ReactNode array (#54104)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: thinkasany <480968828@qq.com>
This commit is contained in:
afc163
2025-06-20 10:55:27 +08:00
committed by GitHub
parent d1bb8b1e09
commit d671e38f2e
11 changed files with 1858 additions and 50 deletions

View File

@@ -1,6 +1,6 @@
---
description:
globs:
description:
globs:
alwaysApply: true
---
# 项目背景
@@ -25,3 +25,4 @@ alwaysApply: true
- 组件名使用大驼峰PascalCase
- 属性名使用小驼峰camelCase
- 合理使用 React.memo、useMemo 和 useCallback 优化性能
- 不要内嵌使用三元表达式

View File

@@ -1,4 +1,4 @@
import * as React from 'react';
import React from 'react';
import LeftOutlined from '@ant-design/icons/LeftOutlined';
import RightOutlined from '@ant-design/icons/RightOutlined';
@@ -7,8 +7,7 @@ import type { DirectionType } from '../config-provider';
export interface TransferOperationProps {
className?: string;
leftArrowText?: string;
rightArrowText?: string;
actions: React.ReactNode[];
moveToLeft?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
moveToRight?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
leftActive?: boolean;
@@ -19,42 +18,80 @@ export interface TransferOperationProps {
oneWay?: boolean;
}
type ButtonElementType = React.ReactElement<{
disabled?: boolean;
onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
}>;
function getArrowIcon(type: 'left' | 'right', direction?: DirectionType) {
const isRight = type === 'right';
if (direction !== 'rtl') {
return isRight ? <RightOutlined /> : <LeftOutlined />;
}
return isRight ? <LeftOutlined /> : <RightOutlined />;
}
interface ActionProps {
type: 'left' | 'right';
actions: React.ReactNode[];
moveToLeft?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
moveToRight?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
leftActive?: boolean;
rightActive?: boolean;
direction?: DirectionType;
disabled?: boolean;
}
const Action: React.FC<ActionProps> = ({
type,
actions,
moveToLeft,
moveToRight,
leftActive,
rightActive,
direction,
disabled,
}) => {
const isRight = type === 'right';
const button = isRight ? actions[0] : actions[1];
const moveHandler = isRight ? moveToRight : moveToLeft;
const active = isRight ? rightActive : leftActive;
const icon = getArrowIcon(type, direction);
if (React.isValidElement(button)) {
const element = button as ButtonElementType;
const onClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = (event) => {
element?.props?.onClick?.(event);
moveHandler?.(event);
};
return React.cloneElement(element, {
disabled: disabled || !active,
onClick,
});
}
return (
<Button
type="primary"
size="small"
disabled={disabled || !active}
onClick={(event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) =>
moveHandler?.(event)
}
icon={icon}
>
{button}
</Button>
);
};
const Actions: React.FC<TransferOperationProps> = (props) => {
const {
disabled,
moveToLeft,
moveToRight,
leftArrowText = '',
rightArrowText = '',
leftActive,
rightActive,
className,
style,
direction,
oneWay,
} = props;
const { className, style, oneWay, actions, ...restProps } = props;
return (
<div className={className} style={style}>
<Button
type="primary"
size="small"
disabled={disabled || !rightActive}
onClick={moveToRight}
icon={direction !== 'rtl' ? <RightOutlined /> : <LeftOutlined />}
>
{rightArrowText}
</Button>
{!oneWay && (
<Button
type="primary"
size="small"
disabled={disabled || !leftActive}
onClick={moveToLeft}
icon={direction !== 'rtl' ? <LeftOutlined /> : <RightOutlined />}
>
{leftArrowText}
</Button>
)}
<Action type="right" actions={actions} {...restProps} />
{!oneWay && <Action type="left" actions={actions} {...restProps} />}
{actions.slice(oneWay ? 1 : 2)}
</div>
);
};

View File

@@ -1,4 +1,853 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`renders components/transfer/demo/actions.tsx extend context correctly 1`] = `
<div
class="ant-transfer css-var-test-id"
>
<div
class="ant-transfer-section"
>
<div
class="ant-transfer-list-header"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
aria-label="down"
class="anticon anticon-down ant-dropdown-trigger"
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>
<div
class="ant-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up css-var-test-id ant-dropdown-css-var ant-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light css-var-test-id ant-dropdown-css-var css-var-test-id ant-dropdown-menu-css-var"
data-menu-list="true"
role="menu"
tabindex="0"
>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-selectAll"
role="menuitem"
tabindex="-1"
>
<span
class="ant-dropdown-menu-title-content"
>
Select all data
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast css-var-test-id ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-selectInvert"
role="menuitem"
tabindex="-1"
>
<span
class="ant-dropdown-menu-title-content"
>
Invert current page
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast css-var-test-id ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
</ul>
<div
aria-hidden="true"
style="display: none;"
/>
</div>
<span
class="ant-transfer-list-header-selected"
>
11 items
</span>
<span
class="ant-transfer-list-header-title"
/>
</div>
<div
class="ant-transfer-list-body"
>
<ul
class="ant-transfer-list-content"
>
<li
class="ant-transfer-list-content-item"
title="Content 1"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 1
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 2"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 2
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 3"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 3
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 4"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 4
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 5"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 5
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 6"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 6
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 7"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 7
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 8"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 8
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 9"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 9
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 10"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 10
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 11"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 11
</span>
</li>
</ul>
</div>
</div>
<div
class="ant-transfer-actions"
>
<button
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
disabled=""
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="double-right"
class="anticon anticon-double-right"
role="img"
>
<svg
aria-hidden="true"
data-icon="double-right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M533.2 492.3L277.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H188c-6.7 0-10.4 7.7-6.3 12.9L447.1 512 181.7 851.1A7.98 7.98 0 00188 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5zm304 0L581.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H492c-6.7 0-10.4 7.7-6.3 12.9L751.1 512 485.7 851.1A7.98 7.98 0 00492 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5z"
/>
</svg>
</span>
</span>
<span>
Move To Right
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
disabled=""
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="double-left"
class="anticon anticon-double-left"
role="img"
>
<svg
aria-hidden="true"
data-icon="double-left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M272.9 512l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L186.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H532c6.7 0 10.4-7.7 6.3-12.9L272.9 512zm304 0l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L490.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H836c6.7 0 10.4-7.7 6.3-12.9L576.9 512z"
/>
</svg>
</span>
</span>
<span>
Move To Left
</span>
</button>
</div>
<div
class="ant-transfer-section"
>
<div
class="ant-transfer-list-header"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
aria-label="down"
class="anticon anticon-down ant-dropdown-trigger"
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>
<div
class="ant-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up css-var-test-id ant-dropdown-css-var ant-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light css-var-test-id ant-dropdown-css-var css-var-test-id ant-dropdown-menu-css-var"
data-menu-list="true"
role="menu"
tabindex="0"
>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-selectAll"
role="menuitem"
tabindex="-1"
>
<span
class="ant-dropdown-menu-title-content"
>
Select all data
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast css-var-test-id ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-selectInvert"
role="menuitem"
tabindex="-1"
>
<span
class="ant-dropdown-menu-title-content"
>
Invert current page
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast css-var-test-id ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
</ul>
<div
aria-hidden="true"
style="display: none;"
/>
</div>
<span
class="ant-transfer-list-header-selected"
>
9 items
</span>
<span
class="ant-transfer-list-header-title"
/>
</div>
<div
class="ant-transfer-list-body"
>
<ul
class="ant-transfer-list-content"
>
<li
class="ant-transfer-list-content-item"
title="Content 12"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 12
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 13"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 13
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 14"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 14
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 15"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 15
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 16"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 16
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 17"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 17
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 18"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 18
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 19"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 19
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 20"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 20
</span>
</li>
</ul>
</div>
</div>
</div>
`;
exports[`renders components/transfer/demo/actions.tsx extend context correctly 2`] = `[]`;
exports[`renders components/transfer/demo/advanced.tsx extend context correctly 1`] = `
<div

View File

@@ -1,4 +1,701 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`renders components/transfer/demo/actions.tsx correctly 1`] = `
<div
class="ant-transfer css-var-test-id"
>
<div
class="ant-transfer-section"
>
<div
class="ant-transfer-list-header"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
aria-label="down"
class="anticon anticon-down ant-dropdown-trigger"
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
class="ant-transfer-list-header-selected"
>
11
<!-- -->
<!-- -->
items
</span>
<span
class="ant-transfer-list-header-title"
/>
</div>
<div
class="ant-transfer-list-body"
>
<ul
class="ant-transfer-list-content"
>
<li
class="ant-transfer-list-content-item"
title="Content 1"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 1
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 2"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 2
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 3"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 3
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 4"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 4
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 5"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 5
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 6"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 6
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 7"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 7
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 8"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 8
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 9"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 9
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 10"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 10
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 11"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 11
</span>
</li>
</ul>
</div>
</div>
<div
class="ant-transfer-actions"
>
<button
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
disabled=""
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="double-right"
class="anticon anticon-double-right"
role="img"
>
<svg
aria-hidden="true"
data-icon="double-right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M533.2 492.3L277.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H188c-6.7 0-10.4 7.7-6.3 12.9L447.1 512 181.7 851.1A7.98 7.98 0 00188 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5zm304 0L581.9 166.1c-3-3.9-7.7-6.1-12.6-6.1H492c-6.7 0-10.4 7.7-6.3 12.9L751.1 512 485.7 851.1A7.98 7.98 0 00492 864h77.3c4.9 0 9.6-2.3 12.6-6.1l255.3-326.1c9.1-11.7 9.1-27.9 0-39.5z"
/>
</svg>
</span>
</span>
<span>
Move To Right
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
disabled=""
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="double-left"
class="anticon anticon-double-left"
role="img"
>
<svg
aria-hidden="true"
data-icon="double-left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M272.9 512l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L186.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H532c6.7 0 10.4-7.7 6.3-12.9L272.9 512zm304 0l265.4-339.1c4.1-5.2.4-12.9-6.3-12.9h-77.3c-4.9 0-9.6 2.3-12.6 6.1L490.8 492.3a31.99 31.99 0 000 39.5l255.3 326.1c3 3.9 7.7 6.1 12.6 6.1H836c6.7 0 10.4-7.7 6.3-12.9L576.9 512z"
/>
</svg>
</span>
</span>
<span>
Move To Left
</span>
</button>
</div>
<div
class="ant-transfer-section"
>
<div
class="ant-transfer-list-header"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
aria-label="down"
class="anticon anticon-down ant-dropdown-trigger"
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
class="ant-transfer-list-header-selected"
>
9
<!-- -->
<!-- -->
items
</span>
<span
class="ant-transfer-list-header-title"
/>
</div>
<div
class="ant-transfer-list-body"
>
<ul
class="ant-transfer-list-content"
>
<li
class="ant-transfer-list-content-item"
title="Content 12"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 12
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 13"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 13
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 14"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 14
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 15"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 15
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 16"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 16
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 17"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 17
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 18"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 18
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 19"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 19
</span>
</li>
<li
class="ant-transfer-list-content-item"
title="Content 20"
>
<label
class="ant-checkbox-wrapper ant-transfer-list-checkbox css-var-test-id ant-checkbox-css-var"
>
<span
class="ant-checkbox ant-wave-target"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-content-item-text"
>
Content 20
</span>
</li>
</ul>
</div>
</div>
</div>
`;
exports[`renders components/transfer/demo/advanced.tsx correctly 1`] = `
<div

View File

@@ -0,0 +1,83 @@
import React from 'react';
import { fireEvent, render } from '@testing-library/react';
import Transfer from '..';
import Button from '../../button';
const listCommonProps: {
dataSource: { key: string; title: string; disabled?: boolean }[];
selectedKeys?: string[];
targetKeys?: string[];
} = {
dataSource: [
{ key: 'a', title: 'a' },
{ key: 'b', title: 'b' },
{ key: 'c', title: 'c', disabled: true },
],
selectedKeys: ['a'],
targetKeys: ['b'],
};
describe('Actions', () => {
it('should handle custom button click correctly via actions', () => {
const handleChange = jest.fn();
const customButtonClick = jest.fn();
const CustomButton = ({ onClick }: { onClick: () => void }) => (
<Button type="link" onClick={onClick}>
Custom Button
</Button>
);
const { getByText } = render(
<Transfer
{...listCommonProps}
onChange={handleChange}
oneWay
actions={[<CustomButton key="test" onClick={customButtonClick} />]}
/>,
);
fireEvent.click(getByText('Custom Button'));
expect(customButtonClick).toHaveBeenCalled();
expect(handleChange).toHaveBeenCalled();
});
it('should accept multiple actions >= 3', () => {
const { getByText } = render(
<Transfer
{...listCommonProps}
actions={[
<Button key="test">test</Button>,
<Button key="test2">test2</Button>,
<Button key="test3">test3</Button>,
]}
/>,
);
expect(getByText('test')).toBeInTheDocument();
expect(getByText('test2')).toBeInTheDocument();
expect(getByText('test3')).toBeInTheDocument();
});
it('should accept multiple actions >= 2 when it is oneWay', () => {
const { getByText } = render(
<Transfer
{...listCommonProps}
oneWay
actions={[<Button key="test">test</Button>, <Button key="test2">test2</Button>]}
/>,
);
expect(getByText('test')).toBeInTheDocument();
expect(getByText('test2')).toBeInTheDocument();
});
it('should accept operations for compatibility', () => {
const { getByText } = render(
<Transfer {...listCommonProps} operations={['to right', 'to left']} />,
);
expect(getByText('to right')).toBeInTheDocument();
expect(getByText('to left')).toBeInTheDocument();
});
});

View File

@@ -88,6 +88,12 @@ const generateData = (n = 20) => {
return data;
};
const ButtonRender = ({ onClick }: { onClick: () => void }) => (
<Button type="link" onClick={onClick}>
Custom Button
</Button>
);
describe('Transfer', () => {
mountTest(Transfer);
rtlTest(Transfer);
@@ -864,10 +870,6 @@ describe('Transfer', () => {
});
});
const ButtonRender = ({ onClick }: { onClick: () => void }) => (
<Button onClick={onClick}>Right button reload</Button>
);
describe('immutable data', () => {
// https://github.com/ant-design/ant-design/issues/28662
it('dataSource is frozen', () => {
@@ -911,7 +913,6 @@ describe('immutable data', () => {
return (
<Transfer
dataSource={mockData}
operations={['to right', 'to left']}
targetKeys={targetKeys}
onChange={handleChange}
render={(item) => `test-${item}`}

View File

@@ -0,0 +1,27 @@
## zh-CN
使用 `actions` 属性可以自定义操作按钮。
`actions` 传入字符串数组时,会使用默认的 Button 组件,并将字符串作为按钮文本。
`actions` 传入 React 元素数组时,会直接使用这些元素作为操作按钮,这样你可以使用自定义的按钮组件,如本例中的带有加载状态的按钮。
注意:
1. 当使用自定义按钮时Transfer 组件会自动处理按钮的禁用状态和点击事件。
2. 你可以在自定义按钮上添加 `disabled` 属性来控制按钮的禁用状态。
3. 你可以在自定义按钮上添加 `onClick` 事件处理函数,它会与 Transfer 组件的内部处理函数合并执行。
## en-US
You can customize operations with the `actions` prop. This example demonstrates how to customize actions, including handling disabled and loading states.
When `actions` is an array of strings, it will use the default Button component and set the strings as button text.
When `actions` is an array of React elements, it will use these elements directly as action buttons, allowing you to use custom button components, such as buttons with loading state in this example.
Note:
1. When using custom buttons, the Transfer component will automatically handle the button's disabled state and click events.
2. You can add a `disabled` property to your custom button to control its disabled state.
3. You can add an `onClick` event handler to your custom button, which will be merged with the Transfer component's internal handler.

View File

@@ -0,0 +1,112 @@
import React, { useState } from 'react';
import { Button, Transfer, message } from 'antd';
import { DoubleLeftOutlined, DoubleRightOutlined } from '@ant-design/icons';
import type { TransferProps } from 'antd';
interface RecordType {
key: string;
title: string;
description: string;
}
const mockData: RecordType[] = Array.from({ length: 20 }).map((_, i) => ({
key: i.toString(),
title: `Content ${i + 1}`,
description: `Description ${i + 1}`,
}));
const initialTargetKeys = mockData.filter((item) => Number(item.key) > 10).map((item) => item.key);
const App: React.FC = () => {
const [targetKeys, setTargetKeys] = useState<string[]>(initialTargetKeys);
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
const [loadingRight, setLoadingRight] = useState<boolean>(false);
const [loadingLeft, setLoadingLeft] = useState<boolean>(false);
// Handle data transfer
const handleChange: TransferProps['onChange'] = (newTargetKeys, direction, moveKeys) => {
setTargetKeys(newTargetKeys as string[]);
// Simulate async action
if (direction === 'right') {
setLoadingRight(true);
setTimeout(() => {
setLoadingRight(false);
message.success(`Successfully added ${moveKeys.length} items to the right`);
}, 1000);
} else {
setLoadingLeft(true);
setTimeout(() => {
setLoadingLeft(false);
message.success(`Successfully added ${moveKeys.length} items to the left`);
}, 1000);
}
};
// Handle selection change
const handleSelectChange: TransferProps['onSelectChange'] = (
sourceSelectedKeys,
targetSelectedKeys,
) => {
setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys] as string[]);
};
// Right button is disabled (no selected items on the left or all selected items are already in the right list)
const rightButtonDisabled =
selectedKeys.length === 0 || selectedKeys.every((key) => targetKeys.includes(key));
// Left button is disabled (no selected items on the right)
const leftButtonDisabled =
selectedKeys.length === 0 || selectedKeys.every((key) => !targetKeys.includes(key));
// Custom right button click handler
const handleRightButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
// You can add custom logic here, such as showing a confirmation dialog
console.log('Right button clicked', event);
// The Transfer component will automatically handle data transfer
};
// Custom left button click handler
const handleLeftButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
// You can add custom logic here, such as showing a confirmation dialog
console.log('Left button clicked', event);
// The Transfer component will automatically handle data transfer
};
return (
<Transfer
dataSource={mockData}
targetKeys={targetKeys}
selectedKeys={selectedKeys}
onChange={handleChange}
onSelectChange={handleSelectChange}
render={(item) => item.title}
actions={[
// Custom right button (transfer data to the right)
<Button
key="to-right"
type="primary"
icon={<DoubleRightOutlined />}
loading={loadingRight}
disabled={rightButtonDisabled}
onClick={handleRightButtonClick}
>
Move To Right
</Button>,
// Custom left button (transfer data to the left)
<Button
key="to-left"
type="primary"
icon={<DoubleLeftOutlined />}
loading={loadingLeft}
disabled={leftButtonDisabled}
onClick={handleLeftButtonClick}
>
Move To Left
</Button>,
]}
/>
);
};
export default App;

View File

@@ -26,6 +26,7 @@ One or more elements can be selected from either column, one click on the proper
<code src="./demo/search.tsx">Search</code>
<code src="./demo/advanced.tsx">Advanced</code>
<code src="./demo/custom-item.tsx">Custom datasource</code>
<code src="./demo/actions.tsx" version="6.0.0">Custom Actions</code>
<code src="./demo/large-data.tsx">Pagination</code>
<code src="./demo/table-transfer.tsx">Table Transfer</code>
<code src="./demo/tree-transfer.tsx">Tree Transfer</code>
@@ -39,7 +40,7 @@ Common props ref[Common props](/docs/react/common-props)
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| actions | A set of operations that are sorted from top to bottom | string\[] | \[`>`, `<`] | |
| actions | A set of operations that are sorted from top to bottom. When an array of strings is provided, default buttons will be used; when an array of ReactNode is provided, custom elements will be used | ReactNode\[] | \[`>`, `<`] | 6.0.0 |
| classNames | Semantic DOM class | [Record<SemanticDOM, string>](#semantic-dom) | - | |
| dataSource | Used for setting the source data. The elements that are part of this array will be present the left column. Except the elements whose keys are included in `targetKeys` prop | [RecordType extends TransferItem = TransferItem](https://github.com/ant-design/ant-design/blob/1bf0bab2a7bc0a774119f501806e3e0e3a6ba283/components/transfer/index.tsx#L12)\[] | \[] | |
| disabled | Whether disabled transfer | boolean | false | |

View File

@@ -117,7 +117,7 @@ export interface TransferProps<RecordType = any> {
titles?: React.ReactNode[];
/** @deprecated Please use `actions` instead. */
operations?: string[];
actions?: string[];
actions?: React.ReactNode[];
showSearch?: boolean | TransferSearchOption;
filterOption?: (inputValue: string, item: RecordType, direction: TransferDirection) => boolean;
locale?: Partial<TransferLocale>;
@@ -520,10 +520,9 @@ const Transfer = <RecordType extends TransferItem = TransferItem>(
<Actions
className={classnames(`${prefixCls}-actions`, mergedClassNames.actions)}
rightActive={rightActive}
rightArrowText={mergedActions[0]}
moveToRight={moveToRight}
leftActive={leftActive}
leftArrowText={mergedActions[1]}
actions={mergedActions}
moveToLeft={moveToLeft}
style={{
...operationStyle,

View File

@@ -27,6 +27,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*g9vUQq2nkpEAAA
<code src="./demo/search.tsx">带搜索框</code>
<code src="./demo/advanced.tsx">高级用法</code>
<code src="./demo/custom-item.tsx">自定义渲染行数据</code>
<code src="./demo/actions.tsx" version="6.0.0">自定义操作按钮</code>
<code src="./demo/large-data.tsx">分页</code>
<code src="./demo/table-transfer.tsx">表格穿梭框</code>
<code src="./demo/tree-transfer.tsx">树穿梭框</code>
@@ -42,7 +43,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*g9vUQq2nkpEAAA
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| actions | 操作文案集合,顺序从上至下 | string\[] | \[`>`, `<`] | |
| actions | 操作文案集合,顺序从上至下。当为字符串数组时使用默认的按钮,当为 ReactNode 数组时直接使用自定义元素 | ReactNode\[] | \[`>`, `<`] | 6.0.0 |
| classNames | 语义化结构 class | [Record<SemanticDOM, string>](#semantic-dom) | - | |
| dataSource | 数据源,其中的数据将会被渲染到左边一栏中,`targetKeys` 中指定的除外 | [RecordType extends TransferItem = TransferItem](https://github.com/ant-design/ant-design/blob/1bf0bab2a7bc0a774119f501806e3e0e3a6ba283/components/transfer/index.tsx#L12)\[] | \[] | |
| disabled | 是否禁用 | boolean | false | |