import { Transfer } from '@alifd/next';
const dataSource = (() => {
const dataSource = [];
for (let i = 0; i < 10; i++) {
dataSource.push({
label: `content${i}`,
value: `${i}`,
disabled: i % 4 === 0
});
}
return dataSource;
})();
class Demo extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(value, data, extra) {
console.log(value, data, extra);
}
render() {
return (
<Transfer defaultValue={['3']} dataSource={dataSource} defaultLeftChecked={['1']} onChange={this.handleChange} titles={['Title', 'Title']} />
);
}
}
ReactDOM.render(<Demo />, mountNode);
最简单的用法。
import { Transfer } from '@alifd/next';
const dataSource = (() => {
const dataSource = [];
for (let i = 0; i < 10; i++) {
dataSource.push({
label: `content${i}`,
value: `${i}`,
disabled: i % 4 === 0
});
}
return dataSource;
})();
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ['3']
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(value, data, extra) {
console.log(value, data, extra);
this.setState({
value
});
}
render() {
return <Transfer value={this.state.value} dataSource={dataSource} defaultLeftChecked={['1']} onChange={this.handleChange} titles={['Title', 'Title']} />;
}
}
ReactDOM.render(<Demo />, mountNode);
展示受控的用法。
import { Transfer } from '@alifd/next';
const dataSource = (() => {
const dataSource = [];
for (let i = 0; i < 10; i++) {
dataSource.push({
label: `content${i}`,
value: `${i}`,
disabled: i % 4 === 0
});
}
return dataSource;
})();
class Demo extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(value, data, extra) {
console.log(value, data, extra);
}
render() {
return <Transfer mode="simple" defaultValue={['3']} dataSource={dataSource} defaultLeftChecked={['1']} onChange={this.handleChange} titles={['Simple Mode', 'Simple Mode']} />;
}
}
ReactDOM.render(<Demo />, mountNode);
通过设置 mode 为 'simple',可以开启简单模式,点击选项即移动。
import { Transfer } from '@alifd/next';
const dataSource = (() => {
const dataSource = [];
for (let i = 0; i < 10; i++) {
dataSource.push({
label: `content${i}`,
value: `${i}`,
disabled: i % 4 === 0
});
}
return dataSource;
})();
class Demo extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(value, data, extra) {
console.log(value, data, extra);
}
render() {
return <Transfer showSearch defaultValue={['3']} dataSource={dataSource} defaultLeftChecked={['1']} onChange={this.handleChange} titles={['Searchable', 'Searchable']} />;
}
}
ReactDOM.render(<Demo />, mountNode);
展示搜索的用法。
import { Transfer } from '@alifd/next';
const dataSource = (() => {
const dataSource = [];
for (let i = 0; i < 10; i++) {
dataSource.push({
label: `content${i}`,
value: `${i}`,
disabled: i % 4 === 0
});
}
return dataSource;
})();
class Demo extends React.Component {
constructor(props) {
super(props);
this.handleSort = this.handleSort.bind(this);
}
handleSort(value, position) {
console.log(value, position);
}
render() {
return <Transfer sortable defaultValue={['3']} dataSource={dataSource} onSort={this.handleSort} titles={['Sortable', 'Sortable']} />;
}
}
ReactDOM.render(<Demo />, mountNode);
设置 sortable 属性为 true 后,可拖拽排序左右面板。
import { Transfer, Button } from '@alifd/next';
const dataSource = (() => {
const dataSource = [];
for (let i = 0; i < 10; i++) {
dataSource.push({
label: i % 3 === 0 ? `content${i}contentcontentcontentcontentcontent` : `content${i}`,
value: `${i}`,
disabled: i % 4 === 0
});
}
return dataSource;
})();
class Demo extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(value, data, extra) {
console.log(value, data, extra);
}
render() {
return (
<Transfer
defaultValue={['3']}
dataSource={dataSource}
listStyle={{ width: '200px', height: '192px' }}
defaultLeftChecked={['1']}
onChange={this.handleChange}
titles={[<Button key='left' type='primary'>Source</Button>, 'Target']}
operations={['>>', '<<']} />
);
}
}
ReactDOM.render(<Demo />, mountNode);
展示自定义样式的用法。
import { Transfer } from '@alifd/next';
const dataSource = (() => {
const dataSource = [];
for (let i = 0; i < 10; i++) {
dataSource.push({
label: `content${i}`,
value: `${i}`,
});
}
return dataSource;
})();
const obj = {
items: '项',
item: '项',
moveAll: '移动全部',
searchPlaceholder: '请输入',
moveToLeft: '撤销选中元素',
moveToRight: '提交选中元素'
};
class Demo extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(value, data, extra) {
console.log(value, data, extra);
}
render() {
return (
<Transfer id="a11y-transfer" defaultValue={['2']} dataSource={dataSource} defaultLeftChecked={['1']} locale={obj} onChange={this.handleChange} titles={['Title', 'Title']} />
);
}
}
ReactDOM.render(<Demo />, mountNode);
通过设置locale
去修改对无障碍支持,默认已经设置,请参考ARIA and KeyBoard
。
为保证可访问性,需要设置全局唯一的id
import { Transfer, Button, Tree } from '@alifd/next';
const TreeNode = Tree.Node;
const treeDataSource = [{
label: 'Form',
key: '2',
value: '2',
children: [{
label: 'Input',
key: '4',
value: '4'
}, {
label: 'Field',
key: '7',
value: '7'
}, {
label: 'Select',
key: '5',
value: '5',
}]
}, {
label: 'Display',
key: '3',
value: '3',
children: [{
label: 'Table',
key: '6',
value: '6'
}]
}, {
label: 'Data',
key: '8',
value: '8',
}];
const transferDataSource = [];
function flatten(list = []) {
list.forEach(item => {
transferDataSource.push(item);
flatten(item.children);
});
}
flatten(treeDataSource);
class Demo extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
selected: []
};
}
handleChange(value, data, extra) {
this.setState({ selected: value });
}
onCheck(keys, info) {
}
getTreeDataSource(dataSource = [], value) {
return dataSource.map(({ children, ...props }) => (
<TreeNode {...props} disabled={props.disabled || value.includes(props.value)} key={props.value}>
{this.getTreeDataSource(children, value)}
</TreeNode>
));
}
render() {
const { onChange } = this.props;
const { selected } = this.state;
return (
<Transfer
dataSource={transferDataSource}
listStyle={{ width: '200px', height: '192px' }}
onChange={this.handleChange}
titles={[<Button key='left' type='primary'>Source</Button>, 'Target']} >
{ ({ position, onChange, value }) => {
if (position === 'left') {
return (
<Tree checkable editable
style={{padding: '10px'}}
checkedKeys={value}
onCheck={
(keys, extra) => {
const newValues=extra.checkedNodes.map(item => item.props.value);
onChange(position, newValues);
}
}>
{this.getTreeDataSource(treeDataSource, selected)}
</Tree>
);
}
}
}
</Transfer>
);
}
}
ReactDOM.render(<Demo />, mountNode);
展示自定义面板的用法。
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
mode | 移动选项模式 可选值: 'normal', 'simple' |
Enum | 'normal' |
dataSource | 数据源 | Array<Object> | [] |
value | (用于受控)当前值 | Array<String> | - |
defaultValue | (用于非受控)初始值 | Array<String> | [] |
onChange | 值发生改变的时候触发的回调函数 签名: Function(value: Array, data: Array, extra: Object) => void 参数: value: {Array} 右面板值 data: {Array} 右面板数据 extra: {Object} 额外参数 extra.leftValue: {Array} 左面板值 extra.leftData: {Array} 左面板数据 extra.movedValue: {Array} 发生移动的值 extra.movedData: {Object} 发生移动的数据 extra.direction: {String} 移动的方向,值为'left'或'right' |
Function | - |
disabled | 是否禁用 | Boolean | false |
leftDisabled | 是否禁用左侧面板 | Boolean | false |
rightDisabled | 是否禁用右侧面板 | Boolean | false |
itemRender | 列表项渲染函数 签名: Function(data: Object) => ReactNode 参数: data: {Object} 数据 返回值: {ReactNode} 列表项内容 |
Function | data => data.label |
showSearch | 是否显示搜索框 | Boolean | false |
filter | 自定义搜索函数 签名: Function(searchedValue: String, data: Object) => Boolean 参数: searchedValue: {String} 搜索的内容 data: {Object} 数据 返回值: {Boolean} 是否匹配到 |
Function | 根据 label 属性匹配 |
onSearch | 搜索框输入时触发的回调函数 签名: Function(searchedValue: String, position: String) => void 参数: searchedValue: {String} 搜索的内容 position: {String} 搜索面板的位置 |
Function | () => {} |
searchPlaceholder | 搜索框占位符 | String | - |
notFoundContent | 列表为空显示内容 | ReactNode | 'Not Found' |
titles | 左右面板标题 | Array<ReactNode> | [] |
operations | 向右向左移动按钮显示内容 | Array<ReactNode> | [<Icon type="arrow-right" />, <Icon type="arrow-left" />] |
defaultLeftChecked | 左面板默认选中值 | Array<String> | [] |
defaultRightChecked | 右面板默认选中值 | Array<String> | [] |
listClassName | 左右面板列表自定义样式类名 | String | - |
listStyle | 左右面板列表自定义样式对象 | Object | - |
sortable | 是否允许拖拽排序 | Boolean | false |
onSort | 拖拽排序时触发的回调函数 签名: Function(value: Array, position: String) => void 参数: value: {Array} 排序后的值 position: {String} 拖拽的面板位置,值为:left 或 right |
Function | () => {} |
id | 请设置 id 以保证transfer的可访问性 | String | - |
children | 接收 children 自定义渲染列表 签名: Function() => void |
Function | - |
按键 | 说明 |
---|---|
Up Arrow | 获取当前项的前一项焦点 |
Down Arrow | 获取当前项的后一项焦点 |
Enter | 当前列表选中的项移动到另一个列表 |
SPACE | 选择/取消当前项或当前列表选中的项移动到另一个列表 |