UI编辑器一批细节优化 #278

Merged
kdletters merged 44 commits from fix/ui-editor-minor-adjusts into master 2026-09-08 11:56:36 +08:00
3 changed files with 56 additions and 7 deletions
Showing only changes of commit 5898d38083 - Show all commits
@@ -79,24 +79,48 @@ export default function UiEditorPage({
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
session.save.isLocked;
const historyUndo = session.history.undo;
const historyRedo = session.history.redo;
const selectedNodeId = session.input.selectedNodeId;
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
const activeImageId = session.input.activeImageId;
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
const deleteNode = session.input.deleteNode;
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
useEffect(() => {
if (session.save.isDirty) setGenerateSuccess(null);
}, [session.save.isDirty]);
useEffect(() => {
const isEditableTarget = (target: EventTarget | null) => {
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
const element = target instanceof HTMLElement ? target : null;
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
const isInteractiveTarget = (target: EventTarget | null) => {
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
const element = target instanceof Element ? target : null;
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
return Boolean(
element?.isContentEditable ||
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
element?.closest('input, textarea, select, [contenteditable="true"]'),
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
(target instanceof HTMLElement && target.isContentEditable) ||
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
element?.closest(
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
'button, a, input, textarea, select, [contenteditable="true"], [role="button"]',
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
),
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
);
};
const onKeyDown = (event: KeyboardEvent) => {
if (
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
event.key === 'Delete' &&
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
!event.repeat &&
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
!event.defaultPrevented &&
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
!event.ctrlKey &&
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
!event.metaKey &&
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
!event.altKey &&
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
!event.shiftKey &&
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
!isInteractiveTarget(event.target)
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
) {
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
if (selectedNodeId && activeImageId) {
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
const result = deleteNode(selectedNodeId, activeImageId);
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
if (result?.ok) {
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
event.preventDefault();
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
event.stopPropagation();
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
return;
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
}
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
}
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
}
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
if (
event.repeat ||
event.defaultPrevented ||
isEditableTarget(event.target) ||
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
isInteractiveTarget(event.target) ||
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
(!event.ctrlKey && !event.metaKey)
) {
return;
@@ -113,7 +137,7 @@ export default function UiEditorPage({
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
};
window.addEventListener('keydown', onKeyDown);
return () => window.removeEventListener('keydown', onKeyDown);
}, [historyRedo, historyUndo]);
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
}, [activeImageId, deleteNode, historyRedo, historyUndo, selectedNodeId]);
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
async function save(afterReturn = false) {
if (await session.save.save()) {
k88936 marked this conversation as resolved
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
Review

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。

完成通知弹窗打开时,页面级 keydown 监听仍会处理 Ctrl/Cmd+Z/Y:onKeyDown 只排除了可编辑元素,没有排除当前 role=dialog/弹窗内焦点。因此用户在弹窗的关闭按钮上按 Ctrl+Z(或 Ctrl+Shift+Z/Ctrl+Y)会直接撤销/重做底层 UI 编辑,弹窗声称阻塞工作台交互但状态仍被修改。建议在快捷键处理前检测 event.target 是否位于 role=dialog(或维护 modal-open 状态)并直接 return;同时补充弹窗打开时快捷键不改变编辑状态的测试。
@@ -437,6 +437,9 @@ export function useUiEditorSession(
);
return next.size === current.size ? current : next;
});
setSelectedNodeId((current) =>
current && !validNodeIds.has(current) ? null : current,
);
}, [editor.state.ui_trees]);
const isNodePreviewVisible = useCallback(
@@ -881,12 +884,17 @@ export function useUiEditorSession(
function deleteNode(nodeId: NodeId, treeId = activeImageId) {
if (!treeId) return;
const tree = editor.state.ui_trees.find(
(candidate) => candidate.src_ui_design === treeId,
);
const location = tree ? findUiNodeLocation(tree.root, nodeId) : null;
const deletedNodeIds = location ? collectUiNodeIds(location.node) : null;
const result = editor.deleteNode(treeId, nodeId);
if (!result.ok) {
setStatus('无法删除该节点。');
return result;
}
if (selectedNodeId === nodeId) setSelectedNodeId(null);
if (deletedNodeIds?.has(selectedNodeId ?? '')) setSelectedNodeId(null);
return result;
}
@@ -473,6 +473,23 @@ describe('UiEditorPage', () => {
expect(result.current.canvas.hiddenNodeIds.size).toBe(0);
});
it('clears selection when deleting a node removes the selected descendant', async () => {
const { result } = await renderLoadedSession(stateWithPages(['page']));
const rootId = 'page-root';
let parentId: string | undefined;
let childId: string | undefined;
act(() => {
parentId = result.current.input.insertNode(rootId, 'page')?.value;
childId = result.current.input.insertNode(parentId!, 'page')?.value;
result.current.input.selectNode(childId!);
});
act(() => result.current.input.deleteNode(parentId!, 'page'));
expect(result.current.canvas.selectedNodeId).toBeNull();
expect(result.current.history.canUndo).toBe(true);
});
it('keeps Inspector status highlighting separate from node navigation', async () => {
const { result } = await renderLoadedSession(stateWithPages(['page']));
const rootId = 'page-root';