fix: adding to selection via shift box-select (#6815)
This commit is contained in:
parent
cbd908097f
commit
8af9ea3cf3
@ -6068,28 +6068,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
pointerDownState.boxSelection.hasOccurred = true;
|
pointerDownState.boxSelection.hasOccurred = true;
|
||||||
|
|
||||||
const elements = this.scene.getNonDeletedElements();
|
const elements = this.scene.getNonDeletedElements();
|
||||||
if (
|
|
||||||
!event.shiftKey &&
|
|
||||||
// allows for box-selecting points (without shift)
|
|
||||||
!this.state.editingLinearElement &&
|
|
||||||
isSomeElementSelected(elements, this.state)
|
|
||||||
) {
|
|
||||||
if (pointerDownState.withCmdOrCtrl && pointerDownState.hit.element) {
|
|
||||||
this.setState((prevState) =>
|
|
||||||
selectGroupsForSelectedElements(
|
|
||||||
{
|
|
||||||
...prevState,
|
|
||||||
selectedElementIds: {
|
|
||||||
[pointerDownState.hit.element!.id]: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
this.scene.getNonDeletedElements(),
|
|
||||||
prevState,
|
|
||||||
this,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// box-select line editor points
|
// box-select line editor points
|
||||||
if (this.state.editingLinearElement) {
|
if (this.state.editingLinearElement) {
|
||||||
LinearElementEditor.handleBoxSelection(
|
LinearElementEditor.handleBoxSelection(
|
||||||
@ -6099,18 +6078,46 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
);
|
);
|
||||||
// regular box-select
|
// regular box-select
|
||||||
} else {
|
} else {
|
||||||
|
let shouldReuseSelection = true;
|
||||||
|
|
||||||
|
if (!event.shiftKey && isSomeElementSelected(elements, this.state)) {
|
||||||
|
if (
|
||||||
|
pointerDownState.withCmdOrCtrl &&
|
||||||
|
pointerDownState.hit.element
|
||||||
|
) {
|
||||||
|
this.setState((prevState) =>
|
||||||
|
selectGroupsForSelectedElements(
|
||||||
|
{
|
||||||
|
...prevState,
|
||||||
|
selectedElementIds: {
|
||||||
|
[pointerDownState.hit.element!.id]: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
this.scene.getNonDeletedElements(),
|
||||||
|
prevState,
|
||||||
|
this,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
shouldReuseSelection = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
const elementsWithinSelection = getElementsWithinSelection(
|
const elementsWithinSelection = getElementsWithinSelection(
|
||||||
elements,
|
elements,
|
||||||
draggingElement,
|
draggingElement,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.setState((prevState) => {
|
this.setState((prevState) => {
|
||||||
const nextSelectedElementIds = elementsWithinSelection.reduce(
|
const nextSelectedElementIds = {
|
||||||
(acc: Record<ExcalidrawElement["id"], true>, element) => {
|
...(shouldReuseSelection && prevState.selectedElementIds),
|
||||||
acc[element.id] = true;
|
...elementsWithinSelection.reduce(
|
||||||
return acc;
|
(acc: Record<ExcalidrawElement["id"], true>, element) => {
|
||||||
},
|
acc[element.id] = true;
|
||||||
{},
|
return acc;
|
||||||
);
|
},
|
||||||
|
{},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
if (pointerDownState.hit.element) {
|
if (pointerDownState.hit.element) {
|
||||||
// if using ctrl/cmd, select the hitElement only if we
|
// if using ctrl/cmd, select the hitElement only if we
|
||||||
@ -6125,6 +6132,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
return selectGroupsForSelectedElements(
|
return selectGroupsForSelectedElements(
|
||||||
{
|
{
|
||||||
...prevState,
|
...prevState,
|
||||||
|
...(!shouldReuseSelection && {
|
||||||
|
selectedGroupIds: {},
|
||||||
|
editingGroupId: null,
|
||||||
|
}),
|
||||||
selectedElementIds: nextSelectedElementIds,
|
selectedElementIds: nextSelectedElementIds,
|
||||||
showHyperlinkPopup:
|
showHyperlinkPopup:
|
||||||
elementsWithinSelection.length === 1 &&
|
elementsWithinSelection.length === 1 &&
|
||||||
|
@ -28,6 +28,74 @@ const { h } = window;
|
|||||||
|
|
||||||
const mouse = new Pointer("mouse");
|
const mouse = new Pointer("mouse");
|
||||||
|
|
||||||
|
describe("box-selection", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await render(<ExcalidrawApp />);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow adding to selection via box-select when holding shift", async () => {
|
||||||
|
const rect1 = API.createElement({
|
||||||
|
type: "rectangle",
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
backgroundColor: "red",
|
||||||
|
fillStyle: "solid",
|
||||||
|
});
|
||||||
|
const rect2 = API.createElement({
|
||||||
|
type: "rectangle",
|
||||||
|
x: 100,
|
||||||
|
y: 0,
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
});
|
||||||
|
|
||||||
|
h.elements = [rect1, rect2];
|
||||||
|
|
||||||
|
mouse.downAt(175, -20);
|
||||||
|
mouse.moveTo(85, 70);
|
||||||
|
mouse.up();
|
||||||
|
|
||||||
|
assertSelectedElements([rect2.id]);
|
||||||
|
|
||||||
|
Keyboard.withModifierKeys({ shift: true }, () => {
|
||||||
|
mouse.downAt(75, -20);
|
||||||
|
mouse.moveTo(-15, 70);
|
||||||
|
mouse.up();
|
||||||
|
});
|
||||||
|
|
||||||
|
assertSelectedElements([rect2.id, rect1.id]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should (de)select element when box-selecting over and out while not holding shift", async () => {
|
||||||
|
const rect1 = API.createElement({
|
||||||
|
type: "rectangle",
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
backgroundColor: "red",
|
||||||
|
fillStyle: "solid",
|
||||||
|
});
|
||||||
|
|
||||||
|
h.elements = [rect1];
|
||||||
|
|
||||||
|
mouse.downAt(75, -20);
|
||||||
|
mouse.moveTo(-15, 70);
|
||||||
|
|
||||||
|
assertSelectedElements([rect1.id]);
|
||||||
|
|
||||||
|
mouse.moveTo(100, -100);
|
||||||
|
|
||||||
|
assertSelectedElements([]);
|
||||||
|
|
||||||
|
mouse.up();
|
||||||
|
|
||||||
|
assertSelectedElements([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("inner box-selection", () => {
|
describe("inner box-selection", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await render(<ExcalidrawApp />);
|
await render(<ExcalidrawApp />);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user