From cf83eb6a5abe2c1a5dfd7a22bcd1048b4cd3d1cf Mon Sep 17 00:00:00 2001 From: Joe Anderson Date: Thu, 19 Oct 2023 16:24:27 +0100 Subject: [PATCH] Improve performance of draggable component --- .changeset/chilled-candles-hunt.md | 5 ++++ .../registry/default/plate-ui/draggable.tsx | 30 +++++++++++++------ packages/dnd/src/components/useDraggable.ts | 18 +++++++++-- 3 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 .changeset/chilled-candles-hunt.md diff --git a/.changeset/chilled-candles-hunt.md b/.changeset/chilled-candles-hunt.md new file mode 100644 index 0000000000..80278a0a3b --- /dev/null +++ b/.changeset/chilled-candles-hunt.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-dnd': patch +--- + +Reduce performance overhead of draggable component diff --git a/apps/www/src/registry/default/plate-ui/draggable.tsx b/apps/www/src/registry/default/plate-ui/draggable.tsx index 82c4e503b0..d05f632ff5 100644 --- a/apps/www/src/registry/default/plate-ui/draggable.tsx +++ b/apps/www/src/registry/default/plate-ui/draggable.tsx @@ -77,14 +77,28 @@ export interface DraggableProps ) => boolean; } +const dragHandle = ( + + + + + Drag to move + +); + const Draggable = forwardRef( ({ className, classNames = {}, onDropHandler, ...props }, ref) => { const { children, element } = props; const state = useDraggableState({ element, onDropHandler }); - const { dropLine, isDragging } = state; - const { droplineProps, gutterLeftProps, previewRef, handleRef } = - useDraggable(state); + const { dropLine, isDragging, isHovered } = state; + const { + groupProps, + droplineProps, + gutterLeftProps, + previewRef, + handleRef, + } = useDraggable(state); return (
( className )} ref={ref} + {...groupProps} >
( classNames.blockToolbar )} > - - - - - Drag to move - +
+ {isHovered && dragHandle} +
diff --git a/packages/dnd/src/components/useDraggable.ts b/packages/dnd/src/components/useDraggable.ts index 3b41172f50..f3a57e6768 100644 --- a/packages/dnd/src/components/useDraggable.ts +++ b/packages/dnd/src/components/useDraggable.ts @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useRef, useState } from 'react'; import { TEditor, TElement } from '@udecode/plate-common'; import { ConnectDragSource, DropTargetMonitor } from 'react-dnd'; @@ -6,6 +6,8 @@ import { DragItemNode, DropLineDirection, useDndBlock } from '..'; export type DraggableState = { dropLine: DropLineDirection; + isHovered: boolean; + setIsHovered: (isHovered: boolean) => void; isDragging: boolean; nodeRef: React.RefObject; dragRef: ConnectDragSource; @@ -26,19 +28,31 @@ export const useDraggableState = (props: { const { element, onDropHandler } = props; const nodeRef = useRef(null); + const [isHovered, setIsHovered] = useState(false); const { dropLine, isDragging, dragRef } = useDndBlock({ id: element.id as string, nodeRef, onDropHandler, }); - return { dropLine, isDragging, nodeRef, dragRef }; + return { + dropLine, + isHovered, + setIsHovered, + isDragging, + nodeRef, + dragRef, + }; }; export const useDraggable = (state: DraggableState) => { return { previewRef: state.nodeRef, handleRef: state.dragRef, + groupProps: { + onPointerEnter: () => state.setIsHovered(true), + onPointerLeave: () => state.setIsHovered(false), + }, droplineProps: { contentEditable: false, },