authorgravatar for crazywolf132@gmail.com0x1f99d <crazywolf132@gmail.com> 2026-03-13 06:15:01+11:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-03-12 12:15:01-07:00
log224acebb57815193ef93c2d1861e606a626d23b3
tree169dbfa5f53cb8a98ee8fb604b8842cbdbaf26f2
parent85c174a6cac04b4fda68f311a904af0435c85807
signature Signed by PGP key B5690EEEBB952194

fix(web): add pointer cursor to running stop-generation button (#900)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

2 files changed, 26 insertions(+), 2 deletions(-)

apps/web/src/components/ChatView.browser.tsx+25-1
...@@ -11,6 +11,7 @@ import {...@@ -11,6 +11,7 @@ import {
11 type WsWelcomePayload,11 type WsWelcomePayload,
12 WS_CHANNELS,12 WS_CHANNELS,
13 WS_METHODS,13 WS_METHODS,
14 OrchestrationSessionStatus,
14} from "@t3tools/contracts";15} from "@t3tools/contracts";
15import { RouterProvider, createMemoryHistory } from "@tanstack/react-router";16import { RouterProvider, createMemoryHistory } from "@tanstack/react-router";
16import { HttpResponse, http, ws } from "msw";17import { HttpResponse, http, ws } from "msw";
...@@ -153,6 +154,7 @@ function createSnapshotForTargetUser(options: {...@@ -153,6 +154,7 @@ function createSnapshotForTargetUser(options: {
153 targetMessageId: MessageId;154 targetMessageId: MessageId;
154 targetText: string;155 targetText: string;
155 targetAttachmentCount?: number;156 targetAttachmentCount?: number;
157 sessionStatus?: OrchestrationSessionStatus;
156}): OrchestrationReadModel {158}): OrchestrationReadModel {
157 const messages: Array<OrchestrationReadModel["threads"][number]["messages"][number]> = [];159 const messages: Array<OrchestrationReadModel["threads"][number]["messages"][number]> = [];
158160
...@@ -222,7 +224,7 @@ function createSnapshotForTargetUser(options: {...@@ -222,7 +224,7 @@ function createSnapshotForTargetUser(options: {
222 checkpoints: [],224 checkpoints: [],
223 session: {225 session: {
224 threadId: THREAD_ID,226 threadId: THREAD_ID,
225 status: "ready",227 status: options.sessionStatus ?? "ready",
226 providerName: "codex",228 providerName: "codex",
227 runtimeMode: "full-access",229 runtimeMode: "full-access",
228 activeTurnId: null,230 activeTurnId: null,
...@@ -1009,6 +1011,28 @@ describe("ChatView timeline estimator parity (full app)", () => {...@@ -1009,6 +1011,28 @@ describe("ChatView timeline estimator parity (full app)", () => {
1009 }1011 }
1010 });1012 });
10111013
1014 it("shows a pointer cursor for the running stop button", async () => {
1015 const mounted = await mountChatView({
1016 viewport: DEFAULT_VIEWPORT,
1017 snapshot: createSnapshotForTargetUser({
1018 targetMessageId: "msg-user-stop-button-cursor" as MessageId,
1019 targetText: "stop button cursor target",
1020 sessionStatus: "running",
1021 }),
1022 });
1023
1024 try {
1025 const stopButton = await waitForElement(
1026 () => document.querySelector<HTMLButtonElement>('button[aria-label="Stop generation"]'),
1027 "Unable to find stop generation button.",
1028 );
1029
1030 expect(getComputedStyle(stopButton).cursor).toBe("pointer");
1031 } finally {
1032 await mounted.cleanup();
1033 }
1034 });
1035
1012 it("keeps the new thread selected after clicking the new-thread button", async () => {1036 it("keeps the new thread selected after clicking the new-thread button", async () => {
1013 const mounted = await mountChatView({1037 const mounted = await mountChatView({
1014 viewport: DEFAULT_VIEWPORT,1038 viewport: DEFAULT_VIEWPORT,
apps/web/src/components/ChatView.tsx+1-1
...@@ -3604,7 +3604,7 @@ export default function ChatView({ threadId }: ChatViewProps) {...@@ -3604,7 +3604,7 @@ export default function ChatView({ threadId }: ChatViewProps) {
3604 ) : phase === "running" ? (3604 ) : phase === "running" ? (
3605 <button3605 <button
3606 type="button"3606 type="button"
3607 className="flex size-8 items-center justify-center rounded-full bg-rose-500/90 text-white transition-all duration-150 hover:bg-rose-500 hover:scale-105 sm:h-8 sm:w-8"3607 className="flex size-8 cursor-pointer items-center justify-center rounded-full bg-rose-500/90 text-white transition-all duration-150 hover:bg-rose-500 hover:scale-105 sm:h-8 sm:w-8"
3608 onClick={() => void onInterrupt()}3608 onClick={() => void onInterrupt()}
3609 aria-label="Stop generation"3609 aria-label="Stop generation"
3610 >3610 >