react-dnd#XYCoord TypeScript Examples

The following examples show how to use react-dnd#XYCoord. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DragItem.tsx    From gio-design with Apache License 2.0 6 votes vote down vote up
DragItem: React.FC<DragItemProps> = (props) => {
  const { label, value, onMoved, index, disabled, ...rest } = props;
  const prefixCls = `${usePrefixCls(PREFIX)}`;
  const ref = useRef<HTMLDivElement>(null);
  const [{ handlerId }, drop] = useDrop({
    accept: 'drag-item',
    collect(monitor) {
      return {
        handlerId: monitor.getHandlerId(),
      };
    },
    hover(item: { index: number; type: string; id: string }, monitor: DropTargetMonitor) {

      const dragIndex = item.index;
      const hoverIndex = index;

      if (dragIndex === hoverIndex) {
        return;
      }
      const hoverBoundingRect = ref.current?.getBoundingClientRect() || { bottom: 0, top: 0 };
      const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
      const clientOffset = monitor.getClientOffset();

      const hoverClientY = (clientOffset as XYCoord).y - hoverBoundingRect.top;

      // Dragging upwards or downwards
      if ((dragIndex < hoverIndex && hoverClientY < hoverMiddleY) || (dragIndex > hoverIndex && hoverClientY > hoverMiddleY)) {
        return
      };

      onMoved?.(dragIndex as number, hoverIndex);
      // eslint-disable-next-line no-param-reassign
      item.index = hoverIndex;
    },
  });
  const [, drag] = useDrag({
    item: { type: 'drag-item', id: value, index },
    collect: (monitor: DragSourceMonitor) => ({
      isDragging: monitor.isDragging(),
    }),
    canDrag: !disabled,
  });

  drag(drop(ref));
  return (
    <div
      className={classNames(`${prefixCls}--item`, `${prefixCls}--item--drag`, {
        [`${prefixCls}--item--disabled`]: disabled,
      })}
      ref={ref}
      data-handler-id={handlerId}
    >
      <DragOutlined
        className={classNames(`${prefixCls}--item--drag--icon`, {
          [`${prefixCls}--item--drag--icon--disabled`]: disabled,
        })}
        color="#ADB2C2"
        size="14px"
      />
      <Item label={label} value={value} disabled={disabled} {...rest} />
    </div>
  );
}
Example #2
Source File: use-hooks.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
useListDnD = ({ type, index, onMove, collect }: IDragProps) => {
  const dragRef = useRef<HTMLDivElement>(null);

  const [, drop] = useDrop({
    accept: type,
    hover(item: DragItem, monitor: DropTargetMonitor) {
      if (!dragRef.current) {
        return;
      }
      const dragIndex = item.index;
      const hoverIndex = index;

      // Don't replace items with themselves
      if (dragIndex === hoverIndex) {
        return;
      }

      // Determine rectangle on screen
      const hoverBoundingRect = dragRef.current!.getBoundingClientRect();

      // Get vertical middle
      const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;

      // Determine mouse position
      const clientOffset = monitor.getClientOffset();

      // Get pixels to the top
      const hoverClientY = (clientOffset as XYCoord).y - hoverBoundingRect.top;

      // Only perform the move when the mouse has crossed half of the items height
      // When dragging downwards, only move when the cursor is below 50%
      // When dragging upwards, only move when the cursor is above 50%

      // Dragging downwards
      if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
        return;
      }

      // Dragging upwards
      if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
        return;
      }

      // Time to actually perform the action
      onMove(dragIndex, hoverIndex);

      // Note: we're mutating the monitor item here!
      // Generally it's better to avoid mutations,
      // but it's good here for the sake of performance
      // to avoid expensive index searches.
      item.index = hoverIndex;
    },
  });

  const [collectedProps, drag, previewRef] = useDrag({
    item: { index, type },
    collect,
  });

  drag(drop(dragRef));

  return [dragRef, previewRef, collectedProps];
}
Example #3
Source File: index.tsx    From uno-game with MIT License 5 votes vote down vote up
CustomCardDragPreview: React.FC = () => {
	const {
		itemType,
		isDragging,
		item,
		initialOffset,
		currentOffset,
	} = useDragLayer((monitor) => ({
		item: monitor.getItem() as DraggedCardItem,
		itemType: monitor.getItemType(),
		initialOffset: monitor.getInitialSourceClientOffset(),
		currentOffset: monitor.getSourceClientOffset(),
		isDragging: monitor.isDragging(),
	}))

	const classes = useStyles()
	const cardStore = useCardStore()

	const getItemStyles = (initialOffset: XYCoord | null, currentOffset: XYCoord | null) => {
		if (!initialOffset || !currentOffset) {
			return {
				display: "none",
			}
		}

		const { x, y } = currentOffset

		const transform = `translate(${x}px, ${y}px)`

		return {
			transform,
			WebkitTransform: transform,
			position: "relative" as const,
			width: 0,
		}
	}

	if (isDragging) {
		return (
			<div className={classes.container} >
				<div style={getItemStyles(initialOffset, currentOffset)}>
					{itemType === CARD_TYPE &&
            cardStore?.selectedCards?.length &&
            cardStore?.selectedCards?.every(card => card.type === item.cardType) ? (
							<>
								{cardStore?.selectedCards?.map((card, index) => (
									<img
										key={index}
										alt={card.name}
										src={card.src}
										className={item.className}
										style={{
											filter: "saturate(1.5)",
											left: +index * 20,
											position: "absolute",
										}}
									/>
								))}
							</>
						) : (
							<img
								alt={item.name}
								src={item.src}
								className={item.className}
								style={{ filter: "saturate(1.5)" }}
							/>
						)}
				</div>
			</div>
		)
	} else {
		return <React.Fragment />
	}
}
Example #4
Source File: ElementListItemDraggable.tsx    From openchakra with MIT License 5 votes vote down vote up
ElementListItemDraggable: React.FC<Props> = ({
  type,
  id,
  onSelect,
  moveItem,
  index,
  onHover,
  onUnhover,
  name,
}) => {
  const ref = useRef<HTMLDivElement>(null)
  const [, drop] = useDrop({
    accept: ITEM_TYPE,
    hover(item: DragObjectWithType, monitor) {
      if (!ref.current) {
        return
      }
      // @ts-ignore
      const dragIndex = item.index
      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 as XYCoord).y - hoverBoundingRect.top
      if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
        return
      }
      if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
        return
      }
      if (moveItem) {
        moveItem(dragIndex, hoverIndex)
      }
      // @ts-ignore
      item.index = hoverIndex
    },
  })
  const [{ isDragging }, drag] = useDrag({
    item: { type: ITEM_TYPE, id, index },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })

  const opacity = isDragging ? 0 : 1

  drag(drop(ref))

  const onSelectElement = () => {
    onSelect(id)
  }

  const onMouseOver = () => {
    onHover(id)
  }

  return (
    <ElementListItem
      ref={ref}
      onSelect={onSelectElement}
      opacity={opacity}
      onMouseOver={onMouseOver}
      onMouseOut={onUnhover}
      type={type}
      draggable
      name={name}
    />
  )
}
Example #5
Source File: DraggableItem.tsx    From querybook with Apache License 2.0 4 votes vote down vote up
export function DraggableItem<T extends { id: any }>({
    children,
    className,
    index,
    originalIndex,
    onHoverMove,
    onMove,
    draggableItemType,
    resetHoverItems,

    itemInfo,
    canDrop,
}: IDraggableItemProps<T> & { children: React.ReactNode }) {
    const ref = useRef<HTMLLIElement>(null);
    const [{ isDragging }, drag] = useDrag({
        type: draggableItemType,
        item: { type: draggableItemType, index, originalIndex, itemInfo },
        collect: (monitor) => ({
            isDragging: !!monitor.isDragging(),
        }),
        end: (_, monitor) => {
            resetHoverItems();
        },
    });
    const [, drop] = useDrop({
        accept: draggableItemType,
        canDrop,
        drop: (item: IDragItem) => {
            onMove(item.originalIndex, item.index);
        },
        hover: (item: IDragItem, monitor: DropTargetMonitor) => {
            if (!ref.current) {
                return;
            }
            if (!monitor.canDrop()) {
                return;
            }
            const dragIndex = item.index;
            const hoverIndex = index;
            if (dragIndex === hoverIndex) {
                return;
            }
            // Determine rectangle on screen
            const hoverBoundingRect = ref.current?.getBoundingClientRect();

            // Get vertical middle
            const hoverMiddleY =
                (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;

            // Determine mouse position
            const clientOffset = monitor.getClientOffset();

            // Get pixels to the top
            const hoverClientY =
                (clientOffset as XYCoord).y - hoverBoundingRect.top;

            // Only perform the move when the mouse has crossed half of the items height
            // When dragging downwards, only move when the cursor is below 50%
            // When dragging upwards, only move when the cursor is above 50%

            // Dragging downwards
            if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
                return;
            }

            // Dragging upwards
            if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
                return;
            }

            // Time to actually perform the action
            onHoverMove(dragIndex, hoverIndex);

            // Note: we're mutating the monitor item here!
            // Generally it's better to avoid mutations,
            // but it's good here for the sake of performance
            // to avoid expensive index searches.
            item.index = hoverIndex;
        },
    });
    drag(drop(ref));

    // To hide the item that is being dragged
    const opacity = isDragging ? 0 : 1;

    return (
        <li
            className={'DraggableItem ' + (className ?? '')}
            style={{ opacity }}
            ref={ref}
        >
            {children}
        </li>
    );
}