fix: z-index inconsistencies during addition / deletion in frames (#6914)

Co-authored-by: Marcel Mraz <marcel.mraz@adacta-fintech.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Marcel Mraz 2023-09-07 00:41:44 +02:00 committed by GitHub
parent 134df7bfbb
commit a13aed92f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 424 additions and 79 deletions

View file

@ -468,14 +468,39 @@ export const addElementsToFrame = (
}
}
let nextElements = allElements.slice();
const allElementsIndex = allElements.reduce(
(acc: Record<string, number>, element, index) => {
acc[element.id] = index;
return acc;
},
{},
);
const frameIndex = allElementsIndex[frame.id];
// need to be calculated before the mutation below occurs
const leftFrameBoundaryIndex = findIndex(
allElements,
(e) => e.frameId === frame.id,
);
const existingFrameChildren = allElements.filter(
(element) => element.frameId === frame.id,
);
const addedFrameChildren_left: ExcalidrawElement[] = [];
const addedFrameChildren_right: ExcalidrawElement[] = [];
const frameBoundary = findIndex(nextElements, (e) => e.frameId === frame.id);
for (const element of omitGroupsContainingFrames(
allElements,
_elementsToAdd,
)) {
if (element.frameId !== frame.id && !isFrameElement(element)) {
if (allElementsIndex[element.id] > frameIndex) {
addedFrameChildren_right.push(element);
} else {
addedFrameChildren_left.push(element);
}
mutateElement(
element,
{
@ -483,28 +508,35 @@ export const addElementsToFrame = (
},
false,
);
const frameIndex = findIndex(nextElements, (e) => e.id === frame.id);
const elementIndex = findIndex(nextElements, (e) => e.id === element.id);
if (elementIndex < frameBoundary) {
nextElements = [
...nextElements.slice(0, elementIndex),
...nextElements.slice(elementIndex + 1, frameBoundary),
element,
...nextElements.slice(frameBoundary),
];
} else if (elementIndex > frameIndex) {
nextElements = [
...nextElements.slice(0, frameIndex),
element,
...nextElements.slice(frameIndex, elementIndex),
...nextElements.slice(elementIndex + 1),
];
}
}
}
const frameElement = allElements[frameIndex];
const nextFrameChildren = addedFrameChildren_left
.concat(existingFrameChildren)
.concat(addedFrameChildren_right);
const nextFrameChildrenMap = nextFrameChildren.reduce(
(acc: Record<string, boolean>, element) => {
acc[element.id] = true;
return acc;
},
{},
);
const nextOtherElements_left = allElements
.slice(0, leftFrameBoundaryIndex >= 0 ? leftFrameBoundaryIndex : frameIndex)
.filter((element) => !nextFrameChildrenMap[element.id]);
const nextOtherElement_right = allElements
.slice(frameIndex + 1)
.filter((element) => !nextFrameChildrenMap[element.id]);
const nextElements = nextOtherElements_left
.concat(nextFrameChildren)
.concat([frameElement])
.concat(nextOtherElement_right);
return nextElements;
};
@ -518,6 +550,7 @@ export const removeElementsFromFrame = (
for (const element of elementsToRemove) {
if (element.frameId) {
_elementsToRemove.push(element);
const boundTextElement = getBoundTextElement(element);
if (boundTextElement) {
_elementsToRemove.push(boundTextElement);
@ -566,7 +599,7 @@ export const replaceAllElementsInFrame = (
);
};
/** does not mutate elements, but return new ones */
/** does not mutate elements, but returns new ones */
export const updateFrameMembershipOfSelectedElements = (
allElements: ExcalidrawElementsIncludingDeleted,
appState: AppState,