# refactor\(web\): the composer's layout and provider hooks live in their own files · PR \#23042 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/23042)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: refactor/split2-composer-layout-hooks

Target branch: refactor/split2-composer-traits

Head commit: 1807a1e9c9d9c7e2dd80b05c6c43041dc5172a8e

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/23042)

[Commits](https://git.cafe/pingdotgg/t3code/pull/23042/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/23042/diffs?format=markdown)

## Description

---

ChatComposer.tsx still holds six module-level hooks and components that don't share the composer's state. They sit in front of the composer body and push it more than a thousand lines down the file.

This PR moves them out unchanged:

- `useComposerRestingTransition.ts`: the resting/collapsed height and content animation.
- `ComposerCommandMenuLayer.tsx`: the portal that positions the slash/mention menu.
- `useRestingComposerControlsLayout.ts`: measures which footer blocks fit.
- `useProviderWorkspaceSnapshotRefresh.ts`: rescans provider skills and commands for the cwd.
- `useComposerProviderModel.ts`: resolves the provider instance, model and options.
- `useComposerImageGroups.ts`: separates pending SnapShots from standalone images.

The code is the same apart from the `export` keywords and imports. Each hook is still called once from the composer body, so render boundaries are unchanged. Typing 20 chars still renders ChatComposer 20 times, with 0 TraitsPicker and 0 ComposerAttachButton renders.

| File | before | after |
| --- | --- | --- |
| ChatComposer.tsx | 6,372 | 5,434 |
| useComposerRestingTransition.ts | | 526 |
| ComposerCommandMenuLayer.tsx | | 94 |
| useRestingComposerControlsLayout.ts | | 84 |
| useProviderWorkspaceSnapshotRefresh.ts | | 137 |
| useComposerProviderModel.ts | | 100 |
| useComposerImageGroups.ts | | 40 |

Tested:
- apps/web typecheck and lint on the touched files.
- React Compiler: 0 bailouts on all seven files.
- Hands-on in a dev build: typing, the slash menu position, and the resting composer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

