fix: duplicating/removing frame while children selected (#9079)

This commit is contained in:
David Luzar 2025-02-04 19:23:47 +01:00 committed by GitHub
parent 302664e500
commit 424e94a403
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 3160 additions and 2065 deletions

View file

@ -40,6 +40,7 @@ import { createTestHook } from "../../components/App";
import type { Action } from "../../actions/types";
import { mutateElement } from "../../element/mutateElement";
import { pointFrom, type LocalPoint, type Radians } from "../../../math";
import { selectGroupsForSelectedElements } from "../../groups";
const readFile = util.promisify(fs.readFile);
// so that window.h is available when App.tsx is not imported as well.
@ -68,13 +69,21 @@ export class API {
});
};
static setSelectedElements = (elements: ExcalidrawElement[]) => {
static setSelectedElements = (elements: ExcalidrawElement[], editingGroupId?: string | null) => {
act(() => {
h.setState({
selectedElementIds: elements.reduce((acc, element) => {
acc[element.id] = true;
return acc;
}, {} as Record<ExcalidrawElement["id"], true>),
...selectGroupsForSelectedElements(
{
editingGroupId: editingGroupId ?? null,
selectedElementIds: elements.reduce((acc, element) => {
acc[element.id] = true;
return acc;
}, {} as Record<ExcalidrawElement["id"], true>),
},
elements,
h.state,
h.app,
)
});
});
};
@ -158,7 +167,7 @@ export class API {
isDeleted?: boolean;
frameId?: ExcalidrawElement["id"] | null;
index?: ExcalidrawElement["index"];
groupIds?: string[];
groupIds?: ExcalidrawElement["groupIds"];
// generic element props
strokeColor?: ExcalidrawGenericElement["strokeColor"];
backgroundColor?: ExcalidrawGenericElement["backgroundColor"];
@ -369,6 +378,84 @@ export class API {
return element as any;
};
static createTextContainer = (opts?: {
frameId?: ExcalidrawElement["id"];
groupIds?: ExcalidrawElement["groupIds"];
label?: {
text?: string;
frameId?: ExcalidrawElement["id"] | null;
groupIds?: ExcalidrawElement["groupIds"];
};
}) => {
const rectangle = API.createElement({
type: "rectangle",
frameId: opts?.frameId || null,
groupIds: opts?.groupIds,
});
const text = API.createElement({
type: "text",
text: opts?.label?.text || "sample-text",
width: 50,
height: 20,
fontSize: 16,
containerId: rectangle.id,
frameId:
opts?.label?.frameId === undefined
? opts?.frameId ?? null
: opts?.label?.frameId ?? null,
groupIds: opts?.label?.groupIds === undefined
? opts?.groupIds
: opts?.label?.groupIds ,
});
mutateElement(
rectangle,
{
boundElements: [{ type: "text", id: text.id }],
},
false,
);
return [rectangle, text];
};
static createLabeledArrow = (opts?: {
frameId?: ExcalidrawElement["id"];
label?: {
text?: string;
frameId?: ExcalidrawElement["id"] | null;
};
}) => {
const arrow = API.createElement({
type: "arrow",
frameId: opts?.frameId || null,
});
const text = API.createElement({
type: "text",
id: "text2",
width: 50,
height: 20,
containerId: arrow.id,
frameId:
opts?.label?.frameId === undefined
? opts?.frameId ?? null
: opts?.label?.frameId ?? null,
});
mutateElement(
arrow,
{
boundElements: [{ type: "text", id: text.id }],
},
false,
);
return [arrow, text];
};
static readFile = async <T extends "utf8" | null>(
filepath: string,
encoding?: T,