diff --git a/src/renderer/src/components/native-chat/NativeChatQuestionCard.test.tsx b/src/renderer/src/components/native-chat/NativeChatQuestionCard.test.tsx index 6cd7ace1591..563cb7b9ba8 100644 --- a/src/renderer/src/components/native-chat/NativeChatQuestionCard.test.tsx +++ b/src/renderer/src/components/native-chat/NativeChatQuestionCard.test.tsx @@ -304,6 +304,34 @@ describe('NativeChatQuestionCard', () => { ]) }) + it('moves between questions with Left and Right from an option or step tab, stopping at the ends', () => { + vi.useFakeTimers() + container.setAttribute('data-native-chat-root', 'true') + render(indentThenFruits, vi.fn(), true, true) + clickOption('Spaces') + + expect(pressKey({ key: 'ArrowLeft' }, document.activeElement!).defaultPrevented).toBe(false) + expect(cardTitle()).toBe('Do you prefer tabs or spaces?') + expect(pressKey({ key: 'ArrowRight' }, document.activeElement!).defaultPrevented).toBe(true) + expect(cardTitle()).toBe('Which fruit?') + expect(document.activeElement?.textContent).toContain('Apple') + expect(pressKey({ key: 'ArrowRight' }, document.activeElement!).defaultPrevented).toBe(false) + expect(cardTitle()).toBe('Which fruit?') + + const cancel = container.querySelector('button[aria-label="Cancel"]')! + act(() => cancel.focus()) + expect(pressKey({ key: 'ArrowLeft' }, cancel).defaultPrevented).toBe(false) + expect(cardTitle()).toBe('Which fruit?') + + const stepTab = [...container.querySelectorAll('button')].find((b) => + b.textContent?.includes('Step 1') + )! + act(() => stepTab.focus()) + expect(pressKey({ key: 'ArrowLeft' }, stepTab).defaultPrevented).toBe(true) + expect(cardTitle()).toBe('Do you prefer tabs or spaces?') + expect(optionPressed('Spaces')).toBe('true') + }) + it('sends nothing when the question is cancelled before the pick moves on', () => { vi.useFakeTimers() const onAnswer = vi.fn() diff --git a/src/renderer/src/components/native-chat/NativeChatQuestionCard.tsx b/src/renderer/src/components/native-chat/NativeChatQuestionCard.tsx index 5e1c635fb1b..fbfd5651bc6 100644 --- a/src/renderer/src/components/native-chat/NativeChatQuestionCard.tsx +++ b/src/renderer/src/components/native-chat/NativeChatQuestionCard.tsx @@ -166,7 +166,6 @@ export function NativeChatQuestionCard({ autoAdvance.schedule(() => advanceOrSubmit(next, otherText)) } } - useNativeChatQuestionKeys(cardRef, shouldFocus && !isSubmitting, q.options.length, pickOption) const confirm = (fromKeyboard = false): void => { autoAdvance.cancel() @@ -184,6 +183,20 @@ export function NativeChatQuestionCard({ autoAdvance.cancel() setIndex(questionIndex) } + useNativeChatQuestionKeys( + cardRef, + shouldFocus && !isSubmitting, + q.options.length, + pickOption, + (delta) => { + const next = index + delta + if (next < 0 || next >= total) { + return false + } + goTo(next) + return true + } + ) const cancel = (): void => { autoAdvance.cancel() onCancel() @@ -226,6 +239,7 @@ export function NativeChatQuestionCard({