Skip to content

Commit f2e8cad

Browse files
authored
fix(canvas): align thread mention rendering
Generated-By: PostHog Code Task-Id: 87a79e23-20c4-440b-818b-28154924ffbc
1 parent eb76666 commit f2e8cad

3 files changed

Lines changed: 45 additions & 5 deletions

File tree

packages/ui/src/features/canvas/components/ActivityView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ function ActivityRow({
104104
<MentionText
105105
content={item.content}
106106
currentUserEmail={currentUserEmail}
107-
className="mt-1 block whitespace-pre-wrap break-words"
107+
className="mt-1 block whitespace-pre-wrap break-words text-xs"
108108
/>
109109
</span>
110110
</button>

packages/ui/src/features/canvas/components/MentionText.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,22 @@ describe("MentionText", () => {
1818
"mention-chip--self",
1919
);
2020
});
21+
22+
it("highlights a literal agent mention", () => {
23+
render(<MentionText content="@agent investigate this" />);
24+
25+
expect(screen.getByText("@agent")).toHaveClass("mention-chip");
26+
});
27+
28+
it("does not highlight agent text inside another token", () => {
29+
render(<MentionText content="person@agent.com" />);
30+
31+
expect(screen.queryByText("@agent")).not.toBeInTheDocument();
32+
});
33+
34+
it("inherits the surrounding message text size", () => {
35+
render(<MentionText content="A thread reply" />);
36+
37+
expect(screen.getByText("A thread reply")).not.toHaveClass("text-xs");
38+
});
2139
});

packages/ui/src/features/canvas/components/MentionText.tsx

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import "./mention-chip.css";
66
type RenderSegment =
77
| { type: "text"; text: string }
88
| { type: "link"; text: string; href: string }
9+
| { type: "agent"; text: string }
910
| { type: "mention"; name: string; email: string };
1011

1112
// The plain (not-the-viewer) mention chip look, also used by surfaces that
@@ -35,24 +36,45 @@ export function MentionText({
3536
entries.push({ segment, key: `${offset}` });
3637
offset += length;
3738
};
39+
const pushText = (text: string) => {
40+
let cursor = 0;
41+
for (const match of text.matchAll(/(^|\s)(@agent)\b/gi)) {
42+
const mentionStart = (match.index ?? 0) + match[1].length;
43+
for (const part of splitLinkSegments(
44+
text.slice(cursor, mentionStart),
45+
)) {
46+
push(part, part.text.length);
47+
}
48+
push({ type: "agent", text: match[2] }, match[2].length);
49+
cursor = mentionStart + match[2].length;
50+
}
51+
for (const part of splitLinkSegments(text.slice(cursor))) {
52+
push(part, part.text.length);
53+
}
54+
};
3855
for (const segment of splitMentionSegments(content)) {
3956
if (segment.type === "mention") {
4057
push(
4158
{ type: "mention", name: segment.name, email: segment.email },
4259
segment.text.length,
4360
);
4461
} else {
45-
for (const part of splitLinkSegments(segment.text)) {
46-
push(part, part.text.length);
47-
}
62+
pushText(segment.text);
4863
}
4964
}
5065
return entries;
5166
}, [content]);
5267
const selfEmail = currentUserEmail?.toLowerCase();
5368
return (
54-
<span className={`text-xs ${className ?? ""}`}>
69+
<span className={className}>
5570
{segments.map(({ segment, key }) => {
71+
if (segment.type === "agent") {
72+
return (
73+
<span key={key} className={mentionChipClass}>
74+
{segment.text}
75+
</span>
76+
);
77+
}
5678
if (segment.type === "mention") {
5779
return (
5880
<span

0 commit comments

Comments
 (0)