import React, { useMemo } from 'react';
import { List, Avatar } from 'antd';
import classNames from 'classnames';
import { TransferSortProps, TransferItem } from './types';
import { MenuOutlined } from '@ant-design/icons';
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
const SortTableItem = (props: TransferSortProps) => {
const { target, direction, sort, sourceActive, targetActive, item = {}, rowKey, onActive, onItemDoubleClick, view, getTitle, prefixCls, icon } = props
const className = useMemo(() => {
return direction === 'left'
? sourceActive.includes(item[rowKey])
: targetActive.includes(item[rowKey])
}, [direction, sourceActive, targetActive, item])
const isChecked = target && target.filter(it => it[rowKey] === item[rowKey]).length > 0;
const isDisabled = direction === 'left' ? isChecked : false;
const getAvatar = (item: TransferItem) => {
const { avatar } = view || {};
if (!avatar) return null;
if (typeof avatar === 'function') {
const avatarProps = avatar(item);
return avatarProps ? <Avatar {...avatarProps} /> : null;
} else {
return item[avatar] ? <Avatar src={item[avatar]} /> : null;
}
};
const avatarRender = () => {
if (sort && direction === 'right') {
return <div className='transfer-sortable-item-avatar'>{icon}{getAvatar(item)}</div>
}
return getAvatar(item)
}
const getDescription = (item: TransferItem) => {
const { fieldDesc } = view || {};
if (fieldDesc) {
return fieldDesc.split(',').map((name, index) =>
item[name] && (<span key={index} style={{ paddingRight: 5 }}>{item[name]}</span>));
} else {
return null;
}
};
const handleClick = (isDisabled: boolean, fn: Function) => {
return !isDisabled && fn(direction, item)
}
return (
<List.Item
className={classNames({
[`${prefixCls}-item-active`]: className, [`${prefixCls}-item-disabled`]: isDisabled
})}
key={`${item.id}`}
onClick={() => handleClick(isDisabled, onActive)}
onDoubleClick={() => handleClick(isDisabled, onItemDoubleClick)}
>
<List.Item.Meta
avatar={avatarRender()}
title={getTitle(item)}
description={getDescription(item)}
/>
</List.Item>
)
}
const SortTable = (props: TransferSortProps) => {
const { direction, unTarget, target, loading = false, sort, onSortEnd } = props;
const isLeft = direction === 'left';
const data = useMemo(() => {
return isLeft ? unTarget : target
}, [direction, unTarget, target])
const listProps = (isLeft && loading) ? { locale: { emptyText: <></> } } : {};
const showLoading = isLeft ? { spinning: loading, tip: '加载中···', wrapperClassName: 'ant-list' } : false;
return (
<List
{...listProps}
size="small"
itemLayout="horizontal"
loading={showLoading}
style={{ overflowY: 'auto' }}
>
<DragDropContext onDragEnd={onSortEnd}>
<Droppable droppableId='droppable'>
{(droppableProvided: any) => (
<div ref={droppableProvided.innerRef}>
{data && data.length > 0 && data.map((item: any, index: number) => {
return (
<Draggable
key={item?.id}
index={index}
draggableId={item?.id}
isDragDisabled={!sort || direction === 'left'}
>
{(provided: any, snapshot: any) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
style={{
...provided.draggableProps.style,
opacity: snapshot.isDragging ? 0.7 : 1,
}}
className='transfer-sortable-item-avatar'
>
<SortTableItem
{...props}
item={item}
index={index}
key={`${item.id}_${index}`}
icon={<MenuOutlined {...provided.dragHandleProps} className='drag-item-icon' />}
/>
</div>
)}
</Draggable>
)
})}
{droppableProvided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</List>
)
}
export default SortTable;
主要是 icon={<MenuOutlined {...provided.dragHandleProps} className='drag-item-icon' />}