]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/defaults/buttons/alignments.ts
Lexical: Added some level of img/media alignment
[bookstack] / resources / js / wysiwyg / ui / defaults / buttons / alignments.ts
1 import {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     $getDecoratorNodesInSelection,
11     $selectionContainsAlignment, getLastSelection
12 } from "../../../utils/selection";
13 import {CommonBlockAlignment} from "../../../nodes/_common";
14 import {nodeHasAlignment} from "../../../utils/nodes";
15
16
17 function setAlignmentForSection(editor: LexicalEditor, alignment: CommonBlockAlignment): void {
18     const selection = getLastSelection(editor);
19     const selectionNodes = selection?.getNodes() || [];
20     const decorators = $getDecoratorNodesInSelection(selection);
21
22     // Handle decorator node selection alignment
23     if (selectionNodes.length === 1 && decorators.length === 1 && nodeHasAlignment(decorators[0])) {
24         decorators[0].setAlignment(alignment);
25         console.log('setting for decorator!');
26         return;
27     }
28
29     // Handle normal block/range alignment
30     const elements = $getBlockElementNodesInSelection(selection);
31     for (const node of elements) {
32         if (nodeHasAlignment(node)) {
33             node.setAlignment(alignment)
34         }
35     }
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 };