diff --git a/components/Blocks/TextBlock/keymap.ts b/components/Blocks/TextBlock/keymap.ts index 3f9c1402..928fe9cb 100644 --- a/components/Blocks/TextBlock/keymap.ts +++ b/components/Blocks/TextBlock/keymap.ts @@ -111,9 +111,11 @@ export const TextBlockKeymap = ( ArrowUp: moveCursorUp(propsRef, repRef), "Ctrl-j": moveCursorDown(propsRef, repRef, true), ArrowDown: moveCursorDown(propsRef, repRef), - ArrowLeft: (state, tr, view) => { - if (state.selection.content().size > 0) return false; + ArrowLeft: (state, dispatch, view) => { + if (!state.selection.empty) return false; + if (skipFootnote(state, dispatch, "before")) return true; if (state.selection.anchor > 1) return false; + if (clearStoredMarks(state, dispatch)) return true; let block = propsRef.current.previousBlock; if (block) { view?.dom.blur(); @@ -121,9 +123,11 @@ export const TextBlockKeymap = ( } return true; }, - ArrowRight: (state, tr, view) => { - if (state.selection.content().size > 0) return false; + ArrowRight: (state, dispatch, view) => { + if (!state.selection.empty) return false; + if (skipFootnote(state, dispatch, "after")) return true; if (state.doc.content.size - state.selection.anchor > 1) return false; + if (clearStoredMarks(state, dispatch)) return true; let block = propsRef.current.nextBlock; if (block) { view?.dom.blur(); @@ -153,6 +157,36 @@ export const TextBlockKeymap = ( "Meta-Enter": CtrlEnter(propsRef, repRef), }) as { [key: string]: Command }; +const skipFootnote = ( + state: EditorState, + dispatch: ((tr: Transaction) => void) | undefined, + side: "before" | "after", +) => { + let node = + side === "before" + ? state.selection.$from.nodeBefore + : state.selection.$from.nodeAfter; + if (node?.type !== schema.nodes.footnote) return false; + let delta = side === "before" ? -node.nodeSize : node.nodeSize; + if (dispatch) + dispatch( + state.tr.setSelection( + TextSelection.create(state.doc, state.selection.from + delta), + ), + ); + return true; +}; + +const clearStoredMarks = ( + state: EditorState, + dispatch: ((tr: Transaction) => void) | undefined, +) => { + let marks = state.storedMarks ?? state.selection.$from.marks(); + if (marks.length === 0) return false; + if (dispatch) dispatch(state.tr.setStoredMarks([])); + return true; +}; + const moveCursorDown = ( propsRef: PropsRef,