|
@@ -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);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- return newElementWith(el, { isDeleted: true });
|
|
|
+ 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;
|
|
|
|
|
|
- if (el.frameId && framesToBeDeleted.has(el.frameId)) {
|
|
|
- return newElementWith(el, { isDeleted: true });
|
|
|
+ // 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;
|
|
|
}
|
|
|
|
|
|
- if (
|
|
|
- isBoundToContainer(el) &&
|
|
|
- appState.selectedElementIds[el.containerId]
|
|
|
- ) {
|
|
|
- return newElementWith(el, { isDeleted: 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 el;
|
|
|
- }),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ elements: nextElements,
|
|
|
appState: {
|
|
|
...appState,
|
|
|
- selectedElementIds: {},
|
|
|
- selectedGroupIds: {},
|
|
|
+ ...selectGroupsForSelectedElements(
|
|
|
+ {
|
|
|
+ selectedElementIds,
|
|
|
+ editingGroupId: nextEditingGroupId,
|
|
|
+ },
|
|
|
+ nextElements,
|
|
|
+ appState,
|
|
|
+ null,
|
|
|
+ ),
|
|
|
},
|
|
|
};
|
|
|
};
|