补充预览拖动当前选中节点契约

拖动命中其它节点时保持变换提交到按下前选中节点

补充跨节点拖动不重新选择命中节点的回归测试

避免无效选中节点提前捕获指针
This commit is contained in:
2026-09-04 14:17:06 +08:00
parent 2ebc97ad71
commit ab2c3465b0
2 changed files with 37 additions and 3 deletions
@@ -264,14 +264,14 @@ export function useNodeTransformInteraction({
) {
return;
}
event.stopPropagation();
event.currentTarget.setPointerCapture(event.pointerId);
suppressNextNodeClickRef.current = false;
const selectedNode =
selectedNodeId && tree ? findNodeById(tree.root, selectedNodeId) : null;
const dragNode =
selectedNode && selectedNode.id !== tree?.root.id ? selectedNode : node;
if (!isFiniteTransform(dragNode.layout.transform)) return;
event.stopPropagation();
event.currentTarget.setPointerCapture(event.pointerId);
suppressNextNodeClickRef.current = false;
event.preventDefault();
activeGestureRef.current = {
kind: 'drag',
@@ -131,6 +131,40 @@ function renderInteraction({
}
describe('useNodeTransformInteraction', () => {
it('moves the current selection when dragging another node without selecting the hit node', () => {
const selected = transformedNode('selected', {
anchor_min: [0, 0],
anchor_max: [0, 0],
offset_min: [20, 20],
offset_max: [80, 70],
});
const tree: UITree = {
src_ui_design: 'page',
root: node('root', [selected, child]),
};
const { result, canvasProjection } = renderInteraction({
tree,
selectedNodeId: 'selected',
});
const target = gestureTarget();
act(() => {
result.current.onNodePointerDown(pointerEvent(target, 1, 0, 0), child);
result.current.onNodePointerMove(pointerEvent(target, 1, 4, 0));
result.current.onNodePointerUp(pointerEvent(target, 1, 4, 0));
});
expect(canvasProjection.selectNode).not.toHaveBeenCalled();
expect(canvasProjection.updateNodeTransform).toHaveBeenCalledWith(
'page',
'selected',
expect.objectContaining({
offset_min: [24, 20],
offset_max: [84, 70],
}),
);
});
it('prevents native text selection when starting a node drag', () => {
const { result } = renderInteraction();
const target = gestureTarget();