mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-12-15 23:53:38 +08:00
117 lines
4.2 KiB
TypeScript
117 lines
4.2 KiB
TypeScript
import {$isElementNode, BaseSelection} from "lexical";
|
|
import {EditorButtonDefinition} from "../../framework/buttons";
|
|
import alignLeftIcon from "@icons/editor/align-left.svg";
|
|
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, $selectionContainsDirection, $selectSingleNode, $toggleSelection, getLastSelection
|
|
} from "../../../utils/selection";
|
|
import {CommonBlockAlignment} from "../../../nodes/_common";
|
|
import {nodeHasAlignment} from "../../../utils/nodes";
|
|
|
|
|
|
function setAlignmentForSelection(context: EditorUiContext, alignment: CommonBlockAlignment): void {
|
|
const selection = getLastSelection(context.editor);
|
|
const selectionNodes = selection?.getNodes() || [];
|
|
|
|
// Handle inline node selection alignment
|
|
if (selectionNodes.length === 1 && $isElementNode(selectionNodes[0]) && selectionNodes[0].isInline() && nodeHasAlignment(selectionNodes[0])) {
|
|
selectionNodes[0].setAlignment(alignment);
|
|
$selectSingleNode(selectionNodes[0]);
|
|
context.manager.triggerFutureStateRefresh();
|
|
return;
|
|
}
|
|
|
|
// Handle normal block/range alignment
|
|
const elements = $getBlockElementNodesInSelection(selection);
|
|
const alignmentNodes = elements.filter(n => nodeHasAlignment(n));
|
|
const allAlreadyAligned = alignmentNodes.every(n => n.getAlignment() === alignment);
|
|
const newAlignment = allAlreadyAligned ? '' : alignment;
|
|
for (const node of alignmentNodes) {
|
|
node.setAlignment(newAlignment);
|
|
}
|
|
|
|
context.manager.triggerFutureStateRefresh();
|
|
}
|
|
|
|
function setDirectionForSelection(context: EditorUiContext, direction: 'ltr' | 'rtl'): void {
|
|
const selection = getLastSelection(context.editor);
|
|
|
|
const elements = $getBlockElementNodesInSelection(selection);
|
|
for (const node of elements) {
|
|
node.setDirection(direction);
|
|
}
|
|
|
|
context.manager.triggerFutureStateRefresh();
|
|
}
|
|
|
|
export const alignLeft: EditorButtonDefinition = {
|
|
label: 'Align left',
|
|
icon: alignLeftIcon,
|
|
action(context: EditorUiContext) {
|
|
context.editor.update(() => setAlignmentForSelection(context, 'left'));
|
|
},
|
|
isActive(selection: BaseSelection|null) {
|
|
return $selectionContainsAlignment(selection, 'left');
|
|
}
|
|
};
|
|
|
|
export const alignCenter: EditorButtonDefinition = {
|
|
label: 'Align center',
|
|
icon: alignCenterIcon,
|
|
action(context: EditorUiContext) {
|
|
context.editor.update(() => setAlignmentForSelection(context, 'center'));
|
|
},
|
|
isActive(selection: BaseSelection|null) {
|
|
return $selectionContainsAlignment(selection, 'center');
|
|
}
|
|
};
|
|
|
|
export const alignRight: EditorButtonDefinition = {
|
|
label: 'Align right',
|
|
icon: alignRightIcon,
|
|
action(context: EditorUiContext) {
|
|
context.editor.update(() => setAlignmentForSelection(context, 'right'));
|
|
},
|
|
isActive(selection: BaseSelection|null) {
|
|
return $selectionContainsAlignment(selection, 'right');
|
|
}
|
|
};
|
|
|
|
export const alignJustify: EditorButtonDefinition = {
|
|
label: 'Justify',
|
|
icon: alignJustifyIcon,
|
|
action(context: EditorUiContext) {
|
|
context.editor.update(() => setAlignmentForSelection(context, '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, '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, 'rtl'));
|
|
},
|
|
isActive(selection: BaseSelection|null) {
|
|
return $selectionContainsDirection(selection, 'rtl');
|
|
}
|
|
}; |