4db6d28603
* 提示词:完善组件建议,增加容器背景与节点大小一致的实现 * 支持Delete删除节点 ctrl + -缩放 * 步骤结束弹窗提醒   * UI 树快捷删除  * zoom滑动条样式 before:  after:  Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/278 Co-authored-by: 王德宇 <kvtodev@outlook.com> Co-committed-by: 王德宇 <kvtodev@outlook.com>
110 lines
3.5 KiB
TypeScript
110 lines
3.5 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
import { fireEvent } from '@testing-library/react';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { handleUiEditorKeyDown } from '../src/view/ui-editor/uiEditorKeyboardShortcuts';
|
|
|
|
describe('ui editor keyboard shortcuts', () => {
|
|
afterEach(() => {
|
|
document.body.replaceChildren();
|
|
});
|
|
|
|
it.each([
|
|
{ key: 'z', ctrlKey: true },
|
|
{ key: 'z', ctrlKey: true, shiftKey: true },
|
|
{ key: 'y', ctrlKey: true },
|
|
])('does not change history from inside a modal (%o)', (shortcut) => {
|
|
const dialog = document.createElement('div');
|
|
dialog.setAttribute('role', 'dialog');
|
|
const button = document.createElement('button');
|
|
dialog.append(button);
|
|
document.body.append(dialog);
|
|
const historyUndo = vi.fn(() => true);
|
|
const historyRedo = vi.fn(() => true);
|
|
const listener = (event: KeyboardEvent) =>
|
|
handleUiEditorKeyDown(event, {
|
|
selectedNodeId: null,
|
|
activeImageId: null,
|
|
deleteNode: vi.fn(),
|
|
historyUndo,
|
|
historyRedo,
|
|
});
|
|
window.addEventListener('keydown', listener);
|
|
|
|
fireEvent.keyDown(button, shortcut);
|
|
|
|
expect(historyUndo).not.toHaveBeenCalled();
|
|
expect(historyRedo).not.toHaveBeenCalled();
|
|
window.removeEventListener('keydown', listener);
|
|
});
|
|
|
|
it('keeps undo available from a non-modal button', () => {
|
|
const button = document.createElement('button');
|
|
document.body.append(button);
|
|
const historyUndo = vi.fn(() => true);
|
|
const historyRedo = vi.fn(() => true);
|
|
const listener = (event: KeyboardEvent) =>
|
|
handleUiEditorKeyDown(event, {
|
|
selectedNodeId: null,
|
|
activeImageId: null,
|
|
deleteNode: vi.fn(),
|
|
historyUndo,
|
|
historyRedo,
|
|
});
|
|
window.addEventListener('keydown', listener);
|
|
|
|
fireEvent.keyDown(button, { key: 'z', ctrlKey: true });
|
|
|
|
expect(historyUndo).toHaveBeenCalledTimes(1);
|
|
window.removeEventListener('keydown', listener);
|
|
});
|
|
|
|
it.each(['Delete', 'Backspace'])(
|
|
'does not delete a node when the zoom slider has focus (%s)',
|
|
(key) => {
|
|
const slider = document.createElement('input');
|
|
slider.type = 'range';
|
|
document.body.append(slider);
|
|
const deleteNode = vi.fn(() => ({ ok: true }));
|
|
const listener = (event: KeyboardEvent) =>
|
|
handleUiEditorKeyDown(event, {
|
|
selectedNodeId: 'node-1',
|
|
activeImageId: 'page-1',
|
|
deleteNode,
|
|
historyUndo: vi.fn(() => true),
|
|
historyRedo: vi.fn(() => true),
|
|
});
|
|
window.addEventListener('keydown', listener);
|
|
|
|
fireEvent.keyDown(slider, { key });
|
|
|
|
expect(deleteNode).not.toHaveBeenCalled();
|
|
window.removeEventListener('keydown', listener);
|
|
},
|
|
);
|
|
|
|
it('keeps node deletion available after zoom button focus is released', () => {
|
|
const zoomControls = document.createElement('div');
|
|
const zoomIn = document.createElement('button');
|
|
zoomControls.append(zoomIn);
|
|
document.body.append(zoomControls);
|
|
const deleteNode = vi.fn(() => ({ ok: true }));
|
|
const listener = (event: KeyboardEvent) =>
|
|
handleUiEditorKeyDown(event, {
|
|
selectedNodeId: 'node-1',
|
|
activeImageId: 'page-1',
|
|
deleteNode,
|
|
historyUndo: vi.fn(() => true),
|
|
historyRedo: vi.fn(() => true),
|
|
});
|
|
window.addEventListener('keydown', listener);
|
|
|
|
fireEvent.click(zoomIn);
|
|
fireEvent.keyDown(window, { key: 'Delete' });
|
|
|
|
expect(deleteNode).toHaveBeenCalledWith('node-1', 'page-1');
|
|
window.removeEventListener('keydown', listener);
|
|
});
|
|
});
|