diff --git a/packages/lexical-react/src/LexicalComposer.tsx b/packages/lexical-react/src/LexicalComposer.tsx index c40568b7d6d..a26b25e55b0 100644 --- a/packages/lexical-react/src/LexicalComposer.tsx +++ b/packages/lexical-react/src/LexicalComposer.tsx @@ -23,7 +23,7 @@ import { Klass, LexicalEditor, LexicalNode, - LexicalNodeReplacement, + LexicalNodeReplacement, type PointType, } from 'lexical'; import {useMemo} from 'react'; import * as React from 'react'; @@ -47,6 +47,10 @@ export type InitialConfigType = Readonly<{ theme?: EditorThemeClasses; editorState?: InitialEditorStateType; html?: HTMLConfig; + customGetAdjacentNode?: ( + focus: PointType, + isBackward: boolean, + ) => null | LexicalNode; }>; type Props = React.PropsWithChildren<{ @@ -75,6 +79,7 @@ export function LexicalComposer({initialConfig, children}: Props): JSX.Element { if (editor === null) { const newEditor = createEditor({ + customGetAdjacentNode: initialConfig.customGetAdjacentNode, editable: initialConfig.editable, html, namespace, diff --git a/packages/lexical/src/LexicalEditor.ts b/packages/lexical/src/LexicalEditor.ts index 79b3bc0f3e3..7d8929a6d02 100644 --- a/packages/lexical/src/LexicalEditor.ts +++ b/packages/lexical/src/LexicalEditor.ts @@ -16,7 +16,7 @@ import type { import invariant from 'shared/invariant'; -import {$getRoot, $getSelection, TextNode} from '.'; +import {type PointType, $getRoot, $getSelection, TextNode} from '.'; import {FULL_RECONCILE, NO_DIRTY_NODES} from './LexicalConstants'; import {createEmptyEditorState} from './LexicalEditorState'; import {addRootElementEvents, removeRootElementEvents} from './LexicalEvents'; @@ -155,6 +155,10 @@ export type EditorConfig = { disableEvents?: boolean; namespace: string; theme: EditorThemeClasses; + customGetAdjacentNode?: ( + focus: PointType, + isBackward: boolean, + ) => null | LexicalNode; }; export type LexicalNodeReplacement = { @@ -184,6 +188,10 @@ export type CreateEditorArgs = { editable?: boolean; theme?: EditorThemeClasses; html?: HTMLConfig; + customGetAdjacentNode?: ( + focus: PointType, + isBackward: boolean, + ) => null | LexicalNode }; export type RegisteredNodes = Map; @@ -509,6 +517,7 @@ export function createEditor(editorConfig?: CreateEditorArgs): LexicalEditor { parentEditor, registeredNodes, { + customGetAdjacentNode: config.customGetAdjacentNode, disableEvents, namespace, theme, diff --git a/packages/lexical/src/LexicalUtils.ts b/packages/lexical/src/LexicalUtils.ts index 5df7b99c954..2b31fc4c8a0 100644 --- a/packages/lexical/src/LexicalUtils.ts +++ b/packages/lexical/src/LexicalUtils.ts @@ -1120,6 +1120,14 @@ export function $getAdjacentNode( focus: PointType, isBackward: boolean, ): null | LexicalNode { + const customGetAdjacentNode = getActiveEditor()._config.customGetAdjacentNode + if (customGetAdjacentNode) { + const result = customGetAdjacentNode(focus, isBackward) + if (result) { + return result + } + } + const focusOffset = focus.offset; if (focus.type === 'element') { const block = focus.getNode();