mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Lexical: Added horizontal rule node
This commit is contained in:
parent
72a0e081ca
commit
4e2820d6e3
@ -80,12 +80,16 @@ export function toggleSelectionBlockNodeType(editor: LexicalEditor, matcher: Lex
|
||||
});
|
||||
}
|
||||
|
||||
export function insertNewBlockNodeAtSelection(node: LexicalNode) {
|
||||
export function insertNewBlockNodeAtSelection(node: LexicalNode, insertAfter: boolean = true) {
|
||||
const selection = $getSelection();
|
||||
const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null;
|
||||
|
||||
if (blockElement) {
|
||||
blockElement.insertAfter(node);
|
||||
if (insertAfter) {
|
||||
blockElement.insertAfter(node);
|
||||
} else {
|
||||
blockElement.insertBefore(node);
|
||||
}
|
||||
} else {
|
||||
$getRoot().append(node);
|
||||
}
|
||||
|
64
resources/js/wysiwyg/nodes/horizontal-rule.ts
Normal file
64
resources/js/wysiwyg/nodes/horizontal-rule.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import {
|
||||
DOMConversion,
|
||||
DOMConversionMap, DOMConversionOutput,
|
||||
ElementNode,
|
||||
LexicalEditor,
|
||||
LexicalNode,
|
||||
SerializedElementNode,
|
||||
} from 'lexical';
|
||||
import type {EditorConfig} from "lexical/LexicalEditor";
|
||||
|
||||
export class HorizontalRuleNode extends ElementNode {
|
||||
|
||||
static getType() {
|
||||
return 'horizontal-rule';
|
||||
}
|
||||
|
||||
static clone(node: HorizontalRuleNode): HorizontalRuleNode {
|
||||
return new HorizontalRuleNode(node.__key);
|
||||
}
|
||||
|
||||
createDOM(_config: EditorConfig, _editor: LexicalEditor) {
|
||||
return document.createElement('hr');
|
||||
}
|
||||
|
||||
updateDOM(prevNode: unknown, dom: HTMLElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static importDOM(): DOMConversionMap|null {
|
||||
return {
|
||||
hr(node: HTMLElement): DOMConversion|null {
|
||||
return {
|
||||
conversion: (element: HTMLElement): DOMConversionOutput|null => {
|
||||
return {
|
||||
node: new HorizontalRuleNode(),
|
||||
};
|
||||
},
|
||||
priority: 3,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
exportJSON(): SerializedElementNode {
|
||||
return {
|
||||
...super.exportJSON(),
|
||||
type: 'horizontal-rule',
|
||||
version: 1,
|
||||
};
|
||||
}
|
||||
|
||||
static importJSON(serializedNode: SerializedElementNode): HorizontalRuleNode {
|
||||
return $createHorizontalRuleNode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function $createHorizontalRuleNode() {
|
||||
return new HorizontalRuleNode();
|
||||
}
|
||||
|
||||
export function $isHorizontalRuleNode(node: LexicalNode | null | undefined) {
|
||||
return node instanceof HorizontalRuleNode;
|
||||
}
|
@ -8,6 +8,7 @@ import {DetailsNode, SummaryNode} from "./details";
|
||||
import {ListItemNode, ListNode} from "@lexical/list";
|
||||
import {TableCellNode, TableNode, TableRowNode} from "@lexical/table";
|
||||
import {CustomTableNode} from "./custom-table";
|
||||
import {HorizontalRuleNode} from "./horizontal-rule";
|
||||
|
||||
/**
|
||||
* Load the nodes for lexical.
|
||||
@ -23,6 +24,7 @@ export function getNodesForPageEditor(): (KlassConstructor<typeof LexicalNode> |
|
||||
TableRowNode,
|
||||
TableCellNode,
|
||||
ImageNode,
|
||||
HorizontalRuleNode,
|
||||
DetailsNode, SummaryNode,
|
||||
CustomParagraphNode,
|
||||
LinkNode,
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
UNDO_COMMAND
|
||||
} from "lexical";
|
||||
import {
|
||||
getNodeFromSelection,
|
||||
getNodeFromSelection, insertNewBlockNodeAtSelection,
|
||||
selectionContainsNodeType,
|
||||
selectionContainsTextFormat,
|
||||
toggleSelectionBlockNodeType
|
||||
@ -47,8 +47,10 @@ import listCheckIcon from "@icons/editor/list-check.svg"
|
||||
import linkIcon from "@icons/editor/link.svg"
|
||||
import tableIcon from "@icons/editor/table.svg"
|
||||
import imageIcon from "@icons/editor/image.svg"
|
||||
import horizontalRuleIcon from "@icons/editor/horizontal-rule.svg"
|
||||
import detailsIcon from "@icons/editor/details.svg"
|
||||
import sourceIcon from "@icons/editor/source-view.svg"
|
||||
import {$createHorizontalRuleNode, $isHorizontalRuleNode, HorizontalRuleNode} from "../../nodes/horizontal-rule";
|
||||
|
||||
export const undo: EditorButtonDefinition = {
|
||||
label: 'Undo',
|
||||
@ -294,6 +296,19 @@ export const image: EditorButtonDefinition = {
|
||||
}
|
||||
};
|
||||
|
||||
export const horizontalRule: EditorButtonDefinition = {
|
||||
label: 'Insert horizontal line',
|
||||
icon: horizontalRuleIcon,
|
||||
action(context: EditorUiContext) {
|
||||
context.editor.update(() => {
|
||||
insertNewBlockNodeAtSelection($createHorizontalRuleNode(), false);
|
||||
});
|
||||
},
|
||||
isActive(selection: BaseSelection|null): boolean {
|
||||
return selectionContainsNodeType(selection, $isHorizontalRuleNode);
|
||||
}
|
||||
};
|
||||
|
||||
export const details: EditorButtonDefinition = {
|
||||
label: 'Insert collapsible block',
|
||||
icon: detailsIcon,
|
||||
|
@ -2,7 +2,7 @@ import {EditorButton} from "./framework/buttons";
|
||||
import {
|
||||
blockquote, bold, bulletList, clearFormating, code,
|
||||
dangerCallout, details,
|
||||
h2, h3, h4, h5, highlightColor, image,
|
||||
h2, h3, h4, h5, highlightColor, horizontalRule, image,
|
||||
infoCallout, italic, link, numberList, paragraph,
|
||||
redo, source, strikethrough, subscript,
|
||||
successCallout, superscript, table, taskList, textColor, underline,
|
||||
@ -67,6 +67,7 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
|
||||
new EditorTableCreator(),
|
||||
]),
|
||||
new EditorButton(image),
|
||||
new EditorButton(horizontalRule),
|
||||
new EditorButton(details),
|
||||
|
||||
// Meta elements
|
||||
@ -74,21 +75,10 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
|
||||
|
||||
// Test
|
||||
new EditorButton({
|
||||
label: 'Expand table col 2',
|
||||
label: 'Test button',
|
||||
action(context: EditorUiContext) {
|
||||
context.editor.update(() => {
|
||||
const root = $getRoot();
|
||||
let table: CustomTableNode|null = null;
|
||||
for (const child of root.getChildren()) {
|
||||
if ($isCustomTableNode(child)) {
|
||||
table = child as CustomTableNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (table) {
|
||||
$setTableColumnWidth(table, 1, 500);
|
||||
}
|
||||
// Do stuff
|
||||
});
|
||||
},
|
||||
isActive() {
|
||||
|
Loading…
Reference in New Issue
Block a user