fix(ui): white text on light-mode user chat bubbles (#10952)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The task detail view shows the conversation as chat bubbles. The requester's own messages sit in a solid accent-colored bubble. > - The bubble container sets `text-white`, but the message body renders through `MarkdownBody`. Tailwind prose tokens (`--tw-prose-body`) win over the inherited container color. > - `prose-invert` only lightens the prose text in dark mode. In light mode the prose body stayed its default dark color, so the text read as near-black on the blue bubble and was hard to read. > - This pull request maps the human bubble's prose tokens to the inherited text color in both themes. > - The benefit is that the requester's chat text is readable white-on-blue in light mode, and dark mode stays exactly as it was. ## Linked Issues or Issue Description <!-- No public GitHub issue exists; described in-PR per the bug report template. --> **What happened?** In light mode, the text inside the user's own chat bubbles in the task detail view rendered as dark (near-black) on the solid blue accent background. This made the requester's messages hard to read. **Expected behavior** The text inside the user's accent-colored chat bubbles should be white in light mode, matching the bubble's `text-white` intent. Dark mode already rendered correctly and should not change. **Steps to reproduce** 1. Open a chat-style task detail view in light mode. 2. Post a message as the requester (human) so it renders in the solid blue accent bubble. 3. Observe the body text renders dark on blue instead of white. **Paperclip version or commit** Reproduces on `master` (branched from `814cb3367`). **Agent adapter(s) involved** Not adapter-specific (core UI bug). ## What Changed - Add the existing `paperclip-markdown-on-accent` class to the human-branch `MarkdownBody` in `TaskChatBubble.tsx`. This class (already used by `IssueChatThread` for the same accent bubble) maps prose body/heading tokens to `currentColor`, so the text follows the bubble's `text-white` in both themes. - Apply the same class to the human-branch `MarkdownBody` in `TaskChatDescriptionBubble.tsx` (the description-as-first-bubble surface) for consistency. - Add unit tests covering that the human accent bubble carries the on-accent class and the agent/neutral bubbles do not. ## Verification - `pnpm check:token-gates` → 3/3 CLEAN. - `pnpm --filter ./ui vitest run src/components/task-chat/TaskChatBubble.test.tsx` → 9/9 passing. - Manual: in light mode, the requester's chat bubble text renders white on blue; agent/neutral bubbles unchanged; dark mode unchanged. This is a visual change. Snapshot baselines are intentionally not updated, per `doc/design/DECISION-SHEET.md` → "Per-change snapshot verification demoted to dormant (Jul 13 2026)". ## Risks Low risk. The change is scoped to the human-branch `MarkdownBody` className on two chat-bubble components and only remaps prose color tokens to the inherited text color. Agent and neutral bubbles are untouched, and dark mode behavior is unchanged. ## Model Used Claude Opus 4.8 (Anthropic), model id `claude-opus-4-8`, ~200K context window, extended thinking mode, with tool use / code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
814cb33676
commit
2ea22d6cea
|
|
@ -66,6 +66,48 @@ describe("TaskChatBubble attachment chips", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("TaskChatBubble accent-bubble text color", () => {
|
||||
let container: HTMLDivElement;
|
||||
let root: Root | null = null;
|
||||
|
||||
beforeEach(() => {
|
||||
container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
root = createRoot(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
flushSync(() => root?.unmount());
|
||||
root = null;
|
||||
container.remove();
|
||||
});
|
||||
|
||||
function render(item: TaskChatMessageItem) {
|
||||
flushSync(() =>
|
||||
root!.render(
|
||||
<ThemeProvider>
|
||||
<TaskChatBubble item={item} />
|
||||
</ThemeProvider>,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
it("marks the human bubble's markdown as on-accent so prose text follows text-white", () => {
|
||||
render({ id: "m1", kind: "message", author: "human", text: "when a new task is created…" });
|
||||
const body = container.querySelector(".paperclip-markdown");
|
||||
expect(body).not.toBeNull();
|
||||
// Without this class the light-mode prose body color reads as black on blue.
|
||||
expect(body?.className).toContain("paperclip-markdown-on-accent");
|
||||
});
|
||||
|
||||
it("leaves the neutral agent bubble on default prose colors", () => {
|
||||
render({ id: "m1", kind: "message", author: "agent", authorName: "CEO", text: "Final reply." });
|
||||
const body = container.querySelector(".paperclip-markdown");
|
||||
expect(body).not.toBeNull();
|
||||
expect(body?.className).not.toContain("paperclip-markdown-on-accent");
|
||||
});
|
||||
});
|
||||
|
||||
describe("TaskChatBubble interstitial self-talk (PAP-357)", () => {
|
||||
let container: HTMLDivElement;
|
||||
let root: Root | null = null;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,17 @@ export function TaskChatBubble({ item, attachedTurn }: TaskChatBubbleProps) {
|
|||
item.optimistic ? "opacity-80" : null,
|
||||
)}
|
||||
>
|
||||
<MarkdownBody softBreaks linkIssueReferences>
|
||||
<MarkdownBody
|
||||
// The human bubble sits on the solid --liveness-blue accent, so the
|
||||
// prose body text must follow the bubble's `text-white` rather than
|
||||
// the default light-mode prose color (which reads as black on blue).
|
||||
// `paperclip-markdown-on-accent` flips prose tokens to currentColor
|
||||
// (== inherited white) in both themes; dark mode was already correct
|
||||
// only because `prose-invert` happened to lighten the text.
|
||||
className={isHuman ? "paperclip-markdown-on-accent" : undefined}
|
||||
softBreaks
|
||||
linkIssueReferences
|
||||
>
|
||||
{bodyText}
|
||||
</MarkdownBody>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -148,7 +148,14 @@ export function TaskChatDescriptionBubble({ brief }: TaskChatDescriptionBubblePr
|
|||
// toggle's muted colors need a lift on the solid blue bubble.
|
||||
toggleClassName={isHuman ? "text-white/80 hover:text-white hover:bg-white/10" : undefined}
|
||||
>
|
||||
<MarkdownBody softBreaks linkIssueReferences externalReferences={brief.externalReferences}>
|
||||
<MarkdownBody
|
||||
// On the solid --liveness-blue human bubble, keep prose body text
|
||||
// following the bubble's `text-white` in both themes.
|
||||
className={isHuman ? "paperclip-markdown-on-accent" : undefined}
|
||||
softBreaks
|
||||
linkIssueReferences
|
||||
externalReferences={brief.externalReferences}
|
||||
>
|
||||
{brief.description}
|
||||
</MarkdownBody>
|
||||
</FoldCurtain>
|
||||
|
|
|
|||
Loading…
Reference in New Issue