FN-6967: widen tablet agent chat bubbles

Improve tablet Chat readability by widening agent-side response bubbles without expanding user or Quick Chat bubbles.

- Add a ChatView container query that widens assistant, streaming, and failure bubbles on tablet-width containers.
- Cover the targeted bubble classes and CSS width contract in ChatView tests.
- Document the tablet behavior and add a structured patch changeset for the published CLI bundle.

Files changed:
 .changeset/fn-6967-tablet-chat-bubble-width.md     |  7 +++
 docs/dashboard-guide.md                            |  3 +-
 packages/dashboard/app/components/ChatView.css     | 12 +++++
 .../app/components/__tests__/ChatView.test.tsx     | 56 ++++++++++++++++++++++
 4 files changed, 77 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6967
Fusion-Task-Lineage: 74195885-4ec0-4fc9-b628-0b0510129026
This commit is contained in:
gsxdsm
2026-06-24 22:24:04 -07:00
parent a554ceb672
commit 29530b5fdb
4 changed files with 77 additions and 1 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Widen tablet Chat View agent response bubbles for easier reading.
category: fix
dev: Uses ChatView container queries to target assistant, streaming, and failure bubbles without widening user or Quick Chat bubbles.

View File

@@ -333,7 +333,8 @@ Chat view provides project-scoped conversations with agents.
- On mobile direct-chat threads, entering a thread and restoring Chat after tab/page visibility returns re-anchors to the newest message (`scrollTop = scrollHeight`) so the view always opens at the live tail.
- On mobile direct-chat threads, tapping the active title/identity in the thread header opens a lightweight conversation dropdown so you can switch to another direct session without backing out to the sidebar list first; long conversation titles now stay readable in the dropdown via wrapped option text and taller touch-friendly rows.
- Direct chat sessions can be renamed from the desktop conversation context menu and from the mobile session switcher; blank rename submissions clear the custom title so the default session label is shown again.
- On mobile (`max-width: 768px`), chat bubbles are slightly wider in full Chat for improved readability while preserving header/composer gutters.
<!-- FNXC:ChatViewDocs 2026-06-23-11:48: Chat responsive docs need to distinguish the mobile all-bubble readability cap from the tablet main Chat assistant-only widening; Quick Chat remains governed by its narrow container so floating desktop hosts do not inherit the tablet measure. -->
- On mobile (`max-width: 768px`), chat bubbles are slightly wider in full Chat for improved readability while preserving header/composer gutters. On tablet-width main Chat containers, assistant/agent, streaming, and failure bubbles use a wider reading measure for long responses while user bubbles and narrow floating Quick Chat hosts stay bounded.
- Full Chat tool-call summaries now use a denser mobile layout: grouped and single-call collapsed rows keep icon + label + status on one line (Quick Chat-style scanability) while expanded details remain unchanged.
<!-- FNXC:ChatAskQuestion 2026-06-17-16:35: Dashboard chat agents have a Fusion-native `fn_ask_question` tool, so the documented question-card behavior must cover both provider-native question tools and Fusion's first-party tool. -->
- Assistant question tool calls now render as a shared in-chat response card instead of a generic tool-call disclosure. The card recognizes provider-native question tools and Fusion's `fn_ask_question`, supports select, multi-select, text, and yes/no prompts, sends the formatted answer back into the same direct or room thread, and renders historical answered questions read-only.

View File

@@ -973,6 +973,18 @@ In the narrow/mobile chat layout there is no room for an expand/maximize afforda
border: var(--btn-border-width) solid var(--status-error-bg-deep);
}
/*
FNXC:ChatView 2026-06-23-11:40:
Tablet Chat View has enough message-pane width for assistant prose, markdown, tool output, failure details, and attachments, so agent-side bubbles need a wider reading measure than the shared desktop/user cap. Use the ChatView container width instead of the viewport so floating Quick Chat and other narrow hosts keep their bounded bubble layout.
*/
@container chat-view (min-width: 48.0625rem) and (max-width: 64rem) {
.chat-message--assistant,
.chat-message--streaming,
.chat-message--failure {
max-width: 88%;
}
}
.chat-message-avatar {
display: flex;
align-items: center;

View File

@@ -1378,6 +1378,41 @@ describe("ChatView", () => {
expect(within(messageBubble).getByText("run-42")).toBeInTheDocument();
});
it("renders assistant, user, streaming, and failure bubbles with the width-targeting classes", async () => {
setupMockChat({
activeSession: activeSessionFixture,
messages: [
{ id: "msg-user", sessionId: "session-001", role: "user", content: "Question", createdAt: "2026-04-08T00:00:00.000Z" },
{ id: "msg-assistant", sessionId: "session-001", role: "assistant", content: "Answer", createdAt: "2026-04-08T00:00:01.000Z" },
{
id: "msg-failure",
sessionId: "session-001",
role: "assistant",
content: "Failed answer",
failureInfo: { summary: "Failed answer", detail: "Provider failed" },
createdAt: "2026-04-08T00:00:02.000Z",
},
],
isStreaming: true,
streamingText: "Live answer",
});
await renderWithAct(<ChatView projectId="proj-123" addToast={vi.fn()} />);
expect(screen.getByTestId("chat-message-msg-user")).toHaveClass("chat-message", "chat-message--user");
expect(screen.getByTestId("chat-message-msg-assistant")).toHaveClass("chat-message", "chat-message--assistant");
expect(screen.getByTestId("chat-message-msg-failure")).toHaveClass(
"chat-message",
"chat-message--assistant",
"chat-message--failure",
);
expect(document.querySelector(".chat-message--streaming")).toHaveClass(
"chat-message",
"chat-message--assistant",
"chat-message--streaming",
);
});
it("shows streaming copy action for provider chats", async () => {
setupMockChat({
activeSession: {
@@ -3194,6 +3229,27 @@ describe("ChatView CSS — failure bubble contracts", () => {
});
});
describe("ChatView CSS — tablet assistant bubble width", () => {
const css = loadAllAppCss();
it("widens assistant, streaming, and failure bubbles on tablet containers while preserving user and mobile caps", async () => {
const baseMessageRule = css.match(/\.chat-message\s*\{([^}]*)\}/);
const userRule = css.match(/\.chat-message--user\s*\{([^}]*)\}/);
const tabletRule = css.match(
/@container\s+chat-view\s+\(min-width:\s*48\.0625rem\)\s+and\s+\(max-width:\s*64rem\)\s*\{([\s\S]*?)\n\}/,
);
expect(baseMessageRule?.[1]).toContain("max-width: 75%");
expect(userRule?.[1]).toContain("align-self: flex-end");
expect(userRule?.[1]).not.toContain("max-width");
expect(tabletRule?.[1]).toMatch(
/\.chat-message--assistant,\s*\.chat-message--streaming,\s*\.chat-message--failure\s*\{[^}]*max-width:\s*88%/,
);
expect(tabletRule?.[1]).not.toMatch(/\.chat-message--user\s*\{[^}]*max-width/);
expect(css).toMatch(/@media\s*\(max-width:\s*768px\)[\s\S]*?\.chat-message\s*\{[^}]*max-width:\s*90%/);
});
});
describe("ChatView CSS — active state edge highlights", () => {
const css = loadAllAppCss();