diff --git a/.changeset/fn-7655-planner-stop-icon-only.md b/.changeset/fn-7655-planner-stop-icon-only.md
new file mode 100644
index 0000000000..e8af50f9be
--- /dev/null
+++ b/.changeset/fn-7655-planner-stop-icon-only.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": patch
+---
+
+summary: Planner chat stop button now shows just the stop icon, not a text label.
+category: fix
+dev: StandardChatActionButton gains showStopText (defaults to showSendText); TaskPlannerChatTab sets showStopText={false}. aria-label "Stop generation" retained.
diff --git a/packages/dashboard/app/components/StandardChatSurface.tsx b/packages/dashboard/app/components/StandardChatSurface.tsx
index 7480a372ac..2ba956e35f 100644
--- a/packages/dashboard/app/components/StandardChatSurface.tsx
+++ b/packages/dashboard/app/components/StandardChatSurface.tsx
@@ -75,6 +75,15 @@ export interface StandardChatActionButtonProps {
classNameSend?: string;
classNameStop?: string;
showSendText?: boolean;
+ /**
+ * FNXC:StandardChatSurface 2026-07-07-00:00:
+ * Send and Stop visible-text are independently controllable so callers like
+ * the planner (FN-7655) can render the Stop button icon-only while keeping
+ * the Send button's text label. Defaults to `showSendText` when unset so
+ * existing callers keep prior combined behavior (accessible name via
+ * aria-label is always preserved regardless of this flag).
+ */
+ showStopText?: boolean;
sendTestId?: string;
stopTestId?: string;
}
@@ -515,11 +524,14 @@ export function useStandardChatActionGesture() {
return { beginTouchActionGesture, markHandledSendTouch, consumeHandledSendTouch };
}
-export function StandardChatActionButton({ isStreaming, canSend, onSend, onStop, sendLabel, stopLabel, classNameSend = "chat-input-send", classNameStop = "chat-input-stop", showSendText = false, sendTestId = "chat-send-btn", stopTestId = "chat-stop-btn" }: StandardChatActionButtonProps) {
+export function StandardChatActionButton({ isStreaming, canSend, onSend, onStop, sendLabel, stopLabel, classNameSend = "chat-input-send", classNameStop = "chat-input-stop", showSendText = false, showStopText, sendTestId = "chat-send-btn", stopTestId = "chat-stop-btn" }: StandardChatActionButtonProps) {
const { t } = useTranslation("app");
const { beginTouchActionGesture, markHandledSendTouch, consumeHandledSendTouch } = useStandardChatActionGesture();
+ // FNXC:StandardChatSurface 2026-07-07-00:00: resolve the Stop button's visible-text flag
+ // independently of Send's, defaulting to showSendText when the caller doesn't opt in (FN-7655).
+ const showStop = showStopText ?? showSendText;
if (isStreaming) {
- return ;
+ return ;
}
return ;
}
diff --git a/packages/dashboard/app/components/TaskPlannerChatTab.tsx b/packages/dashboard/app/components/TaskPlannerChatTab.tsx
index 9dc731eb54..16eaad28c8 100644
--- a/packages/dashboard/app/components/TaskPlannerChatTab.tsx
+++ b/packages/dashboard/app/components/TaskPlannerChatTab.tsx
@@ -964,6 +964,9 @@ export function TaskPlannerChatTab({ task, projectId, active, expanded = false,
sendLabel={t("taskDetail.plannerChat.send", "Send")}
stopLabel={t("chat.stopGeneration", "Stop generation")}
showSendText
+ // FNXC:TaskPlannerChat 2026-07-07-00:00: planner stop button is icon-only
+ // per FN-7655 — aria-label above keeps the accessible name "Stop generation".
+ showStopText={false}
/>
diff --git a/packages/dashboard/app/components/__tests__/TaskPlannerChatTab.test.tsx b/packages/dashboard/app/components/__tests__/TaskPlannerChatTab.test.tsx
index 706b1d8c27..bf45f2bf24 100644
--- a/packages/dashboard/app/components/__tests__/TaskPlannerChatTab.test.tsx
+++ b/packages/dashboard/app/components/__tests__/TaskPlannerChatTab.test.tsx
@@ -710,7 +710,9 @@ describe("TaskPlannerChatTab", () => {
const stopIcon = stopButton.querySelector(".chat-input-stop-icon");
expect(stopIcon).toBeTruthy();
expect(stopIcon).toHaveAttribute("aria-hidden", "true");
- expect(stopButton).toHaveTextContent("Stop generation");
+ // FN-7655: the streaming stop button is icon-only — no visible "Stop generation" text span,
+ // even though the accessible name (aria-label) above still resolves to "Stop generation".
+ expect(stopButton.querySelector("span:not(.chat-input-stop-icon)")).toBeNull();
expect(screen.getByText("Thinking…")).toBeInTheDocument();
expect(screen.getByText("checking the plan")).toBeInTheDocument();