fix: ensure relative z-index of elements added to frame is retained (#7134)

This commit is contained in:
David Luzar 2023-10-12 15:00:23 +02:00 committed by GitHub
parent b552166924
commit b86184a849
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 191 additions and 15 deletions

View file

@ -452,22 +452,31 @@ export const getContainingFrame = (
};
// --------------------------- Frame Operations -------------------------------
/**
* Retains (or repairs for target frame) the ordering invriant where children
* elements come right before the parent frame:
* [el, el, child, child, frame, el]
*/
export const addElementsToFrame = (
allElements: ExcalidrawElementsIncludingDeleted,
elementsToAdd: NonDeletedExcalidrawElement[],
frame: ExcalidrawFrameElement,
) => {
const currTargetFrameChildrenMap = new Map(
const { allElementsIndexMap, currTargetFrameChildrenMap } =
allElements.reduce(
(acc: [ExcalidrawElement["id"], ExcalidrawElement][], element) => {
(acc, element, index) => {
acc.allElementsIndexMap.set(element.id, index);
if (element.frameId === frame.id) {
acc.push([element.id, element]);
acc.currTargetFrameChildrenMap.set(element.id, true);
}
return acc;
},
[],
),
);
{
allElementsIndexMap: new Map<ExcalidrawElement["id"], number>(),
currTargetFrameChildrenMap: new Map<ExcalidrawElement["id"], true>(),
},
);
const suppliedElementsToAddSet = new Set(elementsToAdd.map((el) => el.id));
@ -520,12 +529,36 @@ export const addElementsToFrame = (
currFrameChildren.forEach((child) => {
processedElements.add(child.id);
});
// console.log(currFrameChildren, finalElementsToAdd, element);
nextElements.push(...currFrameChildren, ...finalElementsToAdd, element);
// if not found, add all children on top by assigning the lowest index
const targetFrameIndex = allElementsIndexMap.get(frame.id) ?? -1;
const { newChildren_left, newChildren_right } = finalElementsToAdd.reduce(
(acc, element) => {
// if index not found, add on top of current frame children
const elementIndex = allElementsIndexMap.get(element.id) ?? Infinity;
if (elementIndex < targetFrameIndex) {
acc.newChildren_left.push(element);
} else {
acc.newChildren_right.push(element);
}
return acc;
},
{
newChildren_left: [] as ExcalidrawElement[],
newChildren_right: [] as ExcalidrawElement[],
},
);
nextElements.push(
...newChildren_left,
...currFrameChildren,
...newChildren_right,
element,
);
continue;
}
// console.log("(2)", element.frameId);
nextElements.push(element);
}