Fix bug when nudging shapes with bindings
This commit is contained in:
parent
d09d4087d3
commit
054a9e4acd
2 changed files with 86 additions and 5 deletions
|
@ -1,5 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import { TLDrawState } from '~state'
|
||||
import { mockDocument } from '~test'
|
||||
import { ArrowShape, TLDrawShapeType } from '~types'
|
||||
|
||||
describe('Translate command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
@ -27,6 +29,83 @@ describe('Translate command', () => {
|
|||
expect(tlstate.getShape('rect2').point).toEqual([110, 120])
|
||||
})
|
||||
|
||||
it.todo('deleted bindings if nudging shape is bound to other shapes')
|
||||
// When nudging an arrow shape, delete its bindings
|
||||
describe('when nudging shapes with bindings', () => {
|
||||
it('deleted bindings if nudging shape is bound to other shapes', () => {
|
||||
tlstate
|
||||
.resetDocument()
|
||||
.createShapes(
|
||||
{
|
||||
id: 'target1',
|
||||
type: TLDrawShapeType.Rectangle,
|
||||
point: [0, 0],
|
||||
size: [100, 100],
|
||||
},
|
||||
{
|
||||
type: TLDrawShapeType.Arrow,
|
||||
id: 'arrow1',
|
||||
point: [200, 200],
|
||||
}
|
||||
)
|
||||
.select('arrow1')
|
||||
.startHandleSession([200, 200], 'start')
|
||||
.updateHandleSession([50, 50])
|
||||
.completeSession()
|
||||
|
||||
const bindingId = tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId!
|
||||
|
||||
tlstate.select('arrow1').nudge([10, 10])
|
||||
|
||||
expect(tlstate.getBinding(bindingId)).toBeUndefined()
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBeUndefined()
|
||||
|
||||
tlstate.undo()
|
||||
|
||||
expect(tlstate.getBinding(bindingId)).toBeDefined()
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBe(bindingId)
|
||||
|
||||
tlstate.redo()
|
||||
|
||||
expect(tlstate.getBinding(bindingId)).toBeUndefined()
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBeUndefined()
|
||||
})
|
||||
|
||||
it('does not delete bindings if both bound and bound-to shapes are nudged', () => {
|
||||
tlstate
|
||||
.resetDocument()
|
||||
.createShapes(
|
||||
{
|
||||
id: 'target1',
|
||||
type: TLDrawShapeType.Rectangle,
|
||||
point: [0, 0],
|
||||
size: [100, 100],
|
||||
},
|
||||
{
|
||||
type: TLDrawShapeType.Arrow,
|
||||
id: 'arrow1',
|
||||
point: [200, 200],
|
||||
}
|
||||
)
|
||||
.select('arrow1')
|
||||
.startHandleSession([200, 200], 'start')
|
||||
.updateHandleSession([50, 50])
|
||||
.completeSession()
|
||||
|
||||
const bindingId = tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId!
|
||||
|
||||
tlstate.select('arrow1', 'target1').nudge([10, 10])
|
||||
|
||||
expect(tlstate.getBinding(bindingId)).toBeDefined()
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBe(bindingId)
|
||||
|
||||
tlstate.undo()
|
||||
|
||||
expect(tlstate.getBinding(bindingId)).toBeDefined()
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBe(bindingId)
|
||||
|
||||
tlstate.redo()
|
||||
|
||||
expect(tlstate.getBinding(bindingId)).toBeDefined()
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBe(bindingId)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -27,8 +27,9 @@ export function translate(data: Data, ids: string[], delta: number[]): TLDrawCom
|
|||
before.shapes = change.before
|
||||
after.shapes = change.after
|
||||
|
||||
const bindingsToDelete = TLDR.getBindings(data, currentPageId).filter((binding) =>
|
||||
ids.includes(binding.fromId)
|
||||
// Delete bindings from nudged shapes, unless both bound and bound-to shapes are selected
|
||||
const bindingsToDelete = TLDR.getBindings(data, currentPageId).filter(
|
||||
(binding) => ids.includes(binding.fromId) && !ids.includes(binding.toId)
|
||||
)
|
||||
|
||||
bindingsToDelete.forEach((binding) => {
|
||||
|
@ -39,9 +40,10 @@ export function translate(data: Data, ids: string[], delta: number[]): TLDrawCom
|
|||
// Let's also look at the bound shape...
|
||||
const shape = TLDR.getShape(data, id, data.appState.currentPageId)
|
||||
|
||||
// If the bound shape has a handle that references the deleted binding, delete that reference
|
||||
if (!shape.handles) continue
|
||||
|
||||
// If the bound shape has a handle that references the deleted binding, delete that reference
|
||||
|
||||
Object.values(shape.handles)
|
||||
.filter((handle) => handle.bindingId === binding.id)
|
||||
.forEach((handle) => {
|
||||
|
|
Loading…
Reference in a new issue