fix: copy bound text style when copying element having bound text (#5305)
* fix: copy bound text style when copying element having bound text * fix * fix tests
This commit is contained in:
parent
6196fba286
commit
84b47a2ed5
@ -48,7 +48,7 @@ describe("actionStyles", () => {
|
||||
Keyboard.withModifierKeys({ ctrl: true, alt: true }, () => {
|
||||
Keyboard.codeDown(CODES.C);
|
||||
});
|
||||
const secondRect = JSON.parse(copiedStyles);
|
||||
const secondRect = JSON.parse(copiedStyles)[0];
|
||||
expect(secondRect.id).toBe(h.elements[1].id);
|
||||
|
||||
mouse.reset();
|
||||
|
@ -12,7 +12,9 @@ import {
|
||||
DEFAULT_FONT_FAMILY,
|
||||
DEFAULT_TEXT_ALIGN,
|
||||
} from "../constants";
|
||||
import { getContainerElement } from "../element/textElement";
|
||||
import { getBoundTextElement } from "../element/textElement";
|
||||
import { hasBoundTextElement } from "../element/typeChecks";
|
||||
import { getSelectedElements } from "../scene";
|
||||
|
||||
// `copiedStyles` is exported only for tests.
|
||||
export let copiedStyles: string = "{}";
|
||||
@ -21,9 +23,15 @@ export const actionCopyStyles = register({
|
||||
name: "copyStyles",
|
||||
trackEvent: { category: "element" },
|
||||
perform: (elements, appState) => {
|
||||
const elementsCopied = [];
|
||||
const element = elements.find((el) => appState.selectedElementIds[el.id]);
|
||||
elementsCopied.push(element);
|
||||
if (element && hasBoundTextElement(element)) {
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
elementsCopied.push(boundTextElement);
|
||||
}
|
||||
if (element) {
|
||||
copiedStyles = JSON.stringify(element);
|
||||
copiedStyles = JSON.stringify(elementsCopied);
|
||||
}
|
||||
return {
|
||||
appState: {
|
||||
@ -42,37 +50,59 @@ export const actionPasteStyles = register({
|
||||
name: "pasteStyles",
|
||||
trackEvent: { category: "element" },
|
||||
perform: (elements, appState) => {
|
||||
const pastedElement = JSON.parse(copiedStyles);
|
||||
const elementsCopied = JSON.parse(copiedStyles);
|
||||
const pastedElement = elementsCopied[0];
|
||||
const boundTextElement = elementsCopied[1];
|
||||
if (!isExcalidrawElement(pastedElement)) {
|
||||
return { elements, commitToHistory: false };
|
||||
}
|
||||
|
||||
const selectedElements = getSelectedElements(elements, appState, true);
|
||||
const selectedElementIds = selectedElements.map((element) => element.id);
|
||||
return {
|
||||
elements: elements.map((element) => {
|
||||
if (appState.selectedElementIds[element.id]) {
|
||||
if (selectedElementIds.includes(element.id)) {
|
||||
let elementStylesToCopyFrom = pastedElement;
|
||||
if (isTextElement(element) && element.containerId) {
|
||||
elementStylesToCopyFrom = boundTextElement;
|
||||
}
|
||||
if (!elementStylesToCopyFrom) {
|
||||
return element;
|
||||
}
|
||||
let newElement = newElementWith(element, {
|
||||
backgroundColor: pastedElement?.backgroundColor,
|
||||
strokeWidth: pastedElement?.strokeWidth,
|
||||
strokeColor: pastedElement?.strokeColor,
|
||||
strokeStyle: pastedElement?.strokeStyle,
|
||||
fillStyle: pastedElement?.fillStyle,
|
||||
opacity: pastedElement?.opacity,
|
||||
roughness: pastedElement?.roughness,
|
||||
backgroundColor: elementStylesToCopyFrom?.backgroundColor,
|
||||
strokeWidth: elementStylesToCopyFrom?.strokeWidth,
|
||||
strokeColor: elementStylesToCopyFrom?.strokeColor,
|
||||
strokeStyle: elementStylesToCopyFrom?.strokeStyle,
|
||||
fillStyle: elementStylesToCopyFrom?.fillStyle,
|
||||
opacity: elementStylesToCopyFrom?.opacity,
|
||||
roughness: elementStylesToCopyFrom?.roughness,
|
||||
});
|
||||
|
||||
if (isTextElement(newElement)) {
|
||||
newElement = newElementWith(newElement, {
|
||||
fontSize: pastedElement?.fontSize || DEFAULT_FONT_SIZE,
|
||||
fontFamily: pastedElement?.fontFamily || DEFAULT_FONT_FAMILY,
|
||||
textAlign: pastedElement?.textAlign || DEFAULT_TEXT_ALIGN,
|
||||
fontSize: elementStylesToCopyFrom?.fontSize || DEFAULT_FONT_SIZE,
|
||||
fontFamily:
|
||||
elementStylesToCopyFrom?.fontFamily || DEFAULT_FONT_FAMILY,
|
||||
textAlign:
|
||||
elementStylesToCopyFrom?.textAlign || DEFAULT_TEXT_ALIGN,
|
||||
});
|
||||
|
||||
redrawTextBoundingBox(newElement, getContainerElement(newElement));
|
||||
let container = null;
|
||||
if (newElement.containerId) {
|
||||
container =
|
||||
selectedElements.find(
|
||||
(element) =>
|
||||
isTextElement(newElement) &&
|
||||
element.id === newElement.containerId,
|
||||
) || null;
|
||||
}
|
||||
redrawTextBoundingBox(newElement, container);
|
||||
}
|
||||
|
||||
if (newElement.type === "arrow") {
|
||||
newElement = newElementWith(newElement, {
|
||||
startArrowhead: pastedElement.startArrowhead,
|
||||
endArrowhead: pastedElement.endArrowhead,
|
||||
startArrowhead: elementStylesToCopyFrom.startArrowhead,
|
||||
endArrowhead: elementStylesToCopyFrom.endArrowhead,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ describe("contextMenu element", () => {
|
||||
expect(copiedStyles).toBe("{}");
|
||||
fireEvent.click(queryByText(contextMenu as HTMLElement, "Copy styles")!);
|
||||
expect(copiedStyles).not.toBe("{}");
|
||||
const element = JSON.parse(copiedStyles);
|
||||
const element = JSON.parse(copiedStyles)[0];
|
||||
expect(element).toEqual(API.getSelectedElement());
|
||||
});
|
||||
|
||||
@ -329,7 +329,7 @@ describe("contextMenu element", () => {
|
||||
});
|
||||
let contextMenu = UI.queryContextMenu();
|
||||
fireEvent.click(queryByText(contextMenu as HTMLElement, "Copy styles")!);
|
||||
const secondRect = JSON.parse(copiedStyles);
|
||||
const secondRect = JSON.parse(copiedStyles)[0];
|
||||
expect(secondRect.id).toBe(h.elements[1].id);
|
||||
|
||||
mouse.reset();
|
||||
|
Loading…
x
Reference in New Issue
Block a user