mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 01:18:34 +00:00
PageScene: commit panel transform session on mouseup / Enter / Ctrl+Z
Follow-up to 72071c0066. The session-based panel transform recording
fixed pollution but introduced a new bug: while editing the same
object's panel without changing selection, the session never
committed, so Ctrl+Z fell through to the most recent prior entry —
typically the CreateAction for the shape, which deleted it on undo.
Add three document-level commit triggers covering the natural editing
boundaries the user expects:
- mouseup (any document-level mouseup): catches the end of an
InputVector numeric-scrub drag and any click that moves focus
elsewhere after typing.
- Enter key: explicit "done editing" commit even when the input
retains focus.
- Ctrl+Z / Ctrl+Y (capture phase): flushes the pending session before
the engine's keymap handler runs undo/redo, so the pending edit is
what gets reverted instead of the prior entry.
Capture phase on the keydown listener is load-bearing: keymap.ts
attaches its handler in bubble phase via useViewportKeyboard. Capture
fires first, so the session commits before keymap dispatches.
mouseup commit is a no-op when no session is open, so attaching it
to document doesn't cost anything for unrelated clicks.
Color session is unchanged (focus/blur boundaries on the color
input still work and don't have this issue).
This commit is contained in:
1 parent
5d3cf8bc4a
commit
e8db3f577a
1 file changed
+34
+34
@@ -172,6 +172,40 @@ export const ControlPanelSceneObject = () => {
|
||||
return () => commitPanelTransform();
|
||||
}, []);
|
||||
|
||||
// Document-level commit triggers for the transform session. These
|
||||
// are the natural "end of edit gesture" signals — without them, a
|
||||
// pending session sits open during same-uuid editing and Ctrl+Z
|
||||
// falls through to a prior entry (often the CreateAction that
|
||||
// added the shape, so the shape disappears on undo).
|
||||
//
|
||||
// - mouseup: end of an InputVector numeric-scrub drag, OR a click
|
||||
// that moves focus away after typing.
|
||||
// - Enter: explicit "I'm done" without losing focus.
|
||||
// - Ctrl+Z / Ctrl+Y / Ctrl+Shift+Z (capture phase): flush before the
|
||||
// engine's keymap handler runs the undo, so the pending entry is
|
||||
// the one being reverted.
|
||||
useEffect(() => {
|
||||
const flush = () => {
|
||||
transformSessionRef.current?.commit();
|
||||
transformSessionRef.current = null;
|
||||
};
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === "Enter") flush();
|
||||
if (
|
||||
(e.ctrlKey || e.metaKey) &&
|
||||
(e.code === "KeyZ" || e.code === "KeyY")
|
||||
) {
|
||||
flush();
|
||||
}
|
||||
};
|
||||
document.addEventListener("mouseup", flush);
|
||||
document.addEventListener("keydown", onKeyDown, true);
|
||||
return () => {
|
||||
document.removeEventListener("mouseup", flush);
|
||||
document.removeEventListener("keydown", onKeyDown, true);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!currentSceneObject) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user