mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-23 12:20:21 +00:00
Lexical: Improved navigation around images/media
- Added specific handling to move/insert-up/down on arrow press. - Prevented resize overlay from interrupting image node focus.
This commit is contained in:
parent
62c8eb3357
commit
9bfcadd95f
3 changed files with 43 additions and 4 deletions
resources
|
@ -133,7 +133,7 @@ export class ImageNode extends ElementNode {
|
||||||
|
|
||||||
element.addEventListener('click', e => {
|
element.addEventListener('click', e => {
|
||||||
_editor.update(() => {
|
_editor.update(() => {
|
||||||
$selectSingleNode(this);
|
this.select();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
$createParagraphNode,
|
$createParagraphNode,
|
||||||
$getSelection,
|
$getSelection,
|
||||||
$isDecoratorNode,
|
$isDecoratorNode,
|
||||||
COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND,
|
COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND,
|
||||||
KEY_BACKSPACE_COMMAND,
|
KEY_BACKSPACE_COMMAND,
|
||||||
KEY_DELETE_COMMAND,
|
KEY_DELETE_COMMAND,
|
||||||
KEY_ENTER_COMMAND, KEY_TAB_COMMAND,
|
KEY_ENTER_COMMAND, KEY_TAB_COMMAND,
|
||||||
|
@ -43,7 +43,7 @@ function deleteSingleSelectedNode(editor: LexicalEditor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a new empty node after the selection if the selection contains a single
|
* Insert a new empty node before/after the selection if the selection contains a single
|
||||||
* selected node (like image, media etc...).
|
* selected node (like image, media etc...).
|
||||||
*/
|
*/
|
||||||
function insertAfterSingleSelectedNode(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
|
function insertAfterSingleSelectedNode(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
|
||||||
|
@ -67,6 +67,37 @@ function insertAfterSingleSelectedNode(editor: LexicalEditor, event: KeyboardEve
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function focusAdjacentOrInsertForSingleSelectNode(editor: LexicalEditor, event: KeyboardEvent|null, after: boolean = true): boolean {
|
||||||
|
const selectionNodes = getLastSelection(editor)?.getNodes() || [];
|
||||||
|
if (!isSingleSelectedNode(selectionNodes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
event?.preventDefault();
|
||||||
|
|
||||||
|
const node = selectionNodes[0];
|
||||||
|
const nearestBlock = $getNearestNodeBlockParent(node) || node;
|
||||||
|
let target = after ? nearestBlock.getNextSibling() : nearestBlock.getPreviousSibling();
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
editor.update(() => {
|
||||||
|
if (!target) {
|
||||||
|
target = $createParagraphNode();
|
||||||
|
if (after) {
|
||||||
|
nearestBlock.insertAfter(target)
|
||||||
|
} else {
|
||||||
|
nearestBlock.insertBefore(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target.selectStart();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a new node after a details node, if inside a details node that's
|
* Insert a new node after a details node, if inside a details node that's
|
||||||
* the last element, and if the cursor is at the last block within the details node.
|
* the last element, and if the cursor is at the last block within the details node.
|
||||||
|
@ -199,8 +230,13 @@ export function registerKeyboardHandling(context: EditorUiContext): () => void {
|
||||||
return handleInsetOnTab(context.editor, event);
|
return handleInsetOnTab(context.editor, event);
|
||||||
}, COMMAND_PRIORITY_LOW);
|
}, COMMAND_PRIORITY_LOW);
|
||||||
|
|
||||||
|
const unregisterUp = context.editor.registerCommand(KEY_ARROW_UP_COMMAND, (event): boolean => {
|
||||||
|
return focusAdjacentOrInsertForSingleSelectNode(context.editor, event, false);
|
||||||
|
}, COMMAND_PRIORITY_LOW);
|
||||||
|
|
||||||
const unregisterDown = context.editor.registerCommand(KEY_ARROW_DOWN_COMMAND, (event): boolean => {
|
const unregisterDown = context.editor.registerCommand(KEY_ARROW_DOWN_COMMAND, (event): boolean => {
|
||||||
return insertAfterDetails(context.editor, event);
|
return insertAfterDetails(context.editor, event)
|
||||||
|
|| focusAdjacentOrInsertForSingleSelectNode(context.editor, event, true)
|
||||||
}, COMMAND_PRIORITY_LOW);
|
}, COMMAND_PRIORITY_LOW);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
@ -208,6 +244,7 @@ export function registerKeyboardHandling(context: EditorUiContext): () => void {
|
||||||
unregisterDelete();
|
unregisterDelete();
|
||||||
unregisterEnter();
|
unregisterEnter();
|
||||||
unregisterTab();
|
unregisterTab();
|
||||||
|
unregisterUp();
|
||||||
unregisterDown();
|
unregisterDown();
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -370,8 +370,10 @@ body.editor-is-fullscreen {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
outline: 2px dashed var(--editor-color-primary);
|
outline: 2px dashed var(--editor-color-primary);
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.editor-node-resizer-handle {
|
.editor-node-resizer-handle {
|
||||||
|
pointer-events: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: block;
|
display: block;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
|
|
Loading…
Add table
Reference in a new issue