diff --git a/apps/ai-game-creator-shell/tests/TransformEditor.test.tsx b/apps/ai-game-creator-shell/tests/TransformEditor.test.tsx new file mode 100644 index 000000000..e8b28f0dc --- /dev/null +++ b/apps/ai-game-creator-shell/tests/TransformEditor.test.tsx @@ -0,0 +1,79 @@ +// @vitest-environment jsdom + +import { fireEvent, render, screen } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; + +import type { Transform } from '../src/features/ui-editor/types/Transform'; +import { TransformEditor } from '../src/view/ui-editor/components/Inspector/Transform/TransformEditor'; + +const transform: Transform = { + anchor_min: [0, 0], + anchor_max: [1, 1], + offset_min: [10, 20], + offset_max: [30, 40], +}; + +function renderEditor(onChange = vi.fn()) { + return { + onChange, + ...render(), + }; +} + +describe('TransformEditor corner offset controls', () => { + it('uses one X/Y input pair for the selected corner', () => { + renderEditor(); + + expect( + screen.getByRole('spinbutton', { name: '左上角偏移 X' }), + ).toHaveProperty('value', '10'); + expect( + screen.getByRole('spinbutton', { name: '左上角偏移 Y' }), + ).toHaveProperty('value', '20'); + expect(screen.getAllByRole('spinbutton')).toHaveLength(2); + + fireEvent.click(screen.getByRole('button', { name: '右下角' })); + + expect( + screen.getByRole('spinbutton', { name: '右下角偏移 X' }), + ).toHaveProperty('value', '30'); + expect( + screen.getByRole('spinbutton', { name: '右下角偏移 Y' }), + ).toHaveProperty('value', '40'); + }); + + it('writes the selected corner input back to the matching offset component', () => { + const { onChange } = renderEditor(); + + fireEvent.click(screen.getByRole('button', { name: '右上角' })); + const xInput = screen.getByRole('spinbutton', { + name: '右上角偏移 X', + }); + fireEvent.change(xInput, { target: { value: '55' } }); + fireEvent.blur(xInput); + + expect(onChange).toHaveBeenLastCalledWith({ + ...transform, + offset_max: [55, 40], + }); + }); + + it('moves only the selected corner with direction keys', () => { + const { onChange } = renderEditor(); + + fireEvent.click(screen.getByRole('button', { name: '右下角' })); + fireEvent.click(screen.getByRole('button', { name: '右下角向左' })); + expect(onChange).toHaveBeenLastCalledWith({ + ...transform, + offset_max: [29, 40], + }); + + fireEvent.click(screen.getByRole('button', { name: '右下角向上' }), { + shiftKey: true, + }); + expect(onChange).toHaveBeenLastCalledWith({ + ...transform, + offset_max: [30, 30], + }); + }); +}); diff --git a/docs/technical/【设计】UI编辑器变换角点偏移编辑器-2026-09-03.md b/docs/technical/【设计】UI编辑器变换角点偏移编辑器-2026-09-03.md index 93d608421..2d7728779 100644 --- a/docs/technical/【设计】UI编辑器变换角点偏移编辑器-2026-09-03.md +++ b/docs/technical/【设计】UI编辑器变换角点偏移编辑器-2026-09-03.md @@ -23,7 +23,7 @@ ## 交互 -- 组件内部维护当前选中角,默认左上;节点或 `transform` 切换时重置为左上。 +- 组件内部维护当前选中角,首次挂载时默认左上;切换角点由用户控制,编辑过程中不会因 offset 更新而跳回其他角。 - 四角按钮按左上、右上、左下、右下空间位置排布;当前角高亮并提供可访问名称。 - 页面只渲染一组 X/Y 数字输入和一组上、下、左、右方向键,二者都只作用于当前选中角。 - 方向键每次按 `1` 调整对应分量;按住支持连续触发,按住 `Shift` 时步长为 `10`。