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/.changeset/new-coins-suffer.md b/.changeset/new-coins-suffer.md new file mode 100644 index 0000000000..d4ef965b1d --- /dev/null +++ b/.changeset/new-coins-suffer.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-utils': patch +--- + +Do not re-render placeholder on every editor change 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, }, diff --git a/packages/plate-utils/src/hooks/usePlaceholder.ts b/packages/plate-utils/src/hooks/usePlaceholder.ts index 4eaf9e7db7..56af2aed99 100644 --- a/packages/plate-utils/src/hooks/usePlaceholder.ts +++ b/packages/plate-utils/src/hooks/usePlaceholder.ts @@ -1,4 +1,4 @@ -import { useEditorState } from '@udecode/plate-core'; +import { useEditorRef } from '@udecode/plate-core'; import { isCollapsed, isElementEmpty, @@ -23,7 +23,7 @@ export const usePlaceholderState = ({ }: PlaceholderProps) => { const focused = useFocused(); const selected = useSelected(); - const editor = useEditorState(); + const editor = useEditorRef(); const isEmptyBlock = isElementEmpty(editor, element);