UNPKG

@lexical/react

Version:

This package provides Lexical components and hooks for React applications.

65 lines (59 loc) • 2.19 kB
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import { registerEventListener, $getNearestNodeFromDOMNode, $findMatchingParent } from 'lexical'; import { useRef, useEffect } from 'react'; /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ const capturedEvents = new Set(['mouseenter', 'mouseleave']); /** * Attaches a DOM event listener to the editor's root element and invokes * `eventListener` whenever an event of `eventType` targets a node that is (or * is contained by) an instance of `nodeType`. The listener receives the DOM * event, the editor, and the matching node's {@link NodeKey}. * * @returns `null`, this plugin renders no DOM of its own. */ function NodeEventPlugin({ nodeType, eventType, eventListener }) { const [editor] = useLexicalComposerContext(); const listenerRef = useRef(eventListener); listenerRef.current = eventListener; useEffect(() => { const isCaptured = capturedEvents.has(eventType); const onEvent = event => { editor.update(() => { const nearestNode = $getNearestNodeFromDOMNode(event.target); if (nearestNode !== null) { const targetNode = isCaptured ? nearestNode instanceof nodeType ? nearestNode : null : $findMatchingParent(nearestNode, node => node instanceof nodeType); if (targetNode !== null) { listenerRef.current(event, editor, targetNode.getKey()); return; } } }); }; return editor.registerRootListener(rootElement => { if (rootElement) { return registerEventListener(rootElement, eventType, onEvent, isCaptured); } }); // We intentionally don't respect changes to eventType. // eslint-disable-next-line react-hooks/exhaustive-deps }, [editor, nodeType]); return null; } export { NodeEventPlugin };