133 lines
4.4 KiB
JavaScript
133 lines
4.4 KiB
JavaScript
import React, { useRef } from 'react'
|
|
import { useDrag, useDrop } from 'react-dnd'
|
|
import { ItemTypes } from '../ItemTypes';
|
|
|
|
// store
|
|
import { storeSet, useStore } from '../../../../store';
|
|
|
|
// components
|
|
import { Button } from 'primereact/button';
|
|
import { Tag } from 'primereact/tag';
|
|
import BuilderElementProperLabel from '../BuilderElementProperLabel';
|
|
|
|
const BuilderElement = ({ id, name, label, index }) => {
|
|
const draggingElementId = useStore().main.draggingElementId();
|
|
const ref = useRef(null);
|
|
|
|
const [{ handlerId }, drop] = useDrop({
|
|
accept: ItemTypes.FIELD,
|
|
collect(monitor) {
|
|
return {
|
|
handlerId: monitor.getHandlerId(),
|
|
}
|
|
},
|
|
drop(item, monitor) {
|
|
storeSet.main.draggingElementId(0);
|
|
return item;
|
|
},
|
|
hover(item, monitor) {
|
|
if (!ref.current) {
|
|
return
|
|
}
|
|
const dragIndex = item.index
|
|
|
|
if (dragIndex > -1) {
|
|
const hoverIndex = index
|
|
|
|
if (dragIndex === hoverIndex) {
|
|
return
|
|
}
|
|
|
|
const hoverBoundingRect = ref.current?.getBoundingClientRect()
|
|
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2
|
|
const clientOffset = monitor.getClientOffset()
|
|
const hoverClientY = clientOffset.y - hoverBoundingRect.top
|
|
|
|
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
|
|
return
|
|
}
|
|
|
|
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
|
|
return
|
|
}
|
|
|
|
move(dragIndex, hoverIndex, item)
|
|
item.index = hoverIndex
|
|
} else {
|
|
let hoverIndex = index
|
|
|
|
const hoverBoundingRect = ref.current?.getBoundingClientRect()
|
|
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2
|
|
const clientOffset = monitor.getClientOffset()
|
|
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
|
|
|
|
if (hoverClientY > hoverMiddleY) {
|
|
hoverIndex = hoverIndex + 1;
|
|
}
|
|
|
|
move(dragIndex, hoverIndex, item)
|
|
item.index = hoverIndex;
|
|
}
|
|
},
|
|
});
|
|
|
|
const [{ isDragging }, drag] = useDrag({
|
|
type: ItemTypes.FIELD,
|
|
item: () => {
|
|
return { id, name, index }
|
|
},
|
|
collect: (monitor) => ({
|
|
isDragging: monitor.isDragging(),
|
|
}),
|
|
});
|
|
|
|
const move = (dragIndex, hoverIndex, item) => {
|
|
storeSet.main.moveElement(dragIndex, hoverIndex, item);
|
|
}
|
|
|
|
const openSettings = (id) => {
|
|
storeSet.main.activeElement(id);
|
|
}
|
|
|
|
const remove = (id) => {
|
|
storeSet.main.removeElement(id);
|
|
}
|
|
|
|
const opacity = isDragging ? 0 : 1;
|
|
drag(drop(ref));
|
|
|
|
return (
|
|
draggingElementId === id
|
|
? <div ref={ref} className="formBuilder__elementNew"></div>
|
|
: <div ref={ref} className="formBuilder__element" style={{ opacity }} data-handler-id={handlerId}>
|
|
<div className="meta">
|
|
<Tag value={name} severity="info"/>
|
|
<BuilderElementProperLabel id={id} defaultLabel={label}/>
|
|
</div>
|
|
<div className="actions">
|
|
<Button icon="pi pi-cog" onClick={() => openSettings(id)} outlined severity="info"/>
|
|
<Button icon="pi pi-trash" onClick={() => remove(id)} outlined severity="danger"/>
|
|
</div>
|
|
</div>
|
|
)
|
|
|
|
/*return (
|
|
<div ref={ref} className="formBuilder__element" style={{ opacity }} data-handler-id={handlerId}>
|
|
{draggingId === id
|
|
? <div className="formBuilder__elementNew"></div>
|
|
: <>
|
|
<div className="meta">
|
|
<Tag value={name} severity="info"/>
|
|
<BuilderElementProperLabel id={id} defaultLabel={label}/>
|
|
</div>
|
|
<div className="actions">
|
|
<Button icon="pi pi-cog" onClick={() => openSettings(id)} outlined severity="info"/>
|
|
<Button icon="pi pi-trash" onClick={() => remove(id)} outlined severity="danger"/>
|
|
</div>
|
|
</>
|
|
}
|
|
</div>
|
|
)*/
|
|
}
|
|
|
|
export default BuilderElement; |