fix(PromptInput): place caret at end on initial focus - #237
Conversation
|
🚀 Prerelease version published! Install this PR version: npm i --save-dev @gravity-ui/aikit@2.20.2-beta.14c80e411a3ea24056ed623e72808a95f1c2349d.0 |
|
Preview is ready. |
|
🎭 Component Tests Report is ready. |
There was a problem hiding this comment.
Pull request overview
Fixes PromptInput’s initial caret placement so that when the textarea mounts with a non-empty value, the first focus moves the caret to the end (including pointer focus and autofocus), while subsequent focuses/clicks keep the browser’s native caret behavior. This aligns PromptInput UX with typical “resume typing at end” expectations and addresses #152.
Changes:
- Add a one-time
onFocushandler inPromptInputBodythat moves the caret to the end on the first focus after mount (usingrequestAnimationFrameto avoid fighting pointer-based placement timing). - Add Playwright component regression tests covering first-focus behavior, refocus behavior, and autofocus behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/components/organisms/PromptInput/tests/PromptInput.visual.spec.tsx | Adds regression interaction tests for caret placement on first focus, refocus, and autofocus. |
| src/components/molecules/PromptInputBody/PromptInputBody.tsx | Implements one-time initial-focus caret-to-end behavior via an onFocus handler. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Could we defer pointer-originated initial focus handling until pointerup? During a slow drag, the first requestAnimationFrame can run while the selection is still collapsed and move the caret to the end before the drag creates a range, so an explicit selection may be lost. I suggest preserving non-collapsed drag selections and moving only a collapsed click to the end, while keeping the keyboard/programmatic autofocus path.
Suggestion: please add a slow mouse down/drag/up regression test; the current selectText() test establishes the range before the RAF runs.
There was a problem hiding this comment.
Fixed in 9083eda.
On the first pointer focus, we now wait for pointerup before changing the caret. A regular click still puts a collapsed caret at the end. If the user drags to select text, we leave the selection created by the browser intact.
I added a regression test that holds the mouse button down through two animation frames, then drags across some and releases it. On the previous commit, the selection collapsed at the end (4..4). With this fix, the whole value stays selected (0..4).
Verification passed: 42 @PromptInput tests, 420 component tests, and all CI checks on 9083eda. I also checked the refreshed preview: a regular click and autofocus end at 4..4, while an empty value stays at 0..0.
There was a problem hiding this comment.
Recorded the same first-focus drag in Chromium, Firefox and WebKit (Playwright 1.56.1, Linux Docker). The old version loses the selection in Chromium and Firefox; WebKit already preserves it. With 9083eda, all three preserve the selection.
These are the bundled browser versions shown in the recording. Manual checks in Chrome 152 on macOS did not reproduce the loss.
9083eda to
14c80e4
Compare
What changed
pointerup, after the browser has completed a click or drag selection.Verification
npm run playwright:docker -- --grep "@PromptInput"— 42 passednpm run playwright:docker— 420 passednpm run playwright:docker -- --grep "caret|autofocus|selection" --repeat-each=20— 100 passednpm test— 281 client and 19 server tests passednpm run lintnpm run buildgit diff --checkgit merge-tree --write-tree origin/main HEADCloses #152