188 lines
5.4 KiB
TypeScript
188 lines
5.4 KiB
TypeScript
import { useDrop } from "react-dnd";
|
|
import React, {useCallback, useRef, useState} from "react";
|
|
import CustDrag from "@/component/CustDrag";
|
|
import update from 'immutability-helper'
|
|
// 同级为排序
|
|
// 跨级为插入
|
|
import DragSortItemComponent from "@/component/DragSortItemComponent"
|
|
import {ItemTypes} from "@/cancel-on-drop-outside/ItemTypes";
|
|
|
|
export enum dropType {
|
|
CONTAINER, // 容器
|
|
NODE // 节点
|
|
}
|
|
const DropStore = {
|
|
id:0,
|
|
tag:"",
|
|
type:"drop"
|
|
}
|
|
const getDropStoreId = () =>{
|
|
DropStore.id +=1
|
|
const store = {...DropStore}
|
|
store.tag = store.type+"-"+store.id
|
|
return store
|
|
}
|
|
export interface DropType {
|
|
tag:string
|
|
type:dropType
|
|
list:DropType[]
|
|
setList?:Function
|
|
id:string
|
|
index:number,
|
|
originalIndex: number
|
|
children?:DropType[]
|
|
data:Content
|
|
}
|
|
export interface Content {
|
|
id:number
|
|
label:string
|
|
value:string
|
|
}
|
|
|
|
const dndList:DropType[] = [
|
|
{id:1, label: "组件1", value: "组件1" },
|
|
{id:2,label: "组件2", value: "组件2" },
|
|
{id:3, label: "组件3", value: "组件3" },
|
|
].map((item:Content,index)=>{
|
|
let content:Content = {...item}
|
|
return {
|
|
tag:"",
|
|
type:dropType.NODE,
|
|
id: String(index),
|
|
index:index,
|
|
originalIndex: index,
|
|
data: content,
|
|
}
|
|
})
|
|
|
|
|
|
// @ts-ignore
|
|
const CustDrop = ({ onChange }) => {
|
|
const [tag,setTag] = useState(getDropStoreId())
|
|
const [itemClass, setItemClass] = useState<{ key: number | null; value: string }>({
|
|
key: null,
|
|
value: '',
|
|
})
|
|
const sortItems = useRef<{ dragRow: any; placeRow: any; posi: string }>({
|
|
dragRow: {},
|
|
placeRow: {},
|
|
posi: '',
|
|
})
|
|
const propsList = dndList.map(item=>{
|
|
item.tag = tag.tag
|
|
return item
|
|
})
|
|
const [value, setValue] = useState<DropType[]>(propsList);
|
|
console.log(value)
|
|
const [{ canDrop, isOver }, drop] = useDrop({
|
|
accept: ItemTypes.CARD,
|
|
hover(item:Content) {
|
|
console.log(item)
|
|
},
|
|
// 同组的打上标签-同标签不允许添加,
|
|
drop: (item:DropType) => {
|
|
|
|
// const { dragRow, placeRow, posi } = sortItems.current
|
|
// let _map: any[] = JSON.parse(JSON.stringify(dndList))
|
|
// let index1 = _map.findIndex(v => v.id === dragRow.id) // 拖拽的itemIndex
|
|
// _map.splice(index1, 1) // 先删掉拖拽的,在获取放置的
|
|
const targetValue = [...value];
|
|
console.log(item.tag,tag.tag)
|
|
if (item.tag==tag.tag) {
|
|
return
|
|
}
|
|
// 没有tag就设置tag 不一样就重新设置
|
|
if(item.tag == "" || item.tag == null||item.tag!=tag.tag){
|
|
item.tag = tag.tag
|
|
}
|
|
targetValue.push(item);
|
|
setValue(targetValue);
|
|
console.log(item,value)
|
|
onChange(targetValue);
|
|
// let index = _map.findIndex(v => v.id === placeRow.id) // 放置的itemIndex
|
|
// if (index !== -1 && index1 !== -1) {
|
|
// _map.splice(posi === 'bottom' ? index + 1 : index, 0, dragRow)
|
|
// setValue(() => _map)
|
|
// }
|
|
},
|
|
collect: (monitor) => ({
|
|
// 是否放置在目标上
|
|
isOver: monitor.isOver(),
|
|
// 是否开始拖拽
|
|
canDrop: monitor.canDrop(),
|
|
}),
|
|
|
|
});
|
|
|
|
// 展示拖动时的界面效果
|
|
const showCanDrop = () => {
|
|
if (canDrop && !isOver && !value.length) return <div>请拖拽到此处</div>;
|
|
};
|
|
|
|
const delItem = (ind: number) => {
|
|
const newValue = [...value];
|
|
newValue.splice(ind, 1);
|
|
setValue(newValue);
|
|
onChange(newValue);
|
|
};
|
|
const onItemDragClass = (key:number,value:string) => {
|
|
console.log(key,value,itemClass.value)
|
|
if (itemClass.value !== value) {
|
|
setItemClass(() => {
|
|
let data = { key, value }
|
|
return data
|
|
})
|
|
}
|
|
}
|
|
const onSortItemChange = (dragRow: any, placeRow: any, posi: string) => {
|
|
console.log(dragRow,placeRow,posi)
|
|
sortItems.current = { dragRow, placeRow, posi }
|
|
}
|
|
const findCard = useCallback(
|
|
(id: string) => {
|
|
const card = value.filter((c) => `${c.id}` === id)[0]
|
|
return {
|
|
card,
|
|
index: value.indexOf(card),
|
|
}
|
|
},
|
|
[value],
|
|
)
|
|
const moveCard = useCallback(
|
|
(id: string, atIndex: number) => {
|
|
const { card, index } = findCard(id)
|
|
setValue(
|
|
update(value, {
|
|
$splice: [
|
|
[index, 1],
|
|
[atIndex, 0, card],
|
|
],
|
|
}),
|
|
)
|
|
},
|
|
[findCard, value, setValue],
|
|
)
|
|
// 内容展示
|
|
const showValue = () => {
|
|
const [, sortDrop] = useDrop(() => ({ accept: "Sort" }))
|
|
return value.map((item, index: number) => {
|
|
return (
|
|
<div key={index} >
|
|
<CustDrag data={item} />
|
|
</div>
|
|
);
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div
|
|
ref={drop}
|
|
style={{ border: '1px solid #000', marginTop: '10px', minHeight: '200px', background: '#fff' }}
|
|
>
|
|
{showCanDrop()}
|
|
{showValue()}
|
|
</div>
|
|
);
|
|
};
|
|
export default CustDrop
|