mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fix: make getBoundTextElement and related helpers pure (#7601)
* fix: make getBoundTextElement pure * updating args * fix * pass boundTextElement to getBoundTextMaxWidth * fix labelled arrows * lint * pass elementsMap to removeElementsFromFrame * pass elementsMap to getMaximumGroups, alignElements and distributeElements * lint * pass allElementsMap to renderElement * lint * feat: make more typesafe * fix: remove unnecessary assertion * fix: remove unused params --------- Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
parent
2789d08154
commit
10bd08ef19
34 changed files with 385 additions and 143 deletions
|
@ -40,8 +40,13 @@ const alignSelectedElements = (
|
|||
alignment: Alignment,
|
||||
) => {
|
||||
const selectedElements = app.scene.getSelectedElements(appState);
|
||||
const elementsMap = arrayToMap(elements);
|
||||
|
||||
const updatedElements = alignElements(selectedElements, alignment);
|
||||
const updatedElements = alignElements(
|
||||
selectedElements,
|
||||
elementsMap,
|
||||
alignment,
|
||||
);
|
||||
|
||||
const updatedElementsMap = arrayToMap(updatedElements);
|
||||
|
||||
|
|
|
@ -45,8 +45,9 @@ export const actionUnbindText = register({
|
|||
},
|
||||
perform: (elements, appState, _, app) => {
|
||||
const selectedElements = app.scene.getSelectedElements(appState);
|
||||
const elementsMap = app.scene.getNonDeletedElementsMap();
|
||||
selectedElements.forEach((element) => {
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
const boundTextElement = getBoundTextElement(element, elementsMap);
|
||||
if (boundTextElement) {
|
||||
const { width, height, baseline } = measureText(
|
||||
boundTextElement.originalText,
|
||||
|
@ -106,7 +107,10 @@ export const actionBindText = register({
|
|||
if (
|
||||
textElement &&
|
||||
bindingContainer &&
|
||||
getBoundTextElement(bindingContainer) === null
|
||||
getBoundTextElement(
|
||||
bindingContainer,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
) === null
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,11 @@ const distributeSelectedElements = (
|
|||
) => {
|
||||
const selectedElements = app.scene.getSelectedElements(appState);
|
||||
|
||||
const updatedElements = distributeElements(selectedElements, distribution);
|
||||
const updatedElements = distributeElements(
|
||||
selectedElements,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
distribution,
|
||||
);
|
||||
|
||||
const updatedElementsMap = arrayToMap(updatedElements);
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ const duplicateElements = (
|
|||
continue;
|
||||
}
|
||||
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
const boundTextElement = getBoundTextElement(element, arrayToMap(elements));
|
||||
const isElementAFrameLike = isFrameLikeElement(element);
|
||||
|
||||
if (idsOfElementsToDuplicate.get(element.id)) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
ExcalidrawElement,
|
||||
NonDeleted,
|
||||
NonDeletedElementsMap,
|
||||
NonDeletedSceneElementsMap,
|
||||
} from "../element/types";
|
||||
import { resizeMultipleElements } from "../element/resizeElements";
|
||||
import { AppState } from "../types";
|
||||
|
@ -67,7 +68,7 @@ export const actionFlipVertical = register({
|
|||
|
||||
const flipSelectedElements = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
elementsMap: NonDeletedElementsMap,
|
||||
elementsMap: NonDeletedElementsMap | NonDeletedSceneElementsMap,
|
||||
appState: Readonly<AppState>,
|
||||
flipDirection: "horizontal" | "vertical",
|
||||
) => {
|
||||
|
@ -96,7 +97,7 @@ const flipSelectedElements = (
|
|||
|
||||
const flipElements = (
|
||||
selectedElements: NonDeleted<ExcalidrawElement>[],
|
||||
elementsMap: NonDeletedElementsMap,
|
||||
elementsMap: NonDeletedElementsMap | NonDeletedSceneElementsMap,
|
||||
appState: AppState,
|
||||
flipDirection: "horizontal" | "vertical",
|
||||
): ExcalidrawElement[] => {
|
||||
|
|
|
@ -105,7 +105,10 @@ export const actionGroup = register({
|
|||
const frameElementsMap = groupByFrameLikes(selectedElements);
|
||||
|
||||
frameElementsMap.forEach((elementsInFrame, frameId) => {
|
||||
removeElementsFromFrame(elementsInFrame);
|
||||
removeElementsFromFrame(
|
||||
elementsInFrame,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -225,6 +228,7 @@ export const actionUngroup = register({
|
|||
nextElements,
|
||||
getElementsInResizingFrame(nextElements, frame, appState),
|
||||
frame,
|
||||
app,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -606,7 +606,7 @@ export const actionChangeFontSize = register({
|
|||
perform: (elements, appState, value, app) => {
|
||||
return changeFontSize(elements, appState, app, () => value, value);
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
PanelComponent: ({ elements, appState, updateData, app }) => (
|
||||
<fieldset>
|
||||
<legend>{t("labels.fontSize")}</legend>
|
||||
<ButtonIconSelect
|
||||
|
@ -644,14 +644,21 @@ export const actionChangeFontSize = register({
|
|||
if (isTextElement(element)) {
|
||||
return element.fontSize;
|
||||
}
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
const boundTextElement = getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
);
|
||||
if (boundTextElement) {
|
||||
return boundTextElement.fontSize;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
(element) =>
|
||||
isTextElement(element) || getBoundTextElement(element) !== null,
|
||||
isTextElement(element) ||
|
||||
getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
) !== null,
|
||||
(hasSelection) =>
|
||||
hasSelection
|
||||
? null
|
||||
|
@ -738,7 +745,7 @@ export const actionChangeFontFamily = register({
|
|||
commitToHistory: true,
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData }) => {
|
||||
PanelComponent: ({ elements, appState, updateData, app }) => {
|
||||
const options: {
|
||||
value: FontFamilyValues;
|
||||
text: string;
|
||||
|
@ -778,14 +785,21 @@ export const actionChangeFontFamily = register({
|
|||
if (isTextElement(element)) {
|
||||
return element.fontFamily;
|
||||
}
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
const boundTextElement = getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
);
|
||||
if (boundTextElement) {
|
||||
return boundTextElement.fontFamily;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
(element) =>
|
||||
isTextElement(element) || getBoundTextElement(element) !== null,
|
||||
isTextElement(element) ||
|
||||
getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
) !== null,
|
||||
(hasSelection) =>
|
||||
hasSelection
|
||||
? null
|
||||
|
@ -830,7 +844,8 @@ export const actionChangeTextAlign = register({
|
|||
commitToHistory: true,
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData }) => {
|
||||
PanelComponent: ({ elements, appState, updateData, app }) => {
|
||||
const elementsMap = app.scene.getNonDeletedElementsMap();
|
||||
return (
|
||||
<fieldset>
|
||||
<legend>{t("labels.textAlign")}</legend>
|
||||
|
@ -863,14 +878,18 @@ export const actionChangeTextAlign = register({
|
|||
if (isTextElement(element)) {
|
||||
return element.textAlign;
|
||||
}
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
const boundTextElement = getBoundTextElement(
|
||||
element,
|
||||
elementsMap,
|
||||
);
|
||||
if (boundTextElement) {
|
||||
return boundTextElement.textAlign;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
(element) =>
|
||||
isTextElement(element) || getBoundTextElement(element) !== null,
|
||||
isTextElement(element) ||
|
||||
getBoundTextElement(element, elementsMap) !== null,
|
||||
(hasSelection) =>
|
||||
hasSelection ? null : appState.currentItemTextAlign,
|
||||
)}
|
||||
|
@ -913,7 +932,7 @@ export const actionChangeVerticalAlign = register({
|
|||
commitToHistory: true,
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData }) => {
|
||||
PanelComponent: ({ elements, appState, updateData, app }) => {
|
||||
return (
|
||||
<fieldset>
|
||||
<ButtonIconSelect<VerticalAlign | false>
|
||||
|
@ -945,14 +964,21 @@ export const actionChangeVerticalAlign = register({
|
|||
if (isTextElement(element) && element.containerId) {
|
||||
return element.verticalAlign;
|
||||
}
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
const boundTextElement = getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
);
|
||||
if (boundTextElement) {
|
||||
return boundTextElement.verticalAlign;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
(element) =>
|
||||
isTextElement(element) || getBoundTextElement(element) !== null,
|
||||
isTextElement(element) ||
|
||||
getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
) !== null,
|
||||
(hasSelection) => (hasSelection ? null : VERTICAL_ALIGN.MIDDLE),
|
||||
)}
|
||||
onChange={(value) => updateData(value)}
|
||||
|
|
|
@ -32,12 +32,15 @@ export let copiedStyles: string = "{}";
|
|||
export const actionCopyStyles = register({
|
||||
name: "copyStyles",
|
||||
trackEvent: { category: "element" },
|
||||
perform: (elements, appState) => {
|
||||
perform: (elements, appState, formData, app) => {
|
||||
const elementsCopied = [];
|
||||
const element = elements.find((el) => appState.selectedElementIds[el.id]);
|
||||
elementsCopied.push(element);
|
||||
if (element && hasBoundTextElement(element)) {
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
const boundTextElement = getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
);
|
||||
elementsCopied.push(boundTextElement);
|
||||
}
|
||||
if (element) {
|
||||
|
@ -59,7 +62,7 @@ export const actionCopyStyles = register({
|
|||
export const actionPasteStyles = register({
|
||||
name: "pasteStyles",
|
||||
trackEvent: { category: "element" },
|
||||
perform: (elements, appState) => {
|
||||
perform: (elements, appState, formData, app) => {
|
||||
const elementsCopied = JSON.parse(copiedStyles);
|
||||
const pastedElement = elementsCopied[0];
|
||||
const boundTextElement = elementsCopied[1];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue