Skip to content

feat(ui): add tabbed navigation to AskUserQuestion for multi-question flows#125

Open
Miista wants to merge 4 commits intohappier-dev:devfrom
Miista:dev
Open

feat(ui): add tabbed navigation to AskUserQuestion for multi-question flows#125
Miista wants to merge 4 commits intohappier-dev:devfrom
Miista:dev

Conversation

@Miista
Copy link

@Miista Miista commented Mar 10, 2026

When multiple questions are present, renders a tab bar with checkmark indicators instead of stacking all questions vertically.

Summary

Adds tabbed navigation to the AskUserQuestionView component when multiple questions are present, replacing the previous vertical stacking layout.

Why

When an AskUserQuestion tool call contains multiple questions, stacking them all vertically makes the UI long and hard to navigate. Tabs provide a cleaner, more focused experience; users see one question at a time with clear progress indicators (checkmark icons) showing which questions they've already answered.

How to test

  1. Trigger an AskUserQuestion tool call with a single question — verify it renders as before (no tab bar, just the question inline).
  2. Trigger an AskUserQuestion with multiple questions — verify a tab bar appears with each question's header as the tab label.
  3. Answer a question (select an option or type freeform text), then switch tabs — confirm a checkmark icon appears on the answered tab and your selection persists when you switch back.

Screenshots / recording (UI changes)

Question 1:
Skærmbillede 2026-03-10 kl  20 26 40

Question 2:
Skærmbillede 2026-03-10 kl  20 26 47

Question 3 answered:
Skærmbillede 2026-03-10 kl  20 27 10

All questions answered and response sent:
Skærmbillede 2026-03-10 kl  20 27 37

Notes (optional)

  • Implemented by Claude Code.
  • Verified by me via yarn web

Checklist

  • PR targets dev (not main)
  • I linked an issue/discussion (recommended for non-trivial changes)
  • I added/updated tests where feasible (or explained why not)
  • I updated docs if behavior changed
  • If AI-assisted, I disclosed it and listed what I personally verified

Summary by CodeRabbit

  • New Features
    • Introduced tabbed navigation for multi-question forms with visual tabs and answered-state indicators; preserves single-question view when applicable and supports all question types and submission behavior.
  • Bug Fixes
    • Prevents rendering on empty question sets and ensures the active tab stays valid when question count changes.

… flows

When multiple questions are present, renders a tab bar with checkmark
indicators instead of stacking all questions vertically.
@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

Walkthrough

Refactors AskUserQuestionView to support multiple questions via a tabbed UI, adds activeTab state with clamped synchronization, introduces renderQuestionContent and isQuestionAnswered helpers, adds early-return for empty questions, and updates UI imports/styles for tab rendering.

Changes

Cohort / File(s) Summary
Tabbed Multi-Question Interface
apps/ui/sources/components/tools/renderers/workflow/AskUserQuestionView.tsx
Adds tabbed navigation (activeTab, tabBar, tab/tabActive styles, ScrollView), renderQuestionContent(question, qIndex) extractor, isQuestionAnswered(qIndex) helper, clampedActiveTab sync effect, early return when questions.length === 0, and refactors rendering to choose between tabbed or single-question view while preserving existing answer/submit logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main feature added: tabbed navigation for multi-question flows in the AskUserQuestion component.
Description check ✅ Passed The description covers all required template sections: summary, why, how to test with clear steps, screenshots showing the feature, and a filled-out checklist with AI-assisted disclosure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Miista Miista marked this pull request as ready for review March 10, 2026 20:09
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 10, 2026

Greptile Summary

This PR replaces the vertical-stack layout in AskUserQuestionView with a tab-bar navigation pattern when more than one question is present. The visual result is clean and the per-question answered-state (checkmark icon on the tab) works correctly. However, there are a few issues worth addressing before merging:

  • React Rules of Hooks violation: The newly added isQuestionAnswered useCallback (and the pre-existing handleOptionToggle/handleSubmit callbacks) are all defined after a conditional early return on line 246. If the component ever renders with questions empty and then re-renders with questions present, React will detect a hook count mismatch and throw. This PR makes the problem one hook deeper.
  • activeTab out-of-bounds risk: questions[activeTab]! is accessed without a bounds check. While tool inputs are generally static, the non-null assertion silences TypeScript's safety net; a defensive clamp or a useEffect reset would prevent a hard crash.
  • Non-scrollable tab bar: With more than ~4 questions, tabs will overflow or be compressed to unusable widths on mobile viewports, since the tab bar is a plain non-scrolling flexDirection: 'row'.

