Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions apps/web/src/components/beautiful-ui/CollaborationMarker.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { renderToString } from "react-dom/server";
import { describe, expect, it } from "vitest";
import { ActiveBotGlyph, CollaborationMarker } from "./CollaborationMarker";

describe("collaboration transcript markers", () => {
it("shows the peer avatar in an accessible message marker", () => {
const html = renderToString(
<CollaborationMarker
action="Message from"
ariaLabel="Message from Research"
color="#14B8A6"
name="Research"
onClick={() => undefined}
/>,
);

expect(html).toContain('aria-label="Message from Research"');
expect(html).toContain("rakazo-bot-avatar");
expect(html).toContain("Research");
});

it("animates the active bot glyph from its run status", () => {
const html = renderToString(
<ActiveBotGlyph
bots={[{ botId: "research", color: "#14B8A6", status: "running" }]}
label="Research is working"
/>,
);

expect(html).toContain('role="status"');
expect(html).toContain('data-working="true"');
expect(html).toContain("rakazo-bot-avatar-ring");
});
});
37 changes: 37 additions & 0 deletions apps/web/src/components/beautiful-ui/CollaborationMarker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { BotAvatar, GroupAvatar, type GroupAvatarMember } from "@rakazo/ui-web";
import type { ReactNode } from "react";

export function CollaborationMarker({
action,
ariaLabel,
color,
name,
onClick,
}: {
action: ReactNode;
ariaLabel: string;
color: string;
name: string;
onClick: () => void;
}) {
return (
<button
type="button"
aria-label={ariaLabel}
onClick={onClick}
className="flex items-center justify-center gap-1.5 self-center rounded-full px-2.5 py-1 text-[13px] text-[#85858A] transition-colors hover:bg-[#161618] hover:text-[#B8B8BD]"
>
<span>{action}</span>
<BotAvatar color={color} size={16} />
<span dir="auto">{name}</span>
</button>
);
}

export function ActiveBotGlyph({ bots, label }: { bots: GroupAvatarMember[]; label: string }) {
return (
<div role="status" aria-label={label} className="flex min-h-10 items-center px-1">
<GroupAvatar members={bots} size={28} />
</div>
);
}
Loading
Loading