feat(input): support artboard selection

This commit is contained in:
syntaxbullet
2026-07-03 16:04:43 +02:00
parent 46aa1b8595
commit 28fcbdceda
4 changed files with 122 additions and 5 deletions

69
input/selection.test.ts Normal file
View File

@@ -0,0 +1,69 @@
import { describe, expect, test } from "bun:test";
import { commandIds } from "@commands/ids";
import { createInitialAppState } from "@editor/initial-state";
import { handleArtboardSelection } from "./selection";
import type { PointerInputEvent } from "./pointer";
const ignoredState = undefined as never;
describe("selection input", () => {
test("selects artboard hit by left click", () => {
const state = {
...createInitialAppState("Test"),
document: {
...createInitialAppState("Test").document,
artboards: [{ id: "a1", name: "Artboard", bounds: { x: -50, y: -50, w: 100, h: 100 }, backgroundColor: "transparent", layers: [] }],
},
editor: {
...createInitialAppState("Test").editor,
viewport: { center: { x: 0, y: 0 }, zoom: 1, rotation: 0, size: { w: 200, h: 200 } },
},
};
const dispatched: unknown[] = [];
const consumed = handleArtboardSelection({
event: pointerEvent({ position: { x: 100, y: 100 }, buttons: 1 }),
document: state.document,
viewport: state.editor.viewport,
dispatch: (commandId, payload) => {
dispatched.push({ commandId, payload });
return ignoredState;
},
});
expect(consumed).toBe(true);
expect(dispatched).toEqual([{ commandId: commandIds.selectionSet, payload: { artboardId: "a1", layerIds: [] } }]);
});
test("clears selection when clicking outside artboards", () => {
const state = createInitialAppState("Test");
const dispatched: unknown[] = [];
const consumed = handleArtboardSelection({
event: pointerEvent({ position: { x: 100, y: 100 }, buttons: 1 }),
document: state.document,
viewport: { center: { x: 0, y: 0 }, zoom: 1, rotation: 0, size: { w: 200, h: 200 } },
dispatch: (commandId, payload) => {
dispatched.push({ commandId, payload });
return ignoredState;
},
});
expect(consumed).toBe(true);
expect(dispatched).toEqual([{ commandId: commandIds.selectionClear, payload: undefined }]);
});
});
function pointerEvent(overrides: Partial<PointerInputEvent>): PointerInputEvent {
return {
pointerId: 1,
pointerType: "mouse",
position: { x: 0, y: 0 },
buttons: 0,
altKey: false,
ctrlKey: false,
metaKey: false,
shiftKey: false,
...overrides,
};
}