]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/index.ts
Lexical: Started UI fundementals with basic button
[bookstack] / resources / js / wysiwyg / ui / index.ts
1 import {
2     $getSelection,
3     BaseSelection,
4     COMMAND_PRIORITY_LOW,
5     LexicalEditor,
6     SELECTION_CHANGE_COMMAND
7 } from "lexical";
8 import {$createCalloutNode, $isCalloutNodeOfCategory} from "../nodes/callout";
9 import {selectionContainsNodeType, toggleSelectionBlockNodeType} from "../helpers";
10 import {EditorButton, EditorButtonDefinition} from "./editor-button";
11
12 const calloutButton: EditorButtonDefinition = {
13     label: 'Info Callout',
14     action(editor: LexicalEditor) {
15         toggleSelectionBlockNodeType(
16             editor,
17             (node) => $isCalloutNodeOfCategory(node, 'info'),
18             () => $createCalloutNode('info'),
19         )
20     },
21     isActive(selection: BaseSelection|null): boolean {
22         return selectionContainsNodeType(selection, (node) => $isCalloutNodeOfCategory(node, 'info'));
23     }
24 }
25
26 const toolbarButtonDefinitions: EditorButtonDefinition[] = [
27     calloutButton,
28 ];
29
30 export function buildEditorUI(element: HTMLElement, editor: LexicalEditor) {
31     const toolbarContainer = document.createElement('div');
32     toolbarContainer.classList.add('editor-toolbar-container');
33
34     const buttons = toolbarButtonDefinitions.map(definition => {
35         return new EditorButton(definition, editor);
36     });
37
38     const buttonElements = buttons.map(button => button.getDOMElement());
39
40     toolbarContainer.append(...buttonElements);
41     element.before(toolbarContainer);
42
43     // Update button states on editor selection change
44     editor.registerCommand(SELECTION_CHANGE_COMMAND, () => {
45         const selection = $getSelection();
46         for (const button of buttons) {
47             button.updateActiveState(selection);
48         }
49         return false;
50     }, COMMAND_PRIORITY_LOW);
51 }