FN-9199: Replace chat text back marker with arrow icon
Use a consistent icon-and-label back affordance across direct and room chat threads. - Render the lucide ArrowLeft icon with localized Back text and preserved accessible naming. - Cover mobile direct and room thread back buttons with icon, text, and accessibility assertions. - Add a patch changeset for the published Fusion package. Files changed: .changeset/fix-chat-back-arrow.md | 6 ++++++ packages/dashboard/app/components/ChatView.css | 2 +- packages/dashboard/app/components/ChatView.tsx | 14 ++++++++++++-- .../app/components/__tests__/ChatView.mobile.test.tsx | 4 +++- .../app/components/__tests__/ChatView.rooms.test.tsx | 7 ++++++- 5 files changed, 28 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-9199 Fusion-Task-Lineage: aab2a300-cc2a-4768-b60b-81d7477b8fab Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
6
.changeset/fix-chat-back-arrow.md
Normal file
6
.changeset/fix-chat-back-arrow.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@runfusion/fusion": patch
|
||||
---
|
||||
|
||||
summary: Chat's back button now shows a real back arrow icon instead of a text character.
|
||||
category: fix
|
||||
@@ -2181,7 +2181,7 @@ Thinking-section text uses the defined muted text token across all themes. The m
|
||||
visible, the thread is hidden; when the sidebar is hidden (a session is
|
||||
open), the sidebar is collapsed via .chat-sidebar--hidden and the
|
||||
thread takes the full viewport. The thread already renders a back
|
||||
button (ChevronLeft) on mobile to flip back to the session list. */
|
||||
button (ArrowLeft) on mobile to flip back to the session list. */
|
||||
@media (max-width: 768px) {
|
||||
html[data-viewport-mode="tablet"] .chat-view--docked-list .chat-view__body {
|
||||
flex-direction: row;
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Search,
|
||||
Trash2,
|
||||
Archive,
|
||||
ArrowLeft,
|
||||
Pencil,
|
||||
Bot,
|
||||
Paperclip,
|
||||
@@ -3911,6 +3912,13 @@ export function ChatView({ projectId, addToast, floating = false, compactLayout
|
||||
{rooms.activeRoom ? (
|
||||
<>
|
||||
<div className="chat-room-thread-header">
|
||||
{/*
|
||||
FNXC:ChatNavigation 2026-08-23-15:54:
|
||||
FN-9199 requires the chat detail Back affordance to render a real lucide ArrowLeft
|
||||
glyph, never a literal less-than text character. Both Rooms and Direct thread
|
||||
headers use this same icon-and-translated-label pattern on every chat host and
|
||||
breakpoint, while aria-label retains the fuller accessible name.
|
||||
*/}
|
||||
{!dockedSidebarVisible ? <button
|
||||
type="button"
|
||||
className="btn btn-sm chat-thread-header-back chat-back-btn"
|
||||
@@ -3918,7 +3926,8 @@ export function ChatView({ projectId, addToast, floating = false, compactLayout
|
||||
data-testid="chat-back-btn"
|
||||
aria-label={t("chat.backToConversations", "Back to conversations")}
|
||||
>
|
||||
{"< BACK"}
|
||||
<ArrowLeft size={14} aria-hidden="true" />
|
||||
<span>{t("chat.back", "Back")}</span>
|
||||
</button> : null}
|
||||
<span className="chat-thread-header-title">#{rooms.activeRoom.name}</span>
|
||||
<div className="chat-room-thread-members">
|
||||
@@ -4131,7 +4140,8 @@ export function ChatView({ projectId, addToast, floating = false, compactLayout
|
||||
data-testid="chat-back-btn"
|
||||
aria-label={t("chat.backToConversations", "Back to conversations")}
|
||||
>
|
||||
{"< BACK"}
|
||||
<ArrowLeft size={14} aria-hidden="true" />
|
||||
<span>{t("chat.back", "Back")}</span>
|
||||
</button> : null}
|
||||
<div className="chat-thread-header-identity" data-testid="chat-thread-header-identity">
|
||||
{activeModelProvider ? <ProviderIcon provider={activeModelProvider} size="md" /> : <Bot size={16} />}
|
||||
|
||||
@@ -54,7 +54,9 @@ describe("ChatView mobile list/detail navigation", () => {
|
||||
expect(sidebar).toHaveClass("chat-sidebar--hidden");
|
||||
const back = screen.getByTestId("chat-back-btn");
|
||||
expect(back).toHaveAccessibleName("Back to conversations");
|
||||
expect(back).toHaveTextContent("< BACK");
|
||||
expect(back.textContent ?? "").not.toContain("<");
|
||||
expect(back.querySelector("svg")).toBeInTheDocument();
|
||||
expect(back).toHaveTextContent("Back");
|
||||
expect(back.closest(".chat-thread-header")).toBeInTheDocument();
|
||||
expect(back.closest(".view-header")).toBeNull();
|
||||
expect(screen.getAllByTestId("chat-back-btn")).toHaveLength(1);
|
||||
|
||||
@@ -777,7 +777,12 @@ describe("ChatView — rooms (FN-3805..FN-3811 contract)", () => {
|
||||
await renderRoomDetailWithAct(<ChatView projectId="proj-123" addToast={vi.fn()} experimentalFeatures={{ chatRooms: true }} />);
|
||||
await userEvent.click(screen.getByTestId("chat-room-item-room-a"));
|
||||
|
||||
expect(screen.getByTestId("chat-back-btn")).toBeInTheDocument();
|
||||
const back = screen.getByTestId("chat-back-btn");
|
||||
expect(back).toBeInTheDocument();
|
||||
expect(back).toHaveAccessibleName("Back to conversations");
|
||||
expect(back.textContent ?? "").not.toContain("<");
|
||||
expect(back.querySelector("svg")).toBeInTheDocument();
|
||||
expect(back).toHaveTextContent("Back");
|
||||
mediaSpy.mockRestore();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user