import { mockDocument, TldrawTestApp } from '~test' import { SessionType, TDShapeType } from '~types' import { SelectTool } from '.' describe('SelectTool', () => { it('creates tool', () => { const app = new TldrawTestApp() new SelectTool(app) }) }) describe('When double clicking link controls', () => { const doc = new TldrawTestApp() .createShapes( { id: 'rect1', type: TDShapeType.Rectangle, point: [0, 0], size: [100, 100], }, { id: 'rect2', type: TDShapeType.Rectangle, point: [100, 0], size: [100, 100], }, { id: 'rect3', type: TDShapeType.Rectangle, point: [200, 0], size: [100, 100], }, { id: 'arrow1', type: TDShapeType.Arrow, point: [200, 200], }, { id: 'arrow2', type: TDShapeType.Arrow, point: [200, 200], } ) .select('arrow1') .movePointer({ x: 200, y: 200 }) .startSession(SessionType.Arrow, 'arrow1', 'start') .movePointer({ x: 50, y: 50 }) .completeSession() .movePointer({ x: 200, y: 200 }) .startSession(SessionType.Arrow, 'arrow1', 'end') .movePointer({ x: 150, y: 50 }) .completeSession() .select('arrow2') .movePointer({ x: 200, y: 200 }) .startSession(SessionType.Arrow, 'arrow2', 'start') .movePointer({ x: 150, y: 50 }) .completeSession() .movePointer({ x: 200, y: 200 }) .startSession(SessionType.Arrow, 'arrow2', 'end') .movePointer({ x: 250, y: 50 }) .completeSession() .selectNone().document it('moves all linked shapes when center is dragged', () => { const app = new TldrawTestApp() .loadDocument(doc) .select('rect2') .pointBoundsHandle('center', [100, 100]) .expectShapesToBeAtPoints({ rect1: [0, 0], rect2: [100, 0], rect3: [200, 0], }) app.movePointer([200, 200]).expectShapesToBeAtPoints({ rect1: [100, 100], rect2: [200, 100], rect3: [300, 100], }) app.completeSession().undo() app.expectShapesToBeAtPoints({ rect1: [0, 0], rect2: [100, 0], rect3: [200, 0], }) }) it('moves all upstream shapes when center is dragged', () => { const app = new TldrawTestApp() .loadDocument(doc) .select('rect2') .pointBoundsHandle('center') .movePointer({ x: 100, y: 100 }) expect(app.getShape('rect1').point).toEqual([100, 100]) expect(app.getShape('rect2').point).toEqual([200, 100]) expect(app.getShape('rect3').point).toEqual([300, 100]) }) it('moves all downstream shapes when center is dragged', () => { const app = new TldrawTestApp() .loadDocument(doc) .select('rect2') .pointBoundsHandle('right') .movePointer({ x: 100, y: 100 }) expect(app.getShape('rect1').point).toEqual([0, 0]) expect(app.getShape('rect2').point).toEqual([200, 100]) expect(app.getShape('rect3').point).toEqual([300, 100]) }) it('selects all linked shapes when center is double clicked', () => { new TldrawTestApp() .loadDocument(doc) .select('rect2') .doubleClickBoundHandle('center') .expectSelectedIdsToBe(['rect2', 'rect1', 'rect3']) }) it('selects all linked shapes and arrows when center is double clicked while holding shift', () => { new TldrawTestApp() .loadDocument(doc) .select('rect2') .doubleClickBoundHandle('center', { shiftKey: true }) .expectSelectedIdsToBe(['rect2', 'rect1', 'rect3', 'arrow1', 'arrow2']) }) it('selects all upstream linked shapes when left is double clicked', () => { new TldrawTestApp() .loadDocument(doc) .select('rect2') .doubleClickBoundHandle('left') .expectSelectedIdsToBe(['rect1', 'rect2']) }) it('selects all upstream linked shapes and arrows when left is double clicked with shift', () => { new TldrawTestApp() .loadDocument(doc) .select('rect2') .doubleClickBoundHandle('left', { shiftKey: true }) .expectSelectedIdsToBe(['rect1', 'rect2', 'arrow1']) }) it('selects all downstream linked shapes when right is double clicked', () => { new TldrawTestApp() .loadDocument(doc) .select('rect2') .doubleClickBoundHandle('right') .expectSelectedIdsToBe(['rect2', 'rect3']) }) it('selects all downstream linked shapes and arrows when right is double clicked with shift', () => { new TldrawTestApp() .loadDocument(doc) .select('rect2') .doubleClickBoundHandle('right', { shiftKey: true }) .expectSelectedIdsToBe(['rect2', 'rect3', 'arrow2']) }) }) describe('When selecting grouped shapes', () => { it('Selects the group on single click', () => { const app = new TldrawTestApp() .loadDocument(mockDocument) .group(['rect1', 'rect2'], 'groupA') .clickShape('rect1') expect(app.selectedIds).toStrictEqual(['groupA']) }) it('Drills in and selects the child on double click', () => { const app = new TldrawTestApp() .loadDocument(mockDocument) .group(['rect1', 'rect2'], 'groupA') .doubleClickShape('rect1') expect(app.selectedIds).toStrictEqual(['rect1']) }) it('Selects a sibling on single click after drilling', () => { const app = new TldrawTestApp() .loadDocument(mockDocument) .group(['rect1', 'rect2'], 'groupA') .doubleClickShape('rect1') .clickShape('rect2') expect(app.selectedIds).toStrictEqual(['rect2']) }) it('Selects the group again after selecting a different shape', () => { const app = new TldrawTestApp() .loadDocument(mockDocument) .selectAll() .group(['rect1', 'rect2'], 'groupA') .doubleClickShape('rect1') .clickShape('rect3') .clickShape('rect1') expect(app.selectedIds).toStrictEqual(['groupA']) }) it('Selects grouped text on double click', () => { const app = new TldrawTestApp() .loadDocument(mockDocument) .createShapes({ id: 'text1', type: TDShapeType.Text, text: 'Hello world', }) .group(['rect1', 'rect2', 'text1'], 'groupA') .doubleClickShape('text1') expect(app.selectedIds).toStrictEqual(['text1']) expect(app.pageState.editingId).toBeUndefined() }) it('Edits grouped text on double click after selecting', () => { const app = new TldrawTestApp() .loadDocument(mockDocument) .createShapes({ id: 'text1', type: TDShapeType.Text, text: 'Hello world', }) .group(['rect1', 'rect2', 'text1'], 'groupA') .doubleClickShape('text1') .doubleClickShape('text1') expect(app.selectedIds).toStrictEqual(['text1']) expect(app.pageState.editingId).toBe('text1') }) })