fix: bound text not atomic with container when changing z-index (#4414)

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Aakansha Doshi 2021-12-17 18:40:37 +05:30 committed by GitHub
parent c2a8712593
commit 8b2b03347c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 151 additions and 6 deletions

View file

@ -94,6 +94,10 @@ export class API {
verticalAlign?: T extends "text"
? ExcalidrawTextElement["verticalAlign"]
: never;
boundElements?: ExcalidrawGenericElement["boundElements"];
containerId?: T extends "text"
? ExcalidrawTextElement["containerId"]
: never;
}): T extends "arrow" | "line"
? ExcalidrawLinearElement
: T extends "freedraw"
@ -118,6 +122,7 @@ export class API {
rest.strokeSharpness ?? appState.currentItemStrokeSharpness,
roughness: rest.roughness ?? appState.currentItemRoughness,
opacity: rest.opacity ?? appState.currentItemOpacity,
boundElements: rest.boundElements ?? null,
};
switch (type) {
case "rectangle":
@ -138,6 +143,7 @@ export class API {
fontFamily: rest.fontFamily ?? appState.currentItemFontFamily,
textAlign: rest.textAlign ?? appState.currentItemTextAlign,
verticalAlign: rest.verticalAlign ?? DEFAULT_VERTICAL_ALIGN,
containerId: rest.containerId ?? undefined,
});
element.width = width;
element.height = height;

View file

@ -32,11 +32,12 @@ const populateElements = (
x?: number;
width?: number;
height?: number;
containerId?: string;
}[],
) => {
const selectedElementIds: any = {};
h.elements = elements.map(
const newElements = elements.map(
({
id,
isDeleted = false,
@ -46,9 +47,10 @@ const populateElements = (
x = 100,
width = 100,
height = 100,
containerId = null,
}) => {
const element = API.createElement({
type: "rectangle",
type: containerId ? "text" : "rectangle",
id,
isDeleted,
x,
@ -56,6 +58,7 @@ const populateElements = (
width,
height,
groupIds,
containerId,
});
if (isSelected) {
selectedElementIds[element.id] = true;
@ -64,6 +67,22 @@ const populateElements = (
},
);
// initialize `boundElements` on containers, if applicable
h.elements = newElements.map((element, index, elements) => {
const nextElement = elements[index + 1];
if (
nextElement &&
"containerId" in nextElement &&
element.id === nextElement.containerId
) {
return {
...element,
boundElements: [{ type: "text", id: nextElement.id }],
};
}
return element;
});
h.setState({
selectedElementIds,
});
@ -87,6 +106,7 @@ const assertZindex = ({
isDeleted?: true;
isSelected?: true;
groupIds?: string[];
containerId?: string;
}[];
appState?: Partial<AppState>;
operations: [Actions, string[]][];
@ -1051,4 +1071,73 @@ describe("z-index manipulation", () => {
"C_copy",
]);
});
it("text-container binding should be atomic", () => {
assertZindex({
elements: [
{ id: "A", isSelected: true },
{ id: "B" },
{ id: "C", containerId: "B" },
],
operations: [
[actionBringForward, ["B", "C", "A"]],
[actionSendBackward, ["A", "B", "C"]],
],
});
assertZindex({
elements: [
{ id: "A" },
{ id: "B", isSelected: true },
{ id: "C", containerId: "B" },
],
operations: [
[actionSendBackward, ["B", "C", "A"]],
[actionBringForward, ["A", "B", "C"]],
],
});
assertZindex({
elements: [
{ id: "A", isSelected: true, groupIds: ["g1"] },
{ id: "B", groupIds: ["g1"] },
{ id: "C", containerId: "B", groupIds: ["g1"] },
],
appState: {
editingGroupId: "g1",
},
operations: [
[actionBringForward, ["B", "C", "A"]],
[actionSendBackward, ["A", "B", "C"]],
],
});
assertZindex({
elements: [
{ id: "A", groupIds: ["g1"] },
{ id: "B", groupIds: ["g1"], isSelected: true },
{ id: "C", containerId: "B", groupIds: ["g1"] },
],
appState: {
editingGroupId: "g1",
},
operations: [
[actionSendBackward, ["B", "C", "A"]],
[actionBringForward, ["A", "B", "C"]],
],
});
assertZindex({
elements: [
{ id: "A", groupIds: ["g1"] },
{ id: "B", isSelected: true, groupIds: ["g1"] },
{ id: "C" },
{ id: "D", containerId: "C" },
],
appState: {
editingGroupId: "g1",
},
operations: [[actionBringForward, ["A", "B", "C", "D"]]],
});
});
});