diff --git a/mobile/src/session/MobileNativeChatMessage.test.ts b/mobile/src/session/MobileNativeChatMessage.test.ts index 8736db51327..1b9a8c2e138 100644 --- a/mobile/src/session/MobileNativeChatMessage.test.ts +++ b/mobile/src/session/MobileNativeChatMessage.test.ts @@ -307,6 +307,9 @@ describe('MobileNativeChatMessage', () => { const tree = render(reasoning()) expect(textIn(tree.root)).toContain('Thought for 3s') expect(toggleOf(tree).props.accessibilityState).toEqual({ expanded: false }) + // Said with what it is, as desktop's screen-reader prefix does, on a 32 + 2 × 6 pt target. + expect(toggleOf(tree).props.accessibilityLabel).toBe('Reasoning: Thought for 3s') + expect(toggleOf(tree).props.hitSlop).toBe(6) expect(markdownIn(tree)).toHaveLength(0) }) @@ -328,9 +331,10 @@ describe('MobileNativeChatMessage', () => { it('says only what the host saw', () => { expect(textIn(render(reasoning({ state: 'running' })).root)).toContain('Thought') - expect( - textIn(render(reasoning({ state: undefined, completedAt: undefined })).root) - ).toContain('Reasoning') + const unknown = render(reasoning({ state: undefined, completedAt: undefined })) + expect(textIn(unknown.root)).toContain('Reasoning') + // No "Reasoning: Reasoning". + expect(toggleOf(unknown).props.accessibilityLabel).toBe('Reasoning') expect(textIn(render(reasoning({ completedAt: 1_300 })).root)).toContain('Thought for 1s') }) }) diff --git a/mobile/src/session/MobileNativeChatReasoningRow.tsx b/mobile/src/session/MobileNativeChatReasoningRow.tsx index f8d91d3dd67..cc28a6497e9 100644 --- a/mobile/src/session/MobileNativeChatReasoningRow.tsx +++ b/mobile/src/session/MobileNativeChatReasoningRow.tsx @@ -24,6 +24,8 @@ export function MobileNativeChatReasoningRow({ onOpenFile?: (relativePath: string) => void }): React.JSX.Element { const [expanded, setExpanded] = useState(false) + const headline = nativeChatReasoningHeadlineText(nativeChatReasoningHeadline(message)) + const label = nativeChatReasoningHeadlineText({ kind: 'reasoning' }) return ( - {nativeChatReasoningHeadlineText(nativeChatReasoningHeadline(message))} + {headline} diff --git a/mobile/src/session/mobile-native-chat-message-styles.ts b/mobile/src/session/mobile-native-chat-message-styles.ts index 7070ff765c4..d27e2a8042d 100644 --- a/mobile/src/session/mobile-native-chat-message-styles.ts +++ b/mobile/src/session/mobile-native-chat-message-styles.ts @@ -36,7 +36,8 @@ export const styles = StyleSheet.create({ flexDirection: 'row', alignItems: 'center', gap: spacing.xs, - paddingVertical: 3 + // With the toggle's 6 pt hitSlop above and below, a 44 pt touch target. + minHeight: 32 }, reasoningPressed: { opacity: 0.6 diff --git a/src/shared/native-chat-reasoning-row.ts b/src/shared/native-chat-reasoning-row.ts index b784dd70a08..e3939417965 100644 --- a/src/shared/native-chat-reasoning-row.ts +++ b/src/shared/native-chat-reasoning-row.ts @@ -44,7 +44,7 @@ export function nativeChatReasoningHeadline( } /** English copy for clients without a translation catalog; desktop translates the same three. */ -export const NATIVE_CHAT_REASONING_COPY = { +const NATIVE_CHAT_REASONING_COPY = { reasoning: 'Reasoning', thought: 'Thought', thoughtFor: (duration: string) => `Thought for ${duration}`