});
}
-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);
}
--- /dev/null
+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;
+}
\ No newline at end of file
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.
TableRowNode,
TableCellNode,
ImageNode,
+ HorizontalRuleNode,
DetailsNode, SummaryNode,
CustomParagraphNode,
LinkNode,
UNDO_COMMAND
} from "lexical";
import {
- getNodeFromSelection,
+ getNodeFromSelection, insertNewBlockNodeAtSelection,
selectionContainsNodeType,
selectionContainsTextFormat,
toggleSelectionBlockNodeType
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',
}
};
+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,
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,
new EditorTableCreator(),
]),
new EditorButton(image),
+ new EditorButton(horizontalRule),
new EditorButton(details),
// Meta elements
// 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() {