Repository navigation
Stop camera keys from moving the view while typing in a field - #1110
Devin T. Currie (DTCurrie) wants to merge 2 commits into
Conversation
🦋 Changeset detectedLatest commit: de85a83 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
|
Claude (@claude) review |
|
Claude finished Devin T. Currie (@DTCurrie)'s task in 2m 7s —— View job Review
The fix is correct. Nit — doc comment overstates the contract (inline on Missing test: child of a contenteditable container (inline on Observation (not a bug): task still runs while typing |
| editor.contentEditable = 'true' | ||
| document.body.append(editor) | ||
|
|
||
| expect(isEditableTarget(editor)).toBe(true) |
There was a problem hiding this comment.
Missing case: a child of a contenteditable container. HTMLElement.isContentEditable returns true for descendants that inherit editability from a parent, not just elements that carry the attribute themselves. A focused <span> inside a rich-text editor would satisfy isContentEditable and should block the camera — but there's no test for that shape.
| expect(isEditableTarget(editor)).toBe(true) | |
| expect(isEditableTarget(editor)).toBe(true) | |
| const child = document.createElement('span') | |
| editor.append(child) | |
| expect(isEditableTarget(child)).toBe(true) |
| @@ -0,0 +1,4 @@ | |||
| /** Whether keys pressed with `target` focused are typing into a field, which no shortcut should take. */ | |||
There was a problem hiding this comment.
The second clause of the doc comment — "which no shortcut should take" — slightly overstates the contract. KeyboardBindings still fires modified shortcuts (⌘S, etc.) even when this returns true; the caller adds the !mod guard. The function itself is correct; the doc just describes the camera loop's stricter policy rather than what this predicate means on its own.
| /** Whether keys pressed with `target` focused are typing into a field, which no shortcut should take. */ | |
| /** Whether `target` is an element that accepts typed text. */ |
Claude (@claude) resolve these |
|
Claude finished Devin T. Currie (@DTCurrie)'s task in 2m 44s —— View job Resolved
Note: |
Co-authored-by: Devin T. Currie <DTCurrie@users.noreply.github.com>
Stops the camera's WASD and arrow keys from moving the view while a text field has focus. Before this, typing
wasdinto any input flew the camera, because the camera loop reads held keys offwindowwith no field check.Keybindings
isEditableTarget(target)is new. It reports whether a focused element takes typed text: aninput,textareaorselect, anything inside one, or acontenteditableelement.Components
InputBindingsskips its per-frame camera movement whiledocument.activeElementis editable.KeyboardBindingsreplaces its privateisEditablewithisEditableTarget, so the shortcut dispatcher and the camera agree on what counts as typing.Why?
Why check
document.activeElementand not the key event's target?The camera moves in a
useTaskloop that polls which keys are held. No key event reaches it, so the focused element is the only signal it has.Testing
Added
isEditableTarget.spec.ts, covering inputs, textareas, selects,contenteditableelements, buttons, the body andnull. Changing the check's||to&&fails cases in that spec and in the existingKeyboardBindings.svelte.spec.ts. The camera loop has no spec, becauseuseTaskneeds a live canvas.Ran the binaries behind
pnpm checkandpnpm testdirectly, since this was a worktree:svelte-check(0 errors) and the fullvitest --run(134 files, 1975 tests). Raneslintandprettier --checkon the changed files. No Go changed, sogo vetandgolangci-lintdid not run.