feat: add play apps and layout tools

This commit is contained in:
2026-05-25 17:29:21 +09:00
parent f59522ffc4
commit 51e0099bea
46 changed files with 37152 additions and 119 deletions

View File

@@ -0,0 +1,45 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import {
clampSelectionRect,
findShapesInSelection,
rebaseShapesToComponentBlueprint,
resolveGroupedShapeIds,
} from '../../src/features/layout/draw/layoutDrawSelectionUtils.ts';
import type { DrawableShape } from '../../src/features/layout/draw/layoutDrawTypes.ts';
test('expands grouped selection from any seed id', () => {
const shapes: DrawableShape[] = [
{ id: 'a', type: 'rect', x: 0, y: 0, width: 10, height: 10, label: '', groupId: 'g1' },
{ id: 'b', type: 'rect', x: 20, y: 0, width: 10, height: 10, label: '', groupId: 'g1' },
{ id: 'c', type: 'rect', x: 40, y: 0, width: 10, height: 10, label: '' },
];
assert.deepEqual([...resolveGroupedShapeIds(shapes, ['a'])], ['a', 'b']);
});
test('finds shapes intersecting drag selection bounds', () => {
const shapes: DrawableShape[] = [
{ id: 'a', type: 'rect', x: 10, y: 10, width: 50, height: 50, label: '' },
{ id: 'b', type: 'line', x1: 80, y1: 20, x2: 140, y2: 20, orientation: 'horizontal', label: '' },
{ id: 'c', type: 'rect', x: 200, y: 200, width: 20, height: 20, label: '' },
];
const selection = clampSelectionRect(0, 0, 120, 80);
assert.deepEqual(
findShapesInSelection(shapes, selection).map((shape) => shape.id),
['a', 'b'],
);
});
test('rebases saved component shapes to local coordinates', () => {
const shapes: DrawableShape[] = [
{ id: 'a', type: 'rect', x: 100, y: 40, width: 30, height: 20, label: 'A' },
{ id: 'b', type: 'line', x1: 120, y1: 60, x2: 180, y2: 60, orientation: 'horizontal', label: 'B' },
];
assert.deepEqual(rebaseShapesToComponentBlueprint(shapes), [
{ id: 'a', type: 'rect', x: 0, y: 0, width: 30, height: 20, label: 'A' },
{ id: 'b', type: 'line', x1: 20, y1: 20, x2: 80, y2: 20, orientation: 'horizontal', label: 'B' },
]);
});