fix(editor): unstick empty-click deselect after click-to-move

Validated live by Wassim. The click-to-move branch set `clickHandledRef = true`
then returned early, skipping the 50ms reset the normal select path runs at the
end. The flag stayed true, so `onGridClick`'s guard silently blocked every
empty-click deselect until the next normal select cleared it. Schedule the reset
right after the flag is set so EVERY branch (incl. the early return) clears it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-06-27 16:09:11 -04:00
co-authored by Claude Opus 4.8
parent 5933a00247
commit 8cc6c41b51
@@ -1460,6 +1460,15 @@ export const SelectionManager = () => {
if (activeStrategy?.isValid(node)) { if (activeStrategy?.isValid(node)) {
event.stopPropagation() event.stopPropagation()
clickHandledRef.current = true clickHandledRef.current = true
// Reset the handled flag after a short delay so the grid:click that the
// SAME DOM click also raycasts is ignored (it fires synchronously, before
// this 50ms macrotask). Scheduled here — right after the flag is set — so
// EVERY branch below clears it, including the click-to-move early return
// (which previously skipped the reset and left empty-click deselect stuck
// until the next normal select).
setTimeout(() => {
clickHandledRef.current = false
}, 50)
let nodeToSelect = node let nodeToSelect = node
if (node.type === 'roof-segment' && node.parentId) { if (node.type === 'roof-segment' && node.parentId) {
@@ -1582,11 +1591,6 @@ export const SelectionManager = () => {
if (!nextMaterialTargetHandled && useEditor.getState().selectedMaterialTarget) { if (!nextMaterialTargetHandled && useEditor.getState().selectedMaterialTarget) {
useEditor.getState().setSelectedMaterialTarget(null) useEditor.getState().setSelectedMaterialTarget(null)
} }
// Reset the handled flag after a short delay to allow grid:click to be ignored
setTimeout(() => {
clickHandledRef.current = false
}, 50)
} }
} }