mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-04 21:04:34 +01:00
feat: do not delete frame children on frame delete (#9011)
This commit is contained in:
@@ -7,7 +7,7 @@ import { getNonDeletedElements } from "../element";
|
||||
import type { ExcalidrawElement } from "../element/types";
|
||||
import type { AppClassProperties, AppState } from "../types";
|
||||
import { mutateElement, newElementWith } from "../element/mutateElement";
|
||||
import { getElementsInGroup } from "../groups";
|
||||
import { getElementsInGroup, selectGroupsForSelectedElements } from "../groups";
|
||||
import { LinearElementEditor } from "../element/linearElementEditor";
|
||||
import { fixBindingsAfterDeletion } from "../element/binding";
|
||||
import {
|
||||
@@ -33,48 +33,99 @@ const deleteSelectedElements = (
|
||||
).map((el) => el.id),
|
||||
);
|
||||
|
||||
return {
|
||||
elements: elements.map((el) => {
|
||||
if (appState.selectedElementIds[el.id]) {
|
||||
if (el.boundElements) {
|
||||
el.boundElements.forEach((candidate) => {
|
||||
const bound = app.scene
|
||||
.getNonDeletedElementsMap()
|
||||
.get(candidate.id);
|
||||
if (bound && isElbowArrow(bound)) {
|
||||
mutateElement(bound, {
|
||||
startBinding:
|
||||
el.id === bound.startBinding?.elementId
|
||||
? null
|
||||
: bound.startBinding,
|
||||
endBinding:
|
||||
el.id === bound.endBinding?.elementId
|
||||
? null
|
||||
: bound.endBinding,
|
||||
});
|
||||
mutateElbowArrow(bound, elementsMap, bound.points);
|
||||
}
|
||||
});
|
||||
const selectedElementIds: Record<ExcalidrawElement["id"], true> = {};
|
||||
|
||||
let shouldSelectEditingGroup = true;
|
||||
|
||||
const nextElements = elements.map((el) => {
|
||||
if (appState.selectedElementIds[el.id]) {
|
||||
if (el.boundElements) {
|
||||
el.boundElements.forEach((candidate) => {
|
||||
const bound = app.scene.getNonDeletedElementsMap().get(candidate.id);
|
||||
if (bound && isElbowArrow(bound)) {
|
||||
mutateElement(bound, {
|
||||
startBinding:
|
||||
el.id === bound.startBinding?.elementId
|
||||
? null
|
||||
: bound.startBinding,
|
||||
endBinding:
|
||||
el.id === bound.endBinding?.elementId ? null : bound.endBinding,
|
||||
});
|
||||
mutateElbowArrow(bound, elementsMap, bound.points);
|
||||
}
|
||||
});
|
||||
}
|
||||
return newElementWith(el, { isDeleted: true });
|
||||
}
|
||||
|
||||
// if deleting a frame, remove the children from it and select them
|
||||
if (el.frameId && framesToBeDeleted.has(el.frameId)) {
|
||||
shouldSelectEditingGroup = false;
|
||||
selectedElementIds[el.id] = true;
|
||||
return newElementWith(el, { frameId: null });
|
||||
}
|
||||
|
||||
if (isBoundToContainer(el) && appState.selectedElementIds[el.containerId]) {
|
||||
return newElementWith(el, { isDeleted: true });
|
||||
}
|
||||
return el;
|
||||
});
|
||||
|
||||
let nextEditingGroupId = appState.editingGroupId;
|
||||
|
||||
// select next eligible element in currently editing group or supergroup
|
||||
if (shouldSelectEditingGroup && appState.editingGroupId) {
|
||||
const elems = getElementsInGroup(
|
||||
nextElements,
|
||||
appState.editingGroupId,
|
||||
).filter((el) => !el.isDeleted);
|
||||
if (elems.length > 1) {
|
||||
if (elems[0]) {
|
||||
selectedElementIds[elems[0].id] = true;
|
||||
}
|
||||
} else {
|
||||
nextEditingGroupId = null;
|
||||
if (elems[0]) {
|
||||
selectedElementIds[elems[0].id] = true;
|
||||
}
|
||||
|
||||
const lastElementInGroup = elems[0];
|
||||
if (lastElementInGroup) {
|
||||
const editingGroupIdx = lastElementInGroup.groupIds.findIndex(
|
||||
(groupId) => {
|
||||
return groupId === appState.editingGroupId;
|
||||
},
|
||||
);
|
||||
const superGroupId = lastElementInGroup.groupIds[editingGroupIdx + 1];
|
||||
if (superGroupId) {
|
||||
const elems = getElementsInGroup(nextElements, superGroupId).filter(
|
||||
(el) => !el.isDeleted,
|
||||
);
|
||||
if (elems.length > 1) {
|
||||
nextEditingGroupId = superGroupId;
|
||||
|
||||
elems.forEach((el) => {
|
||||
selectedElementIds[el.id] = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
return newElementWith(el, { isDeleted: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (el.frameId && framesToBeDeleted.has(el.frameId)) {
|
||||
return newElementWith(el, { isDeleted: true });
|
||||
}
|
||||
|
||||
if (
|
||||
isBoundToContainer(el) &&
|
||||
appState.selectedElementIds[el.containerId]
|
||||
) {
|
||||
return newElementWith(el, { isDeleted: true });
|
||||
}
|
||||
return el;
|
||||
}),
|
||||
return {
|
||||
elements: nextElements,
|
||||
appState: {
|
||||
...appState,
|
||||
selectedElementIds: {},
|
||||
selectedGroupIds: {},
|
||||
...selectGroupsForSelectedElements(
|
||||
{
|
||||
selectedElementIds,
|
||||
editingGroupId: nextEditingGroupId,
|
||||
},
|
||||
nextElements,
|
||||
appState,
|
||||
null,
|
||||
),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user