refactor(web): the composer's footer controls render in ComposerControlsBar#23058
The composer body built its footer controls inline: the model picker, the traits picker and traits menu, the mode controls, the resting blocks and the overflow menu. Typing re-rendered the control separators in that block on every keystroke. A 4-keystroke trace on #23049 shows ComposerControlSeparator and its two Separators re-rendering with the same props, 3 renders per keystroke.
ComposerControlsBar is a memoized component that owns all of it, including the traits picker inputs and the resting-block bookkeeping. The composer still measures which blocks fit, through useRestingComposerControlsLayout on the host elements. It passes the hidden and icon-only counts down, and renders the same composerControls element in the resting host, the expanded footer, and the inline resting row. The DOM is unchanged, so the measurement code sees the same nodes.
Renders vs #23049 (Codex model, draft thread, median of 3):
| Interaction | #23049 | this PR |
|---|---|---|
| Type 20 chars (total) | 230 | 165 |
| Type 20 chars with an image attached | 182 | 122 |
| Open the slash menu | 450 | 442 |
| Traits Medium <-> High | 284 | 281 |
TraitsPicker, ComposerAttachButton and ComposerModelPicker stay at 0 renders while typing.
| File | before | after |
|---|---|---|
| ChatComposer.tsx | 4,267 | 4,111 |
| ComposerControlsBar.tsx | 331 |
Tested:
- apps/web typecheck and lint on the touched files.
- React Compiler: 0 bailouts on both files.
- Hands-on in a dev build:
- switching the model from Codex to Claude and back
- flipping traits between Medium and High
- the runtime mode combobox is present
- the slash menu
- typing with an image attached
🤖 Generated with Claude Code
Checks
Added 1 commit
- refactor(web): the composer's footer controls render in ComposerControlsBar959fea3
Approvability
Verdict: Approved at 959fea3
Macroscope's review found this PR approvable — This PR extracts the existing composer footer controls into a memoized component while preserving the same controls, props, callbacks, and layout markers. Its runtime effect is limited to reducing unnecessary rerenders in the composer; it introduces no new user-facing capability or product-default change.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Configuration used: Path: .coderabbit.config.ts
- Review profile: CHILL
- Plan: Team
- Run ID:
d229833b-5de8-4986-a726-2d665139519c
📥 Commits
Reviewing files that changed from the base of the PR and between 13c6e32e1074613f279304cccab27c176e8ec104 and 959fea314650da81769dde58c4b89b77ffeada8f.
📒 Files selected for processing: 2
apps/web/src/components/chat/ChatComposer.tsxapps/web/src/components/chat/ComposerControlsBar.tsx
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.
📝 Walkthrough
ChatComposer now delegates provider, model, runtime-mode, and trait controls to the new ComposerControlsBar component. The component builds route-aware provider controls and renders model selection, provider setup actions, and responsive resting and overflow controls.
Changes: Composer controls
Layer / File(s) Summary Control inputs and provider traits
apps/web/src/components/chat/ComposerControlsBar.tsxComposerControlsBar defines its props and derives route-aware provider trait menus and picker content. Model selection and provider setup
apps/web/src/components/chat/ComposerControlsBar.tsxThe component creates a loading-aware model picker and renders provider setup actions based on provider availability. Responsive rendering and composer integration
apps/web/src/components/chat/ComposerControlsBar.tsx,apps/web/src/components/chat/ChatComposer.tsxThe component renders resting and overflow controls. ChatComposer replaces its inline control tree and related trait inputs with ComposerControlsBar. Priority: ➖ Normal
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Refactor
Suggested reviewers:
t3dotgg
Merge Risk: ⚪ Minimal · up to 959fe
This refactor moves the composer footer controls into a separate component without intended behavior changes. No concrete defects were found in the supplied context, so it looks safe to merge after the usual checks.
Pre-merge checks: Passed 3 · Failed 1
Failed Failed checks: 1 warning
Check name Status Explanation Resolution Description check Warning The description explains the performance problem, implementation, measured results, and validation. It does not provide the required Scope and approval information or the required before/after screens… Add the required Problem, Change, Scope and approval, and Verification headings. Link the triaged issue or maintainer approval, or explain why this focused refactor qualifies for an exemption. Embed clear before/after screenshots and state … Passed Passed checks: 3 passed
Check name Status Explanation Title check Passed The title clearly and concisely describes the main change: moving the composer's footer controls into ComposerControlsBar. Linked Issues check Passed Check skipped because no linked issues were found for this pull request. Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check
Explanation
The description explains the performance problem, implementation, measured results, and validation. It does not provide the required Scope and approval information or the required before/after screenshots for this UI change.
Resolution
Add the required Problem, Change, Scope and approval, and Verification headings. Link the triaged issue or maintainer approval, or explain why this focused refactor qualifies for an exemption. Embed clear before/after screenshots and state any checks that could not be completed.
✨ Finishing Touches
📝 Generate docstrings
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.