Confidence Score: 3/5

  • Safe to merge for typical 2-3 question scenarios, but carries a latent Rules of Hooks violation and an unguarded array access that should be fixed before the component is stressed with edge-case inputs.
  • The core tab-switching feature works correctly for the documented happy paths. The two logic issues (hooks-after-return and activeTab out-of-bounds) are unlikely to trigger in current usage given static tool inputs, but they represent real defects that can cause hard runtime errors under slightly different conditions. The non-scrolling tab bar is a usability gap for larger question sets.
  • apps/ui/sources/components/tools/renderers/workflow/AskUserQuestionView.tsx — hooks ordering, activeTab bounds, and tab bar overflow all need attention.

Important Files Changed

Filename Overview
apps/ui/sources/components/tools/renderers/workflow/AskUserQuestionView.tsx Adds tabbed navigation for multi-question flows; introduces a Rules-of-Hooks violation (new isQuestionAnswered useCallback placed after a conditional early return), a potential activeTab out-of-bounds crash when questions shrinks between renders, and a non-scrolling tab bar that will overflow with many questions.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[AskUserQuestionView renders] --> B{questions\nempty/missing?}
    B -- yes --> C[return null]
    B -- no --> D{tool.state === completed\nor isSubmitted?}
    D -- yes --> E[Render submitted summary\nfor all questions]
    D -- no --> F{showTabs?\nquestions.length > 1}
    F -- no single question --> G[renderQuestionContent\nquestions 0 , index 0]
    F -- yes multiple questions --> H[Render tab bar\none tab per question\nwith checkmark if answered]
    H --> I[renderQuestionContent\nquestions activeTab , activeTab]
    G --> J[Render submit button\nif canInteract]
    I --> J
    J --> K{allQuestionsAnswered?}
    K -- yes --> L[Submit button enabled]
    K -- no --> M[Submit button disabled]
    L --> N[handleSubmit\ncaptures selections + freeform\ncalls sessionAllowWithAnswers\nor sessionDeny + sendMessage]
Loading

Last reviewed commit: 5c4b745

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ui/sources/components/tools/renderers/workflow/AskUserQuestionView.tsx`:
- Around line 507-533: The tab row currently rendered when showTabs is true (the
View with style styles.tabBar containing questions.map and TouchableOpacity
tabs) can overflow; wrap that list in a horizontal ScrollView
(horizontal={true}, optionally showsHorizontalScrollIndicator={false}) so tabs
become scrollable on small viewports, ensuring the children (the mapped
TouchableOpacity elements and Ionicons) remain unchanged; keep styles.tabBar as
a row container or adjust to allow horizontal scrolling as needed.
- Around line 275-284: Normalize the questions variable before any hooks and
move the early return until after all hooks: replace direct use of
input?.questions with a local normalized const questions = input?.questions ??
[]; ensure useUnistyles() and all useState/useEffect hooks (and the useCallback
isQuestionAnswered which references selections and freeformAnswers) are declared
unconditionally, then perform the early return that returns null if the original
input/questions are absent; this preserves hook call order and keeps
isQuestionAnswered, selections, and freeformAnswers intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 19d92a63-bfaa-4462-ad72-13b055886099

📥 Commits

Reviewing files that changed from the base of the PR and between cd992ae and 5c4b745.

📒 Files selected for processing (1)
  • apps/ui/sources/components/tools/renderers/workflow/AskUserQuestionView.tsx

Miista added 3 commits March 10, 2026 22:18
Normalize questions array before hooks to prevent Rules of Hooks
violation when the component re-renders with different question counts.
If the questions array shrinks while activeTab points beyond its length,
the component would crash. Clamp to valid range and sync state via effect.
With 5+ questions on smaller screens, tabs would compress or overflow.
Wrapping in a horizontal ScrollView keeps all tabs accessible.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ui/sources/components/tools/renderers/workflow/AskUserQuestionView.tsx`:
- Around line 439-455: Replace the direct react-native TextInput with the app's
shared TextInput component to ensure proper font scaling: in
AskUserQuestionView.tsx swap the JSX element currently using TextInput (the
freeform input bound to freeformAnswers and qIndex) to use the imported
component from "@/components/ui/text/TextInput" and keep all existing props
(style, value, onChangeText, placeholder, placeholderTextColor, editable,
autoCapitalize, autoCorrect) and behavior (checking canInteract and
setFreeformAnswers) intact; also add or update the import for TextInput from
"@/components/ui/text/TextInput" and remove any unused react-native TextInput
import.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: faf66172-f0a3-4d39-a5d5-04b632dfd396

📥 Commits

Reviewing files that changed from the base of the PR and between 5c4b745 and 5c1c340.

📒 Files selected for processing (1)
  • apps/ui/sources/components/tools/renderers/workflow/AskUserQuestionView.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant