From 29530b5fdb37e5abfe5a8078e1759e64a275660f Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 24 Jun 2026 22:24:04 -0700 Subject: [PATCH] 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 --- .../fn-6967-tablet-chat-bubble-width.md | 7 +++ docs/dashboard-guide.md | 3 +- .../dashboard/app/components/ChatView.css | 12 ++++ .../components/__tests__/ChatView.test.tsx | 56 +++++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 .changeset/fn-6967-tablet-chat-bubble-width.md diff --git a/.changeset/fn-6967-tablet-chat-bubble-width.md b/.changeset/fn-6967-tablet-chat-bubble-width.md new file mode 100644 index 0000000000..d512d5220a --- /dev/null +++ b/.changeset/fn-6967-tablet-chat-bubble-width.md @@ -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. diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index cf966f68fe..bc55e46222 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -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. + +- 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. - 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. diff --git a/packages/dashboard/app/components/ChatView.css b/packages/dashboard/app/components/ChatView.css index 3b1c2f5ed7..68c0eb9715 100644 --- a/packages/dashboard/app/components/ChatView.css +++ b/packages/dashboard/app/components/ChatView.css @@ -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; diff --git a/packages/dashboard/app/components/__tests__/ChatView.test.tsx b/packages/dashboard/app/components/__tests__/ChatView.test.tsx index 85f40464a8..cd57de4880 100644 --- a/packages/dashboard/app/components/__tests__/ChatView.test.tsx +++ b/packages/dashboard/app/components/__tests__/ChatView.test.tsx @@ -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(); + + 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();