Skip to content

Commit

Permalink
Merge pull request #4000 from udecode/perf/draggable
Browse files Browse the repository at this point in the history
Improve performance of drag and drop
  • Loading branch information
zbeyens authored Jan 17, 2025
2 parents 4317799 + c4acb9b commit 493086a
Show file tree
Hide file tree
Showing 15 changed files with 163 additions and 135 deletions.
5 changes: 5 additions & 0 deletions .changeset/tiny-adults-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@udecode/plate-dnd': patch
---

Improve performance of drag and drop
14 changes: 7 additions & 7 deletions apps/www/content/docs/cn/dnd.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ const plugins = [
<APIParameters>
<APIItem name="options" type="UseDndNodeOptions">
<APISubList>
<APISubListItem parent="options" name="id" type="string">
要拖动的节点的 ID
<APISubListItem parent="options" name="element" type="TElement">
要拖动的节点
</APISubListItem>
<APISubListItem parent="options" name="type" type="string">
拖动项的类型。默认为 `'block'`
Expand Down Expand Up @@ -247,10 +247,10 @@ const plugins = [
编辑器实例。
</APIItem>
<APIItem name="options" type="UseDragNodeOptions">
拖动行为的选项,包括要拖动的节点的唯一 ID。
拖动行为的选项,包括要拖动的节点,该节点必须有一个唯一的 ID。
<APISubList>
<APISubListItem parent="options" name="id" type="string">
要拖动的节点的唯一 ID
<APISubListItem parent="options" name="element" type="TElement">
要拖动的节点
</APISubListItem>
<APISubListItem
parent="options"
Expand Down Expand Up @@ -314,8 +314,8 @@ const plugins = [
<APISubListItem parent="options" name="nodeRef" type="any">
被拖动节点的引用。
</APISubListItem>
<APISubListItem parent="options" name="id" type="string">
节点的 ID
<APISubListItem parent="options" name="element" type="TElement">
节点
</APISubListItem>
<APISubListItem parent="options" name="dropLine" type="string">
放置线的当前值。
Expand Down
16 changes: 8 additions & 8 deletions apps/www/content/docs/en/dnd.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ A custom hook that combines the `useDragNode` and `useDropNode` hooks to enable
<APIParameters>
<APIItem name="options" type="UseDndNodeOptions">
<APISubList>
<APISubListItem parent="options" name="id" type="string">
The ID of the node to be dragged.
<APISubListItem parent="options" name="element" type="TElement">
The node to be dragged.
</APISubListItem>
<APISubListItem parent="options" name="type" type="string">
The type of drag item. Defaults to `'block'`.
Expand Down Expand Up @@ -251,11 +251,11 @@ A custom hook that enables dragging of a node from the editor using the `useDrag
The editor instance.
</APIItem>
<APIItem name="options" type="UseDragNodeOptions">
The options for the drag behavior, including the unique ID of the node to be
dragged.
The options for the drag behavior, including the node to be dragged, which
must have a unique ID.
<APISubList>
<APISubListItem parent="options" name="id" type="string">
The unique ID of the node to be dragged.
<APISubListItem parent="options" name="element" type="TElement">
The node to be dragged.
</APISubListItem>
<APISubListItem
parent="options"
Expand Down Expand Up @@ -319,8 +319,8 @@ A custom hook that enables dropping a node on the editor. It uses the `useDrop`
<APISubListItem parent="options" name="nodeRef" type="any">
The reference to the node being dragged.
</APISubListItem>
<APISubListItem parent="options" name="id" type="string">
The ID of the node.
<APISubListItem parent="options" name="element" type="TElement">
The node to which the drop line is attached.
</APISubListItem>
<APISubListItem parent="options" name="dropLine" type="string">
The current value of the drop line.
Expand Down
8 changes: 1 addition & 7 deletions packages/dnd/src/components/useDraggable.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React from 'react';

import type { TElement } from '@udecode/plate';

import { useEditorRef } from '@udecode/plate/react';

import { type UseDndNodeOptions, DRAG_ITEM_BLOCK, useDndNode } from '..';
Expand All @@ -16,11 +14,8 @@ export type DraggableState = {
) => void;
};

export const useDraggable = (
props: UseDndNodeOptions & { element: TElement }
): DraggableState => {
export const useDraggable = (props: UseDndNodeOptions): DraggableState => {
const {
element,
orientation = 'vertical',
type = DRAG_ITEM_BLOCK,
onDropHandler,
Expand All @@ -34,7 +29,6 @@ export const useDraggable = (

// eslint-disable-next-line react-hooks/rules-of-hooks
const { dragRef, isDragging } = useDndNode({
id: element.id as string,
nodeRef,
orientation,
type,
Expand Down
21 changes: 11 additions & 10 deletions packages/dnd/src/components/useDropLine.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEditorPlugin, useElement } from '@udecode/plate/react';
import { useEditorRef, useElement } from '@udecode/plate/react';

import type { DropLineDirection } from '../types';

Expand All @@ -14,17 +14,18 @@ export const useDropLine = ({
} = {}): {
dropLine?: DropLineDirection;
} => {
const editor = useEditorRef();
const element = useElement();
const id = idProp || (element.id as string);
const dropTarget = useEditorPlugin(DndPlugin).useOption('dropTarget');
const dropLine = dropTarget?.line;

// Only show dropline for currently hovered element
if (id && dropTarget?.id !== id) {
return {
dropLine: '',
};
}

const dropLine =
editor.useOptions(DndPlugin, ({ dropTarget }) => {
if (!dropTarget) return null;
if (dropTarget.id !== id) return null;

return dropTarget.line;
}) ?? '';

if (orientation) {
const isHorizontalDropLine = dropLine === 'left' || dropLine === 'right';
const isVerticalDropLine = dropLine === 'top' || dropLine === 'bottom';
Expand Down
19 changes: 10 additions & 9 deletions packages/dnd/src/hooks/useDndNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import { DRAG_ITEM_BLOCK, DndPlugin } from '../DndPlugin';
import { type UseDragNodeOptions, useDragNode } from './useDragNode';
import { type UseDropNodeOptions, useDropNode } from './useDropNode';

export type UseDndNodeOptions = Partial<
Pick<UseDropNodeOptions, 'canDropNode' | 'id' | 'nodeRef'>
> &
export type UseDndNodeOptions = Pick<UseDropNodeOptions, 'element'> &
Partial<Pick<UseDropNodeOptions, 'canDropNode' | 'nodeRef'>> &
Partial<Pick<UseDragNodeOptions, 'type'>> & {
/** Options passed to the drop hook, excluding element, nodeRef. */
drop?: Partial<
Omit<UseDropNodeOptions, 'canDropNode' | 'element' | 'nodeRef'>
>;

preview?: {
/** Whether to disable the preview. */
disable?: boolean;
Expand All @@ -26,9 +30,6 @@ export type UseDndNodeOptions = Partial<
/** Options passed to the drag hook. */
drag?: Partial<Omit<UseDragNodeOptions, 'type'>>;

/** Options passed to the drop hook, excluding id, nodeRef. */
drop?: Partial<Omit<UseDropNodeOptions, 'canDropNode' | 'id' | 'nodeRef'>>;

/** Orientation of the drag and drop interaction. */
orientation?: 'horizontal' | 'vertical';

Expand All @@ -49,10 +50,10 @@ export type UseDndNodeOptions = Partial<
* can be customized or removed. Returns the drag ref and drop line direction.
*/
export const useDndNode = ({
id = '',
canDropNode,
drag: dragOptions,
drop: dropOptions,
element,
nodeRef,
orientation = 'vertical',
preview: previewOptions = {},
Expand All @@ -66,15 +67,15 @@ export const useDndNode = ({
const editor = useEditorRef();

const [{ isDragging }, dragRef, preview] = useDragNode(editor, {
id,
element,
type,
...dragOptions,
});

const [{ isOver }, drop] = useDropNode(editor, {
id,
accept: [type, NativeTypes.FILE],
canDropNode,
element,
nodeRef,
orientation,
onDropHandler,
Expand Down
8 changes: 5 additions & 3 deletions packages/dnd/src/hooks/useDragNode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type DragSourceHookSpec, useDrag } from 'react-dnd';

import type { TElement } from '@udecode/plate';
import type { PlateEditor } from '@udecode/plate/react';

import type { DragItemNode } from '../types';
Expand All @@ -8,7 +9,7 @@ import { DndPlugin } from '../DndPlugin';

export interface UseDragNodeOptions
extends DragSourceHookSpec<DragItemNode, unknown, { isDragging: boolean }> {
id: string;
element: TElement;
}

/**
Expand All @@ -30,7 +31,7 @@ export interface UseDragNodeOptions
*/
export const useDragNode = (
editor: PlateEditor,
{ id, item, ...options }: UseDragNodeOptions
{ element, item, ...options }: UseDragNodeOptions
) => {
return useDrag<DragItemNode, unknown, { isDragging: boolean }>(
() => ({
Expand All @@ -48,8 +49,9 @@ export const useDragNode = (
const _item = typeof item === 'function' ? item(monitor) : item;

return {
id,
id: element.id as string,
editorId: editor.id,
element,
..._item,
};
},
Expand Down
14 changes: 8 additions & 6 deletions packages/dnd/src/hooks/useDropNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export type CanDropCallback = (args: {

export interface UseDropNodeOptions
extends DropTargetHookSpec<DragItemNode, unknown, { isOver: boolean }> {
/** Id of the node. */
id: string;
/** The node to which the drop line is attached. */
element: TElement;

/** The reference to the node being dragged. */
nodeRef: any;
Expand Down Expand Up @@ -76,14 +76,16 @@ export interface UseDropNodeOptions
export const useDropNode = (
editor: PlateEditor,
{
id,
canDropNode,
element,
nodeRef,
orientation,
onDropHandler,
...options
}: UseDropNodeOptions
) => {
const id = element.id as string;

return useDrop<DragItemNode, unknown, { isOver: boolean }>({
collect: (monitor) => ({
isOver: monitor.isOver({
Expand All @@ -95,9 +97,9 @@ export const useDropNode = (

if (!(dragItem as ElementDragItemNode).id) {
const result = getDropPath(editor, {
id,
canDropNode,
dragItem: dragItem as any,
element,
monitor,
nodeRef,
orientation,
Expand Down Expand Up @@ -129,18 +131,18 @@ export const useDropNode = (
if (handled) return;

onDropNode(editor, {
id,
dragItem: dragItem as ElementDragItemNode,
element,
monitor,
nodeRef,
orientation,
});
},
hover(item: DragItemNode, monitor: DropTargetMonitor) {
onHoverNode(editor, {
id,
canDropNode,
dragItem: item,
element,
monitor,
nodeRef,
orientation,
Expand Down
Loading

0 comments on commit 493086a

Please sign in to comment.