From a77f22b160fee95fdbda34231e8864c57a5195ee Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 21 Oct 2023 11:59:04 +0530 Subject: [PATCH] smartly exit formatting with backspace --- src/app/components/editor/keyboard.ts | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index 1b4293177..0bcd36980 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -1,6 +1,6 @@ import { isKeyHotkey } from 'is-hotkey'; import { KeyboardEvent } from 'react'; -import { Editor } from 'slate'; +import { Editor, Range } from 'slate'; import { isAnyMarkActive, isBlockActive, removeAllMark, toggleBlock, toggleMark } from './utils'; import { BlockType, MarkType } from './types'; @@ -26,6 +26,35 @@ const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS); * @return boolean true if shortcut is toggled. */ export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent): boolean => { + if (isKeyHotkey('backspace', event) && editor.selection && Range.isCollapsed(editor.selection)) { + const startPoint = Range.start(editor.selection); + if (startPoint.offset !== 0) return false; + + const [parentNode, parentPath] = Editor.parent(editor, startPoint); + + if (Editor.isEditor(parentNode)) return false; + + if (parentNode.type === BlockType.Heading) { + toggleBlock(editor, BlockType.Paragraph); + return true; + } + if ( + parentNode.type === BlockType.CodeLine || + parentNode.type === BlockType.QuoteLine || + parentNode.type === BlockType.ListItem + ) { + // exit formatting only when line block + // is first of last of it's parent + const parentLocation = { at: parentPath }; + const [previousNode] = Editor.previous(editor, parentLocation) ?? []; + const [nextNode] = Editor.next(editor, parentLocation) ?? []; + if (!previousNode || !nextNode) { + toggleBlock(editor, BlockType.Paragraph); + return true; + } + } + } + if (isKeyHotkey('mod+e', event)) { if (isAnyMarkActive(editor)) { removeAllMark(editor);