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";
11 $getBlockElementNodesInSelection,
12 $selectionContainsAlignment, $selectionContainsDirection, $selectSingleNode, $toggleSelection, getLastSelection
13 } from "../../../utils/selection";
14 import {CommonBlockAlignment} from "../../../nodes/_common";
15 import {nodeHasAlignment} from "../../../utils/nodes";
18 function setAlignmentForSelection(editor: LexicalEditor, alignment: CommonBlockAlignment): void {
19 const selection = getLastSelection(editor);
20 const selectionNodes = selection?.getNodes() || [];
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);
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)
37 $toggleSelection(editor);
40 function setDirectionForSelection(editor: LexicalEditor, direction: 'ltr' | 'rtl'): void {
41 const selection = getLastSelection(editor);
43 const elements = $getBlockElementNodesInSelection(selection);
44 for (const node of elements) {
45 console.log('setting direction', node);
46 node.setDirection(direction);
50 export const alignLeft: EditorButtonDefinition = {
53 action(context: EditorUiContext) {
54 context.editor.update(() => setAlignmentForSelection(context.editor, 'left'));
56 isActive(selection: BaseSelection|null) {
57 return $selectionContainsAlignment(selection, 'left');
61 export const alignCenter: EditorButtonDefinition = {
62 label: 'Align center',
63 icon: alignCenterIcon,
64 action(context: EditorUiContext) {
65 context.editor.update(() => setAlignmentForSelection(context.editor, 'center'));
67 isActive(selection: BaseSelection|null) {
68 return $selectionContainsAlignment(selection, 'center');
72 export const alignRight: EditorButtonDefinition = {
75 action(context: EditorUiContext) {
76 context.editor.update(() => setAlignmentForSelection(context.editor, 'right'));
78 isActive(selection: BaseSelection|null) {
79 return $selectionContainsAlignment(selection, 'right');
83 export const alignJustify: EditorButtonDefinition = {
84 label: 'Align justify',
85 icon: alignJustifyIcon,
86 action(context: EditorUiContext) {
87 context.editor.update(() => setAlignmentForSelection(context.editor, 'justify'));
89 isActive(selection: BaseSelection|null) {
90 return $selectionContainsAlignment(selection, 'justify');
94 export const directionLTR: EditorButtonDefinition = {
95 label: 'Left to right',
97 action(context: EditorUiContext) {
98 context.editor.update(() => setDirectionForSelection(context.editor, 'ltr'));
100 isActive(selection: BaseSelection|null) {
101 return $selectionContainsDirection(selection, 'ltr');
105 export const directionRTL: EditorButtonDefinition = {
106 label: 'Right to left',
108 action(context: EditorUiContext) {
109 context.editor.update(() => setDirectionForSelection(context.editor, 'rtl'));
111 isActive(selection: BaseSelection|null) {
112 return $selectionContainsDirection(selection, 'rtl');