diff --git a/resources/icons/editor/direction-ltr.svg b/resources/icons/editor/direction-ltr.svg new file mode 100644 index 000000000..16befc75c --- /dev/null +++ b/resources/icons/editor/direction-ltr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/icons/editor/direction-rtl.svg b/resources/icons/editor/direction-rtl.svg new file mode 100644 index 000000000..5125472a0 --- /dev/null +++ b/resources/icons/editor/direction-rtl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts b/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts index 329b11956..130fd6b72 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts @@ -5,15 +5,17 @@ import {EditorUiContext} from "../../framework/core"; import alignCenterIcon from "@icons/editor/align-center.svg"; import alignRightIcon from "@icons/editor/align-right.svg"; import alignJustifyIcon from "@icons/editor/align-justify.svg"; +import ltrIcon from "@icons/editor/direction-ltr.svg"; +import rtlIcon from "@icons/editor/direction-rtl.svg"; import { $getBlockElementNodesInSelection, - $selectionContainsAlignment, $selectSingleNode, $toggleSelection, getLastSelection + $selectionContainsAlignment, $selectionContainsDirection, $selectSingleNode, $toggleSelection, getLastSelection } from "../../../utils/selection"; import {CommonBlockAlignment} from "../../../nodes/_common"; import {nodeHasAlignment} from "../../../utils/nodes"; -function setAlignmentForSection(editor: LexicalEditor, alignment: CommonBlockAlignment): void { +function setAlignmentForSelection(editor: LexicalEditor, alignment: CommonBlockAlignment): void { const selection = getLastSelection(editor); const selectionNodes = selection?.getNodes() || []; @@ -35,11 +37,21 @@ function setAlignmentForSection(editor: LexicalEditor, alignment: CommonBlockAli $toggleSelection(editor); } +function setDirectionForSelection(editor: LexicalEditor, direction: 'ltr' | 'rtl'): void { + const selection = getLastSelection(editor); + + const elements = $getBlockElementNodesInSelection(selection); + for (const node of elements) { + console.log('setting direction', node); + node.setDirection(direction); + } +} + export const alignLeft: EditorButtonDefinition = { label: 'Align left', icon: alignLeftIcon, action(context: EditorUiContext) { - context.editor.update(() => setAlignmentForSection(context.editor, 'left')); + context.editor.update(() => setAlignmentForSelection(context.editor, 'left')); }, isActive(selection: BaseSelection|null) { return $selectionContainsAlignment(selection, 'left'); @@ -50,7 +62,7 @@ export const alignCenter: EditorButtonDefinition = { label: 'Align center', icon: alignCenterIcon, action(context: EditorUiContext) { - context.editor.update(() => setAlignmentForSection(context.editor, 'center')); + context.editor.update(() => setAlignmentForSelection(context.editor, 'center')); }, isActive(selection: BaseSelection|null) { return $selectionContainsAlignment(selection, 'center'); @@ -61,7 +73,7 @@ export const alignRight: EditorButtonDefinition = { label: 'Align right', icon: alignRightIcon, action(context: EditorUiContext) { - context.editor.update(() => setAlignmentForSection(context.editor, 'right')); + context.editor.update(() => setAlignmentForSelection(context.editor, 'right')); }, isActive(selection: BaseSelection|null) { return $selectionContainsAlignment(selection, 'right'); @@ -72,9 +84,31 @@ export const alignJustify: EditorButtonDefinition = { label: 'Align justify', icon: alignJustifyIcon, action(context: EditorUiContext) { - context.editor.update(() => setAlignmentForSection(context.editor, 'justify')); + context.editor.update(() => setAlignmentForSelection(context.editor, 'justify')); }, isActive(selection: BaseSelection|null) { return $selectionContainsAlignment(selection, 'justify'); } }; + +export const directionLTR: EditorButtonDefinition = { + label: 'Left to right', + icon: ltrIcon, + action(context: EditorUiContext) { + context.editor.update(() => setDirectionForSelection(context.editor, 'ltr')); + }, + isActive(selection: BaseSelection|null) { + return $selectionContainsDirection(selection, 'ltr'); + } +}; + +export const directionRTL: EditorButtonDefinition = { + label: 'Right to left', + icon: rtlIcon, + action(context: EditorUiContext) { + context.editor.update(() => setDirectionForSelection(context.editor, 'rtl')); + }, + isActive(selection: BaseSelection|null) { + return $selectionContainsDirection(selection, 'rtl'); + } +}; \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/toolbars.ts b/resources/js/wysiwyg/ui/toolbars.ts index 0ad638410..b064a2a9f 100644 --- a/resources/js/wysiwyg/ui/toolbars.ts +++ b/resources/js/wysiwyg/ui/toolbars.ts @@ -51,7 +51,14 @@ import { textColor, underline } from "./defaults/buttons/inline-formats"; -import {alignCenter, alignJustify, alignLeft, alignRight} from "./defaults/buttons/alignments"; +import { + alignCenter, + alignJustify, + alignLeft, + alignRight, + directionLTR, + directionRTL +} from "./defaults/buttons/alignments"; import { bulletList, indentDecrease, @@ -117,11 +124,13 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement { ]), // Alignment - new EditorOverflowContainer(4, [ + new EditorOverflowContainer(6, [ // TODO - Dynamic new EditorButton(alignLeft), new EditorButton(alignCenter), new EditorButton(alignRight), new EditorButton(alignJustify), + new EditorButton(directionLTR), // TODO - Dynamic + new EditorButton(directionRTL), // TODO - Dynamic ]), // Lists diff --git a/resources/js/wysiwyg/utils/selection.ts b/resources/js/wysiwyg/utils/selection.ts index 2110ea4be..f1055d98a 100644 --- a/resources/js/wysiwyg/utils/selection.ts +++ b/resources/js/wysiwyg/utils/selection.ts @@ -2,7 +2,7 @@ import { $createNodeSelection, $createParagraphNode, $createRangeSelection, $getRoot, - $getSelection, $isDecoratorNode, + $getSelection, $isBlockElementNode, $isDecoratorNode, $isElementNode, $isTextNode, $setSelection, @@ -199,6 +199,22 @@ export function $selectionContainsAlignment(selection: BaseSelection | null, ali return false; } +export function $selectionContainsDirection(selection: BaseSelection | null, direction: 'rtl'|'ltr'): boolean { + + const nodes = [ + ...(selection?.getNodes() || []), + ...$getBlockElementNodesInSelection(selection) + ]; + + for (const node of nodes) { + if ($isBlockElementNode(node) && node.getDirection() === direction) { + return true; + } + } + + return false; +} + export function $getBlockElementNodesInSelection(selection: BaseSelection | null): ElementNode[] { if (!selection) { return [];