diff --git a/package-lock.json b/package-lock.json index 2cddccb59..0757e7868 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@lexical/history": "^0.15.0", "@lexical/html": "^0.15.0", "@lexical/link": "^0.15.0", + "@lexical/list": "^0.15.0", "@lexical/rich-text": "^0.15.0", "@lexical/selection": "^0.15.0", "@lexical/utils": "^0.15.0", diff --git a/package.json b/package.json index d9fa89c18..732bb1759 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@lexical/history": "^0.15.0", "@lexical/html": "^0.15.0", "@lexical/link": "^0.15.0", + "@lexical/list": "^0.15.0", "@lexical/rich-text": "^0.15.0", "@lexical/selection": "^0.15.0", "@lexical/utils": "^0.15.0", diff --git a/resources/js/wysiwyg/nodes/index.ts b/resources/js/wysiwyg/nodes/index.ts index f47575bc5..03fcd33a5 100644 --- a/resources/js/wysiwyg/nodes/index.ts +++ b/resources/js/wysiwyg/nodes/index.ts @@ -5,6 +5,7 @@ import {CustomParagraphNode} from "./custom-paragraph"; import {LinkNode} from "@lexical/link"; import {ImageNode} from "./image"; import {DetailsNode, SummaryNode} from "./details"; +import {ListItemNode, ListNode} from "@lexical/list"; /** * Load the nodes for lexical. @@ -14,6 +15,8 @@ export function getNodesForPageEditor(): (KlassConstructor | CalloutNode, // Todo - Create custom HeadingNode, // Todo - Create custom QuoteNode, // Todo - Create custom + ListNode, // Todo - Create custom + ListItemNode, ImageNode, DetailsNode, SummaryNode, CustomParagraphNode, diff --git a/resources/js/wysiwyg/ui/defaults/button-definitions.ts b/resources/js/wysiwyg/ui/defaults/button-definitions.ts index d8c7f515c..57460ef60 100644 --- a/resources/js/wysiwyg/ui/defaults/button-definitions.ts +++ b/resources/js/wysiwyg/ui/defaults/button-definitions.ts @@ -1,11 +1,11 @@ import {EditorBasicButtonDefinition, EditorButtonDefinition} from "../framework/buttons"; import { $createNodeSelection, - $createParagraphNode, $getRoot, $getSelection, $insertNodes, + $createParagraphNode, $getRoot, $getSelection, $isParagraphNode, $isTextNode, $setSelection, BaseSelection, ElementNode, FORMAT_TEXT_COMMAND, LexicalNode, - REDO_COMMAND, TextFormatType, TextNode, + REDO_COMMAND, TextFormatType, UNDO_COMMAND } from "lexical"; import { @@ -23,12 +23,12 @@ import { HeadingNode, HeadingTagType } from "@lexical/rich-text"; -import {$isLinkNode, $toggleLink, LinkNode} from "@lexical/link"; +import {$isLinkNode, LinkNode} from "@lexical/link"; import {EditorUiContext} from "../framework/core"; import {$isImageNode, ImageNode} from "../../nodes/image"; import {$createDetailsNode, $isDetailsNode} from "../../nodes/details"; -import {$insertNodeToNearestRoot} from "@lexical/utils"; import {getEditorContentAsHtml} from "../../actions"; +import {$isListNode, insertList, ListNode, ListType, removeList} from "@lexical/list"; export const undo: EditorButtonDefinition = { label: 'Undo', @@ -155,6 +155,31 @@ export const clearFormating: EditorButtonDefinition = { } }; +function buildListButton(label: string, type: ListType): EditorButtonDefinition { + return { + label, + action(context: EditorUiContext) { + context.editor.getEditorState().read(() => { + const selection = $getSelection(); + if (this.isActive(selection)) { + removeList(context.editor); + } else { + insertList(context.editor, type); + } + }); + }, + isActive(selection: BaseSelection|null): boolean { + return selectionContainsNodeType(selection, (node: LexicalNode | null | undefined): boolean => { + return $isListNode(node) && (node as ListNode).getListType() === type; + }); + } + }; +} + +export const bulletList: EditorButtonDefinition = buildListButton('Bullet list', 'bullet'); +export const numberList: EditorButtonDefinition = buildListButton('Numbered list', 'number'); +export const taskList: EditorButtonDefinition = buildListButton('Task list', 'check'); + export const link: EditorButtonDefinition = { label: 'Insert/edit link', diff --git a/resources/js/wysiwyg/ui/toolbars.ts b/resources/js/wysiwyg/ui/toolbars.ts index de90a1d70..fe19b94ed 100644 --- a/resources/js/wysiwyg/ui/toolbars.ts +++ b/resources/js/wysiwyg/ui/toolbars.ts @@ -1,11 +1,11 @@ import {EditorButton} from "./framework/buttons"; import { - blockquote, bold, clearFormating, code, + blockquote, bold, bulletList, clearFormating, code, dangerCallout, details, h2, h3, h4, h5, highlightColor, image, - infoCallout, italic, link, paragraph, + infoCallout, italic, link, numberList, paragraph, redo, source, strikethrough, subscript, - successCallout, superscript, textColor, underline, + successCallout, superscript, taskList, textColor, underline, undo, warningCallout } from "./defaults/button-definitions"; @@ -53,6 +53,11 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement { new EditorButton(code), new EditorButton(clearFormating), + // Lists + new EditorButton(bulletList), + new EditorButton(numberList), + new EditorButton(taskList), + // Insert types new EditorButton(link), new EditorButton(image), diff --git a/resources/sass/_editor.scss b/resources/sass/_editor.scss index b98e624bd..13d8e96f9 100644 --- a/resources/sass/_editor.scss +++ b/resources/sass/_editor.scss @@ -6,6 +6,7 @@ // Main UI elements .editor-toolbar-main { display: flex; + flex-wrap: wrap; } // Buttons