Repository navigation
Commit f51ea67
⌨️ feat: Keyboard Submit, Focus and Escape for Ask User Cards (#17231)
* ⌨️ feat: Keyboard submit for ask_user_question answer box
The interactive ask_user_question card's answer textarea had no key
handling, so the answer could only be submitted by clicking. Route its
keydown through resolveComposerKeyDown so it follows the composer's
Enter-to-send preference, a rebound submit chord, and IME composition.
The run is paused rather than generating, so it resolves as idle and
Ctrl/Cmd+Enter submits instead of reaching the during-run actions.
* ⌨️ feat: Keyboard focus and confirm for batched ask_user_question
- Focus the first question's controls when a batch arrives, only when
focus is idle (body, or the empty composer that sent the turn), and
focus into the next step on advance instead of the fieldset: the picked
or first option, else the answer field.
- Enter on the already-picked single-select option confirms the step;
Enter on an unpicked option stays its click, so a pick never submits
by itself (WCAG 3.2.2). Multi-select rows only toggle.
- Ctrl/Cmd+Enter confirm from the answer field like Enter; Shift+Enter
never does.
* 🐛 fix: Keep Held Enter and Remounts From Picking Batched Answers
Review findings on the batched ask_user_question card, and what this
commit does about each.
1. Held or double-tapped Enter could pick answers and submit the batch.
After Enter confirmed a step, focus moved to the next step's first
option. A keyboard Enter on a focused button is its click, so the
key repeat of a held Enter (or a quick double-tap) picked that option
and advanced again. On the last step the next repeat landed on the
now-pressed option, confirmed it, and submitted the whole batch with
answers the user never chose.
Fix: after a step change, focus goes to the step's picked option,
else its answer field. An unpicked option is only a focus target when
a batch first arrives. Repeats now reach a text field, which can page
on but never picks an option or submits on the user's behalf.
2. Focus-on-arrival ran on every mount, not only on arrival. Its effect
has empty deps, so moving the batch between the composer popover and
the chat card, or remounting a message that still holds an
unanswered batch (reopening a conversation, a Share view), pulled
focus onto an option of that batch. The next Enter or Space would
then answer it.
Fix: `AskUserQuestions` takes a `focusOnArrival` prop, set only by
the surface showing the live pause (the popover, or the chat card
while it is live and visible), so other mounts never take focus.
Focus is placed at most once per batch, tracked by action id, so a
move between surfaces is not treated as a new arrival.
Tests: a held Enter from an answer field picks nothing and never
submits; a surface that isn't the live pause leaves focus alone; a
remount of the same batch doesn't take focus again. All three fail
without this change. The Chat/Messages/Content, Chat/Input, Chat/ask
and hooks/Input suites pass, apart from TokenUsage/index.spec.tsx,
which fails the same way without this change. tsc, ESLint and Prettier
are clean on the changed files.
* feat: Escape to Skip Ask Cards and Move the Popover to Chat
Escape in the chat card skips the question or batch, but only before
anything is entered, so a stray Escape cannot discard an answer and
resume the run. Escape with focus inside the composer popover moves the
question to the chat, as it already did from the composer, and returns
focus to the composer once the popover closes. Also drops the em dashes
from the batched card's comments.
* fix: Read Enter-to-Send From the Chat Surface Host in the Ask Card
* test: Cover Ask Batch Keyboard Control in E2E Scenarios
* fix: Keep Held and Modified Enter From Submitting Ask Answers
Ignore auto-repeated Enter before confirming a picked option, so a held
Enter cannot both pick and submit the last question. In the answer
field, Shift, Alt and repeated Enter now prevent the enclosing chat
form's implicit submit instead of returning early. Escape that cancels
an IME composition no longer moves the popover to the chat, and the
arrival-focus flag lives in the batch's Jotai form state.
* fix: Honor a Submit Shortcut Rebound Off Enter in Ask Answer Fields
The window shortcut handler yields submitMessage in every editing field
except the composer, so a chord such as Ctrl+J did nothing in the ask
answer fields. Both the single-question answer box and the batched
answer field now act on it, through a shared isReboundSubmitChord.
---------
Co-authored-by: elie605 <ebtien@gmail.com>1 parent ce9a9d8 commit f51ea67
10 files changed
Lines changed: 1140 additions & 34 deletions
File tree
- client/src
- components/Chat
- Input
- __tests__
- Messages/Content
- __tests__
- hooks/Input
- utils
- e2e/specs/mock/scenarios
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
35 | | - | |
| 36 | + | |
| 37 | + | |
36 | 38 | | |
37 | | - | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
38 | 58 | | |
39 | 59 | | |
40 | 60 | | |
41 | 61 | | |
42 | | - | |
| 62 | + | |
43 | 63 | | |
44 | 64 | | |
45 | | - | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
46 | 68 | | |
47 | 69 | | |
48 | | - | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
49 | 77 | | |
50 | 78 | | |
51 | 79 | | |
| |||
62 | 90 | | |
63 | 91 | | |
64 | 92 | | |
| 93 | + | |
| 94 | + | |
65 | 95 | | |
66 | 96 | | |
67 | 97 | | |
| |||
101 | 131 | | |
102 | 132 | | |
103 | 133 | | |
| 134 | + | |
104 | 135 | | |
105 | 136 | | |
106 | 137 | | |
| 138 | + | |
107 | 139 | | |
108 | 140 | | |
109 | 141 | | |
| |||
165 | 197 | | |
166 | 198 | | |
167 | 199 | | |
168 | | - | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
169 | 208 | | |
170 | 209 | | |
171 | 210 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
5 | 8 | | |
6 | 9 | | |
| 10 | + | |
| 11 | + | |
7 | 12 | | |
8 | 13 | | |
9 | 14 | | |
10 | 15 | | |
11 | 16 | | |
12 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
13 | 24 | | |
14 | 25 | | |
15 | 26 | | |
| |||
81 | 92 | | |
82 | 93 | | |
83 | 94 | | |
| 95 | + | |
84 | 96 | | |
85 | 97 | | |
86 | 98 | | |
| |||
122 | 134 | | |
123 | 135 | | |
124 | 136 | | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
125 | 141 | | |
126 | 142 | | |
127 | 143 | | |
| |||
216 | 232 | | |
217 | 233 | | |
218 | 234 | | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
219 | 288 | | |
220 | 289 | | |
221 | 290 | | |
| |||
233 | 302 | | |
234 | 303 | | |
235 | 304 | | |
| 305 | + | |
236 | 306 | | |
237 | 307 | | |
238 | 308 | | |
| |||
284 | 354 | | |
285 | 355 | | |
286 | 356 | | |
| 357 | + | |
287 | 358 | | |
288 | 359 | | |
289 | 360 | | |
| |||
0 commit comments