1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-08-07 23:03:00 +03:00

Lexical: Finished off baseline shortcut implementation

This commit is contained in:
Dan Brown
2024-08-20 14:54:53 +01:00
parent aa1fac62d5
commit dbb2fe3e59
7 changed files with 124 additions and 85 deletions

View File

@@ -1,12 +1,17 @@
import {COMMAND_PRIORITY_HIGH, FORMAT_TEXT_COMMAND, KEY_ENTER_COMMAND, LexicalEditor} from "lexical";
import {$getSelection, COMMAND_PRIORITY_HIGH, FORMAT_TEXT_COMMAND, KEY_ENTER_COMMAND, LexicalEditor} from "lexical";
import {
cycleSelectionCalloutFormats,
formatCodeBlock,
formatCodeBlock, insertOrUpdateLink,
toggleSelectionAsBlockquote,
toggleSelectionAsHeading,
toggleSelectionAsHeading, toggleSelectionAsList,
toggleSelectionAsParagraph
} from "../utils/formats";
import {HeadingTagType} from "@lexical/rich-text";
import {EditorUiContext} from "../ui/framework/core";
import {$getNodeFromSelection} from "../utils/selection";
import {$isLinkNode, LinkNode} from "@lexical/link";
import {$showLinkForm} from "../ui/defaults/forms/objects";
import {showLinkSelector} from "../utils/links";
function headerHandler(editor: LexicalEditor, tag: HeadingTagType): boolean {
toggleSelectionAsHeading(editor, tag);
@@ -25,10 +30,9 @@ function toggleInlineCode(editor: LexicalEditor): boolean {
return true;
}
type ShortcutAction = (editor: LexicalEditor) => boolean;
type ShortcutAction = (editor: LexicalEditor, context: EditorUiContext) => boolean;
const actionsByKeys: Record<string, ShortcutAction> = {
// Save draft
'ctrl+s': () => {
window.$events.emit('editor-save-draft');
return true;
@@ -51,18 +55,35 @@ const actionsByKeys: Record<string, ShortcutAction> = {
'ctrl+shift+e': toggleInlineCode,
'ctrl+9': wrapFormatAction(cycleSelectionCalloutFormats),
// TODO Lists
// TODO Links
// TODO Link selector
'ctrl+o': wrapFormatAction((e) => toggleSelectionAsList(e, 'number')),
'ctrl+p': wrapFormatAction((e) => toggleSelectionAsList(e, 'bullet')),
'ctrl+k': (editor, context) => {
editor.getEditorState().read(() => {
const selectedLink = $getNodeFromSelection($getSelection(), $isLinkNode) as LinkNode | null;
$showLinkForm(selectedLink, context);
});
return true;
},
'ctrl+shift+k': (editor, context) => {
showLinkSelector(entity => {
insertOrUpdateLink(editor, {
text: entity.name,
title: entity.link,
target: '',
url: entity.link,
});
});
return true;
},
};
function createKeyDownListener(editor: LexicalEditor): (e: KeyboardEvent) => void {
function createKeyDownListener(context: EditorUiContext): (e: KeyboardEvent) => void {
return (event: KeyboardEvent) => {
// TODO - Mac Cmd support
const combo = `${event.ctrlKey ? 'ctrl+' : ''}${event.shiftKey ? 'shift+' : ''}${event.key}`.toLowerCase();
console.log(`pressed: ${combo}`);
// console.log(`pressed: ${combo}`);
if (actionsByKeys[combo]) {
const handled = actionsByKeys[combo](editor);
const handled = actionsByKeys[combo](context.editor, context);
if (handled) {
event.stopPropagation();
event.preventDefault();
@@ -78,11 +99,11 @@ function overrideDefaultCommands(editor: LexicalEditor) {
}, COMMAND_PRIORITY_HIGH);
}
export function registerShortcuts(editor: LexicalEditor) {
const listener = createKeyDownListener(editor);
overrideDefaultCommands(editor);
export function registerShortcuts(context: EditorUiContext) {
const listener = createKeyDownListener(context);
overrideDefaultCommands(context.editor);
return editor.registerRootListener((rootElement: null | HTMLElement, prevRootElement: null | HTMLElement) => {
return context.editor.registerRootListener((rootElement: null | HTMLElement, prevRootElement: null | HTMLElement) => {
// add the listener to the current root element
rootElement?.addEventListener('keydown', listener);
// remove the listener from the old root element