FN-7917: center chat composer attach/model icons with input box

Centers the Chat composer's attach and model/thinking icon buttons with the single-line message input across desktop, tablet, and mobile, while keeping them bottom-aligned when the textarea grows multi-line.

- Size .chat-attach-btn, .chat-thinking-level-root, and .chat-thinking-btn to --chat-input-control-size (matching the send button/textarea min-height) instead of the old calc(var(--space-lg) * 2) / * 2.25) sizing
- Replace the separate mobile touch-target overrides for .chat-attach-btn and .chat-thinking-btn with a shared rule using the same --chat-input-control-size sizing
- Add a regression test asserting the attach/thinking controls use --chat-input-control-size and align-self: flex-end, and no longer use the old calc()-based sizing
- Add a patch changeset for @runfusion/fusion documenting the composer icon centering fix

Files changed:
 .changeset/chat-composer-icon-centering.md         |  7 +++++
 packages/dashboard/app/components/ChatView.css     | 30 ++++++++++++----------
 .../ChatView.chat-input-autosize.test.tsx          | 28 ++++++++++++++++++++
 3 files changed, 52 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-7917
Fusion-Task-Lineage: aba1d5ea-21ee-4b27-90f2-11aca7c4a5fa
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-12 23:02:46 -07:00
parent 87aab438dc
commit 382a4d5d05
3 changed files with 52 additions and 13 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Center the Chat composer attach and model icons with the message input box.
category: fix
dev: ChatView.css sizes .chat-attach-btn and .chat-thinking-level-root to --chat-input-control-size so they center with the single-line input across desktop/tablet/mobile while staying bottom-aligned when multi-line (FN-7917).

View File

@@ -1967,9 +1967,14 @@ CLI-agent sessions, or while streaming) — see StandardChatSurface.tsx `showEdi
transform: scale(0.97);
}
/*
FNXC:Chat-ComposerAlignment 2026-07-12-10:25:
Composer attach + model/thinking icon controls must be vertically centered with the single-line text input box on all surfaces (desktop/tablet/mobile). Match their block-size to --chat-input-control-size (== send button == textarea min-height) so align-self: flex-end yields center alignment when single-line and keeps them at the row bottom when the textarea grows multi-line. (FN-7917)
*/
.chat-attach-btn {
min-width: calc(var(--space-lg) * 2);
min-height: calc(var(--space-lg) * 2);
min-inline-size: var(--chat-input-control-size);
min-block-size: var(--chat-input-control-size);
block-size: var(--chat-input-control-size);
align-self: flex-end;
}
@@ -1985,12 +1990,15 @@ FN-7908 keeps model/agent retargeting inside the same brain popup. The widened p
*/
.chat-thinking-level-root {
position: relative;
min-block-size: var(--chat-input-control-size);
block-size: var(--chat-input-control-size);
align-self: flex-end;
}
.chat-thinking-btn {
min-width: calc(var(--space-lg) * 2);
min-height: calc(var(--space-lg) * 2);
min-inline-size: var(--chat-input-control-size);
min-block-size: var(--chat-input-control-size);
block-size: var(--chat-input-control-size);
}
.chat-thinking-btn--active {
@@ -2520,16 +2528,12 @@ Queued-message banners stack above the composer input with a capped scroll area,
margin-left: auto;
}
/* primary touch targets per AGENTS.md convention */
.chat-attach-btn {
min-width: calc(var(--space-lg) * 2.25);
min-height: calc(var(--space-lg) * 2.25);
}
/* FN-7898: mirror the attach button's mobile touch-target bump. */
/* primary touch targets per AGENTS.md convention; FN-7917 keeps the icon controls in parity with the send/input control size on mobile too. */
.chat-attach-btn,
.chat-thinking-btn {
min-width: calc(var(--space-lg) * 2.25);
min-height: calc(var(--space-lg) * 2.25);
min-inline-size: var(--chat-input-control-size);
min-block-size: var(--chat-input-control-size);
block-size: var(--chat-input-control-size);
}
/*

View File

@@ -33,6 +33,34 @@ describe("ChatView chat input autosize", () => {
expect(stopRule?.[0]).toContain("min-height: var(--chat-input-control-size)");
});
it("centers attach and thinking controls with the single-line input while preserving bottom row alignment", () => {
const attachRule = chatViewCss.match(/\.chat-attach-btn\s*\{[^}]*\}/);
const thinkingRootRule = chatViewCss.match(/\.chat-thinking-level-root\s*\{[^}]*\}/);
const thinkingButtonRule = chatViewCss.match(/\.chat-thinking-btn\s*\{[^}]*\}/);
const mobileRule = chatViewCss.match(
/\/\* primary touch targets[\s\S]*?\.chat-attach-btn,\s*\.chat-thinking-btn\s*\{[^}]*\}/,
);
expect(attachRule).not.toBeNull();
expect(thinkingRootRule).not.toBeNull();
expect(thinkingButtonRule).not.toBeNull();
expect(mobileRule).not.toBeNull();
expect(attachRule?.[0]).toContain("min-block-size: var(--chat-input-control-size)");
expect(attachRule?.[0]).toContain("block-size: var(--chat-input-control-size)");
expect(attachRule?.[0]).toContain("align-self: flex-end");
expect(thinkingRootRule?.[0]).toContain("min-block-size: var(--chat-input-control-size)");
expect(thinkingRootRule?.[0]).toContain("block-size: var(--chat-input-control-size)");
expect(thinkingRootRule?.[0]).toContain("align-self: flex-end");
expect(thinkingButtonRule?.[0]).toContain("min-block-size: var(--chat-input-control-size)");
expect(thinkingButtonRule?.[0]).toContain("block-size: var(--chat-input-control-size)");
expect(mobileRule?.[0]).toContain("min-block-size: var(--chat-input-control-size)");
expect(mobileRule?.[0]).toContain("block-size: var(--chat-input-control-size)");
expect(attachRule?.[0]).not.toContain("min-height: calc(var(--space-lg) * 2)");
expect(thinkingButtonRule?.[0]).not.toContain("min-height: calc(var(--space-lg) * 2)");
expect(mobileRule?.[0]).not.toContain("calc(var(--space-lg) * 2.25)");
});
it("caps textarea max-height at 200px on tablet viewports", () => {
const tabletRule = chatViewCss.match(
/@media \(min-width: 769px\) and \(max-width: 1024px\)\s*\{\s*\.chat-input-textarea\s*\{[^}]*\}\s*\}/,