react-beautiful-dnd拖拽插件指定拖拽元素

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' />}

React-beautiful-dnd是一个React组件库,用于实现漂亮且易于使用的拖放列表。要实现一个列表拖放,需要执行以下步骤: 1. 安装react-beautiful-dnd: ``` npm install --save react-beautiful-dnd ``` 2. 导入DragDropContext、Droppable和Draggable组件: ```javascript import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; ``` 3. 创建状态并为每个列表项目分配一个唯一标识符: ```javascript const [items, setItems] = useState([ { id: "1", content: "Item 1" }, { id: "2", content: "Item 2" }, { id: "3", content: "Item 3" }, { id: "4", content: "Item 4" }, { id: "5", content: "Item 5" }, { id: "6", content: "Item 6" } ]); ``` 4. 创建渲染函数以呈现每个拖动项目: ```javascript const renderItems = () => { return items.map((item, index) => ( <Draggable key={item.id} draggableId={item.id} index={index}> {(provided, snapshot) => ( <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)}> {item.content} </div> )} </Draggable> )); }; ``` 5. 创建渲染函数以呈现拖放列表: ```javascript const renderList = () => { return ( <DragDropContext onDragEnd={onDragEnd}> <Droppable droppableId="items"> {(provided, snapshot) => ( <div {...provided.droppableProps} ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)}> {renderItems()} {provided.placeholder} </div> )} </Droppable> </DragDropContext> ); }; ``` 6. 创建onDragEnd函数以处理拖动项目: ```javascript const onDragEnd = result => { if (!result.destination) { return; } const itemsCopy = [...items]; const [reorderedItem] = itemsCopy.splice(result.source.index, 1); itemsCopy.splice(result.destination.index, 0, reorderedItem); setItems(itemsCopy); }; ``` 7. 创建样式函数以获取拖动和放置元素的样式: ```javascript const getItemStyle = (isDragging, draggableStyle) => ({ userSelect: 'none', padding: 16, margin: `0 0 ${8}px 0`, border: isDragging ? '2px solid #000' : 'none', ...draggableStyle }); const getListStyle = isDraggingOver => ({ background: isDraggingOver ? 'lightblue' : '#eee', padding: 8, width: 250 }); ``` 最后,用renderList函数渲染列表,将其放在你的React组件中,就可以开始拖放操作了!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值