]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/defaults/buttons/alignments.ts
130fd6b726c676ca5f0a1f9d157eb9288f3f147f
[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 ltrIcon from "@icons/editor/direction-ltr.svg";
9 import rtlIcon from "@icons/editor/direction-rtl.svg";
10 import {
11     $getBlockElementNodesInSelection,
12     $selectionContainsAlignment, $selectionContainsDirection, $selectSingleNode, $toggleSelection, getLastSelection
13 } from "../../../utils/selection";
14 import {CommonBlockAlignment} from "../../../nodes/_common";
15 import {nodeHasAlignment} from "../../../utils/nodes";
16
17
18 function setAlignmentForSelection(editor: LexicalEditor, alignment: CommonBlockAlignment): void {
19     const selection = getLastSelection(editor);
20     const selectionNodes = selection?.getNodes() || [];
21
22     // Handle inline node selection alignment
23     if (selectionNodes.length === 1 && $isElementNode(selectionNodes[0]) && selectionNodes[0].isInline() && nodeHasAlignment(selectionNodes[0])) {
24         selectionNodes[0].setAlignment(alignment);
25         $selectSingleNode(selectionNodes[0]);
26         $toggleSelection(editor);
27         return;
28     }
29
30     // Handle normal block/range alignment
31     const elements = $getBlockElementNodesInSelection(selection);
32     for (const node of elements) {
33         if (nodeHasAlignment(node)) {
34             node.setAlignment(alignment)
35         }
36     }
37     $toggleSelection(editor);
38 }
39
40 function setDirectionForSelection(editor: LexicalEditor, direction: 'ltr' | 'rtl'): void {
41     const selection = getLastSelection(editor);
42
43     const elements = $getBlockElementNodesInSelection(selection);
44     for (const node of elements) {
45         console.log('setting direction', node);
46         node.setDirection(direction);
47     }
48 }
49
50 export const alignLeft: EditorButtonDefinition = {
51     label: 'Align left',
52     icon: alignLeftIcon,
53     action(context: EditorUiContext) {
54         context.editor.update(() => setAlignmentForSelection(context.editor, 'left'));
55     },
56     isActive(selection: BaseSelection|null) {
57         return $selectionContainsAlignment(selection, 'left');
58     }
59 };
60
61 export const alignCenter: EditorButtonDefinition = {
62     label: 'Align center',
63     icon: alignCenterIcon,
64     action(context: EditorUiContext) {
65         context.editor.update(() => setAlignmentForSelection(context.editor, 'center'));
66     },
67     isActive(selection: BaseSelection|null) {
68         return $selectionContainsAlignment(selection, 'center');
69     }
70 };
71
72 export const alignRight: EditorButtonDefinition = {
73     label: 'Align right',
74     icon: alignRightIcon,
75     action(context: EditorUiContext) {
76         context.editor.update(() => setAlignmentForSelection(context.editor, 'right'));
77     },
78     isActive(selection: BaseSelection|null) {
79         return $selectionContainsAlignment(selection, 'right');
80     }
81 };
82
83 export const alignJustify: EditorButtonDefinition = {
84     label: 'Align justify',
85     icon: alignJustifyIcon,
86     action(context: EditorUiContext) {
87         context.editor.update(() => setAlignmentForSelection(context.editor, 'justify'));
88     },
89     isActive(selection: BaseSelection|null) {
90         return $selectionContainsAlignment(selection, 'justify');
91     }
92 };
93
94 export const directionLTR: EditorButtonDefinition = {
95     label: 'Left to right',
96     icon: ltrIcon,
97     action(context: EditorUiContext) {
98         context.editor.update(() => setDirectionForSelection(context.editor, 'ltr'));
99     },
100     isActive(selection: BaseSelection|null) {
101         return $selectionContainsDirection(selection, 'ltr');
102     }
103 };
104
105 export const directionRTL: EditorButtonDefinition = {
106     label: 'Right to left',
107     icon: rtlIcon,
108     action(context: EditorUiContext) {
109         context.editor.update(() => setDirectionForSelection(context.editor, 'rtl'));
110     },
111     isActive(selection: BaseSelection|null) {
112         return $selectionContainsDirection(selection, 'rtl');
113     }
114 };