| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- import type { ReactNode } from 'react';
- import { useDrag, useDrop } from 'react-dnd';
- import type { DragItemDataType } from '~/interfaces/bookmark-info';
- type DragAndDropWrapperProps = {
- item?: Partial<DragItemDataType>
- type: string[]
- children: ReactNode
- useDragMode?: boolean
- useDropMode?: boolean
- onDropItem?:(item: DragItemDataType, type: string | null | symbol) => Promise<void>
- isDropable?:(item: Partial<DragItemDataType>, type: string | null | symbol) => boolean
- }
- export const DragAndDropWrapper = (props: DragAndDropWrapperProps): JSX.Element => {
- const {
- item, children, useDragMode, useDropMode, type, onDropItem, isDropable,
- } = props;
- const acceptedTypes = type;
- const sourcetype: string | symbol = type[0];
- const [, dragRef] = useDrag({
- type: sourcetype,
- item,
- collect: monitor => ({
- isDragging: monitor.isDragging(),
- canDrag: monitor.canDrag(),
- }),
- });
- const [{ isOver }, dropRef] = useDrop(() => ({
- accept: acceptedTypes,
- drop: (item: DragItemDataType, monitor) => {
- const itemType: string | null | symbol = monitor.getItemType();
- if (onDropItem != null) {
- onDropItem(item, itemType);
- }
- },
- canDrop: (item, monitor) => {
- const itemType: string | null | symbol = monitor.getItemType();
- if (isDropable != null) {
- return isDropable(item, itemType);
- }
- return false;
- },
- collect: monitor => ({
- isOver: monitor.isOver({ shallow: true }) && monitor.canDrop(),
- }),
- }));
- const getCallback = (c: HTMLDivElement | null) => {
- if (useDragMode && useDropMode) {
- dragRef(c);
- dropRef(c);
- }
- else if (useDragMode) {
- dragRef(c);
- }
- else if (useDropMode) {
- dropRef(c);
- }
- };
- return (
- <div ref={getCallback} className={`grw-drag-drop-container ${isOver ? 'grw-accept-drop-item' : ''}`}>
- {children}
- </div>
- );
- };
|