feat: keyboard waves A/B — global shortcut registry, question row machine, Esc-cancel dictation
Wave A (owner key map): registry in src/core/keyboard.ts + KeyboardShortcuts
provider; Cmd+D dictation, Cmd+K model picker, Shift+Tab thinking cycle,
Cmd+B sidebar, Cmd+Shift+F sessions search, Alt+arrows session cycle,
Alt+Enter open, Cmd+G graph, Cmd+N new, F2 rename, ? cheat sheet. Tab
fully suppressed; Esc chain popover > dictation > abort (local stream).
Esc now CANCELS dictation (discard) — flush stays on Cmd+D/Stop. Owner
bug reports fixed: focus outline removed, Alt+Enter setState-in-render,
Cmd+F graph node search (surface-scoped lh:kbd-find).
Wave B: question dock row machine — arrows walk options + dont-know/Other
with wrap + ring highlight, Space picks (mirrors click semantics), Enter
submits when canSubmit; typing surfaces and in-dock keys keep native
behavior. aria-checked={isSel} restored on option buttons.
docs/keyboard.md records the full map.
This commit is contained in:
+5
-5
@@ -899,7 +899,7 @@ export function Chat({
|
||||
turns={turns}
|
||||
onReserve={setDockReserve}
|
||||
dictationSlot={<DictationBar dictation={dictation} />}
|
||||
dictationStop={dictation.stop}
|
||||
dictationCancel={dictation.cancel}
|
||||
composer={
|
||||
<Composer
|
||||
// Stop applies only to a LOCAL stream: a server-side turn has no
|
||||
@@ -910,7 +910,7 @@ export function Chat({
|
||||
onSend={onSend}
|
||||
onStop={() => stop()}
|
||||
canSend={canSend}
|
||||
onEscape={dictation.active ? dictation.stop : undefined}
|
||||
onEscape={dictation.active ? dictation.cancel : undefined}
|
||||
verdict={
|
||||
planVerdict
|
||||
? {
|
||||
@@ -978,7 +978,7 @@ function DockOverlay({
|
||||
plan,
|
||||
onOpenPlan,
|
||||
dictationSlot,
|
||||
dictationStop,
|
||||
dictationCancel,
|
||||
}: {
|
||||
pending: ReturnType<typeof findPendingToolCall>;
|
||||
/** Teach-phase pending question: arrives collapsed behind the reveal button (W5). */
|
||||
@@ -1006,7 +1006,7 @@ function DockOverlay({
|
||||
dictationSlot?: React.ReactNode;
|
||||
/** Esc in a pending question's field stops dictation (the strip is the
|
||||
* stats bar's; the stop belongs to the page-owned hook, threaded down). */
|
||||
dictationStop?: () => void;
|
||||
dictationCancel?: () => void;
|
||||
}) {
|
||||
const { isAtBottom, scrollToBottom, scrollRef } = useStickToBottomContext();
|
||||
// Teach-phase mount (session reload with a pending check): the dock starts
|
||||
@@ -1257,7 +1257,7 @@ function DockOverlay({
|
||||
phase={phase}
|
||||
onExpand={expandAndReveal}
|
||||
onSubmit={onSubmitAnswer}
|
||||
onEscape={dictationStop}
|
||||
onEscape={dictationCancel}
|
||||
/>
|
||||
) : (
|
||||
composer
|
||||
|
||||
Reference in New Issue
Block a user