]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/defaults/buttons/alignments.ts
Lexical: Revamped image node resize method
[bookstack] / resources / js / wysiwyg / ui / defaults / buttons / alignments.ts
1 import {$isElementNode, BaseSelection, LexicalEditor} from "lexical";
2 import {EditorButtonDefinition} from "../../framework/buttons";
3 import alignLeftIcon from "@icons/editor/align-left.svg";
4 import {EditorUiContext} from "../../framework/core";
5 import alignCenterIcon from "@icons/editor/align-center.svg";
6 import alignRightIcon from "@icons/editor/align-right.svg";
7 import alignJustifyIcon from "@icons/editor/align-justify.svg";
8 import {
9     $getBlockElementNodesInSelection,
10     $selectionContainsAlignment, $selectSingleNode, $toggleSelection, getLastSelection
11 } from "../../../utils/selection";
12 import {CommonBlockAlignment} from "../../../nodes/_common";
13 import {nodeHasAlignment} from "../../../utils/nodes";
14
15
16 function setAlignmentForSection(editor: LexicalEditor, alignment: CommonBlockAlignment): void {
17     const selection = getLastSelection(editor);
18     const selectionNodes = selection?.getNodes() || [];
19
20     // Handle inline node selection alignment
21     if (selectionNodes.length === 1 && $isElementNode(selectionNodes[0]) && selectionNodes[0].isInline() && nodeHasAlignment(selectionNodes[0])) {
22         selectionNodes[0].setAlignment(alignment);
23         $selectSingleNode(selectionNodes[0]);
24         $toggleSelection(editor);
25         return;
26     }
27
28     // Handle normal block/range alignment
29     const elements = $getBlockElementNodesInSelection(selection);
30     for (const node of elements) {
31         if (nodeHasAlignment(node)) {
32             node.setAlignment(alignment)
33         }
34     }
35     $toggleSelection(editor);
36 }
37
38 export const alignLeft: EditorButtonDefinition = {
39     label: 'Align left',
40     icon: alignLeftIcon,
41     action(context: EditorUiContext) {
42         context.editor.update(() => setAlignmentForSection(context.editor, 'left'));
43     },
44     isActive(selection: BaseSelection|null) {
45         return $selectionContainsAlignment(selection, 'left');
46     }
47 };
48
49 export const alignCenter: EditorButtonDefinition = {
50     label: 'Align center',
51     icon: alignCenterIcon,
52     action(context: EditorUiContext) {
53         context.editor.update(() => setAlignmentForSection(context.editor, 'center'));
54     },
55     isActive(selection: BaseSelection|null) {
56         return $selectionContainsAlignment(selection, 'center');
57     }
58 };
59
60 export const alignRight: EditorButtonDefinition = {
61     label: 'Align right',
62     icon: alignRightIcon,
63     action(context: EditorUiContext) {
64         context.editor.update(() => setAlignmentForSection(context.editor, 'right'));
65     },
66     isActive(selection: BaseSelection|null) {
67         return $selectionContainsAlignment(selection, 'right');
68     }
69 };
70
71 export const alignJustify: EditorButtonDefinition = {
72     label: 'Align justify',
73     icon: alignJustifyIcon,
74     action(context: EditorUiContext) {
75         context.editor.update(() => setAlignmentForSection(context.editor, 'justify'));
76     },
77     isActive(selection: BaseSelection|null) {
78         return $selectionContainsAlignment(selection, 'justify');
79     }
80 };