import type { JSX } from 'react' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { DraggableBlockPlugin_EXPERIMENTAL } from '@lexical/react/LexicalDraggableBlockPlugin' import { useEffect, useRef, useState } from 'react' import { cn } from '@/utils/classnames' const DRAGGABLE_BLOCK_MENU_CLASSNAME = 'draggable-block-menu' function isOnMenu(element: HTMLElement): boolean { return !!element.closest(`.${DRAGGABLE_BLOCK_MENU_CLASSNAME}`) } const SUPPORT_DRAG_CLASS = 'support-drag' function checkSupportDrag(element: Element | null): boolean { if (!element) return false if (element.classList.contains(SUPPORT_DRAG_CLASS)) return true if (element.querySelector(`.${SUPPORT_DRAG_CLASS}`)) return true return !!(element.closest(`.${SUPPORT_DRAG_CLASS}`)) } export default function DraggableBlockPlugin({ anchorElem = document.body, }: { anchorElem?: HTMLElement }): JSX.Element { const menuRef = useRef(null) const targetLineRef = useRef(null) const [, setDraggableElement] = useState( null, ) const [editor] = useLexicalComposerContext() const [isSupportDrag, setIsSupportDrag] = useState(false) useEffect(() => { const root = editor.getRootElement() if (!root) return const onMove = (e: MouseEvent) => { const isSupportDrag = checkSupportDrag(e.target as Element) setIsSupportDrag(isSupportDrag) } root.addEventListener('mousemove', onMove) return () => root.removeEventListener('mousemove', onMove) }, [editor]) return ( ) : null } targetLineComponent={(
)} isOnMenu={isOnMenu} onElementChanged={setDraggableElement} /> ) }