mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-19 18:22:16 +03:00
Lexical: Added basic list button/support
This commit is contained in:
parent
9e43e03db4
commit
e2409a5fab
1
package-lock.json
generated
1
package-lock.json
generated
@ -21,6 +21,7 @@
|
|||||||
"@lexical/history": "^0.15.0",
|
"@lexical/history": "^0.15.0",
|
||||||
"@lexical/html": "^0.15.0",
|
"@lexical/html": "^0.15.0",
|
||||||
"@lexical/link": "^0.15.0",
|
"@lexical/link": "^0.15.0",
|
||||||
|
"@lexical/list": "^0.15.0",
|
||||||
"@lexical/rich-text": "^0.15.0",
|
"@lexical/rich-text": "^0.15.0",
|
||||||
"@lexical/selection": "^0.15.0",
|
"@lexical/selection": "^0.15.0",
|
||||||
"@lexical/utils": "^0.15.0",
|
"@lexical/utils": "^0.15.0",
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
"@lexical/history": "^0.15.0",
|
"@lexical/history": "^0.15.0",
|
||||||
"@lexical/html": "^0.15.0",
|
"@lexical/html": "^0.15.0",
|
||||||
"@lexical/link": "^0.15.0",
|
"@lexical/link": "^0.15.0",
|
||||||
|
"@lexical/list": "^0.15.0",
|
||||||
"@lexical/rich-text": "^0.15.0",
|
"@lexical/rich-text": "^0.15.0",
|
||||||
"@lexical/selection": "^0.15.0",
|
"@lexical/selection": "^0.15.0",
|
||||||
"@lexical/utils": "^0.15.0",
|
"@lexical/utils": "^0.15.0",
|
||||||
|
@ -5,6 +5,7 @@ import {CustomParagraphNode} from "./custom-paragraph";
|
|||||||
import {LinkNode} from "@lexical/link";
|
import {LinkNode} from "@lexical/link";
|
||||||
import {ImageNode} from "./image";
|
import {ImageNode} from "./image";
|
||||||
import {DetailsNode, SummaryNode} from "./details";
|
import {DetailsNode, SummaryNode} from "./details";
|
||||||
|
import {ListItemNode, ListNode} from "@lexical/list";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the nodes for lexical.
|
* Load the nodes for lexical.
|
||||||
@ -14,6 +15,8 @@ export function getNodesForPageEditor(): (KlassConstructor<typeof LexicalNode> |
|
|||||||
CalloutNode, // Todo - Create custom
|
CalloutNode, // Todo - Create custom
|
||||||
HeadingNode, // Todo - Create custom
|
HeadingNode, // Todo - Create custom
|
||||||
QuoteNode, // Todo - Create custom
|
QuoteNode, // Todo - Create custom
|
||||||
|
ListNode, // Todo - Create custom
|
||||||
|
ListItemNode,
|
||||||
ImageNode,
|
ImageNode,
|
||||||
DetailsNode, SummaryNode,
|
DetailsNode, SummaryNode,
|
||||||
CustomParagraphNode,
|
CustomParagraphNode,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import {EditorBasicButtonDefinition, EditorButtonDefinition} from "../framework/buttons";
|
import {EditorBasicButtonDefinition, EditorButtonDefinition} from "../framework/buttons";
|
||||||
import {
|
import {
|
||||||
$createNodeSelection,
|
$createNodeSelection,
|
||||||
$createParagraphNode, $getRoot, $getSelection, $insertNodes,
|
$createParagraphNode, $getRoot, $getSelection,
|
||||||
$isParagraphNode, $isTextNode, $setSelection,
|
$isParagraphNode, $isTextNode, $setSelection,
|
||||||
BaseSelection, ElementNode, FORMAT_TEXT_COMMAND,
|
BaseSelection, ElementNode, FORMAT_TEXT_COMMAND,
|
||||||
LexicalNode,
|
LexicalNode,
|
||||||
REDO_COMMAND, TextFormatType, TextNode,
|
REDO_COMMAND, TextFormatType,
|
||||||
UNDO_COMMAND
|
UNDO_COMMAND
|
||||||
} from "lexical";
|
} from "lexical";
|
||||||
import {
|
import {
|
||||||
@ -23,12 +23,12 @@ import {
|
|||||||
HeadingNode,
|
HeadingNode,
|
||||||
HeadingTagType
|
HeadingTagType
|
||||||
} from "@lexical/rich-text";
|
} from "@lexical/rich-text";
|
||||||
import {$isLinkNode, $toggleLink, LinkNode} from "@lexical/link";
|
import {$isLinkNode, LinkNode} from "@lexical/link";
|
||||||
import {EditorUiContext} from "../framework/core";
|
import {EditorUiContext} from "../framework/core";
|
||||||
import {$isImageNode, ImageNode} from "../../nodes/image";
|
import {$isImageNode, ImageNode} from "../../nodes/image";
|
||||||
import {$createDetailsNode, $isDetailsNode} from "../../nodes/details";
|
import {$createDetailsNode, $isDetailsNode} from "../../nodes/details";
|
||||||
import {$insertNodeToNearestRoot} from "@lexical/utils";
|
|
||||||
import {getEditorContentAsHtml} from "../../actions";
|
import {getEditorContentAsHtml} from "../../actions";
|
||||||
|
import {$isListNode, insertList, ListNode, ListType, removeList} from "@lexical/list";
|
||||||
|
|
||||||
export const undo: EditorButtonDefinition = {
|
export const undo: EditorButtonDefinition = {
|
||||||
label: 'Undo',
|
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 = {
|
export const link: EditorButtonDefinition = {
|
||||||
label: 'Insert/edit link',
|
label: 'Insert/edit link',
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import {EditorButton} from "./framework/buttons";
|
import {EditorButton} from "./framework/buttons";
|
||||||
import {
|
import {
|
||||||
blockquote, bold, clearFormating, code,
|
blockquote, bold, bulletList, clearFormating, code,
|
||||||
dangerCallout, details,
|
dangerCallout, details,
|
||||||
h2, h3, h4, h5, highlightColor, image,
|
h2, h3, h4, h5, highlightColor, image,
|
||||||
infoCallout, italic, link, paragraph,
|
infoCallout, italic, link, numberList, paragraph,
|
||||||
redo, source, strikethrough, subscript,
|
redo, source, strikethrough, subscript,
|
||||||
successCallout, superscript, textColor, underline,
|
successCallout, superscript, taskList, textColor, underline,
|
||||||
undo,
|
undo,
|
||||||
warningCallout
|
warningCallout
|
||||||
} from "./defaults/button-definitions";
|
} from "./defaults/button-definitions";
|
||||||
@ -53,6 +53,11 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
|
|||||||
new EditorButton(code),
|
new EditorButton(code),
|
||||||
new EditorButton(clearFormating),
|
new EditorButton(clearFormating),
|
||||||
|
|
||||||
|
// Lists
|
||||||
|
new EditorButton(bulletList),
|
||||||
|
new EditorButton(numberList),
|
||||||
|
new EditorButton(taskList),
|
||||||
|
|
||||||
// Insert types
|
// Insert types
|
||||||
new EditorButton(link),
|
new EditorButton(link),
|
||||||
new EditorButton(image),
|
new EditorButton(image),
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
// Main UI elements
|
// Main UI elements
|
||||||
.editor-toolbar-main {
|
.editor-toolbar-main {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
|
Loading…
x
Reference in New Issue
Block a user