diff --git a/CLAUDE.md b/CLAUDE.md index acec2fb..b3af99b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,7 +20,7 @@ claudius/ │ │ │ ├── ChatWindow.tsx # Chat UI container │ │ │ ├── ChatInput.tsx # Message input form │ │ │ ├── ChatToggleButton.tsx # Floating action button -│ │ │ └── MessageBubble.tsx # Individual message display +│ │ │ └── ChatMessage.tsx # Individual message display │ │ ├── hooks/ │ │ │ └── useChat.ts # Chat state management │ │ ├── index.ts # Public exports @@ -99,7 +99,7 @@ pnpm test # Run tests | `ChatWindow` | Chat UI container with message list and input | | `ChatInput` | Message input form with submit handling | | `ChatToggleButton` | Floating button to open/close chat | -| `MessageBubble` | Renders individual messages with URL linking | +| `ChatMessage` | Renders individual messages with URL linking | | `ChatSources` | Slide-out sidebar displaying grouped source links | | `SourceIcon` | Icon button with badge count to trigger source sidebar | diff --git a/docs/plans/2026-03-27-chatmessage-rename.md b/docs/plans/2026-03-27-chatmessage-rename.md new file mode 100644 index 0000000..be49de7 --- /dev/null +++ b/docs/plans/2026-03-27-chatmessage-rename.md @@ -0,0 +1,85 @@ +# ChatMessage Rename Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Rename `MessageBubble` to `ChatMessage` for naming consistency with other `Chat*` components. + +**Architecture:** Pure rename/refactor. No logic changes. Rename the component, file, test file, and update all imports. + +**Tech Stack:** React, TypeScript, Vitest + +--- + +### Task 1: Rename component file + +**Files:** +- Rename: `widget/src/components/MessageBubble.tsx` -> `widget/src/components/ChatMessage.tsx` + +**Step 1: Create ChatMessage.tsx with renamed exports** + +Copy `MessageBubble.tsx` to `ChatMessage.tsx`. Rename: +- Interface: `MessageBubbleProps` -> `ChatMessageProps` +- Component: `MessageBubble` -> `ChatMessage` +- `memo` display name: `MessageBubble` -> `ChatMessage` + +**Step 2: Delete old MessageBubble.tsx** + +**Step 3: Run tests to verify they fail (imports broken)** + +Run: `cd widget && pnpm test -- --run` +Expected: FAIL - cannot find `MessageBubble` + +### Task 2: Update test file + +**Files:** +- Rename: `widget/src/components/__tests__/MessageBubble.test.tsx` -> `widget/src/components/__tests__/ChatMessage.test.tsx` + +**Step 1: Create ChatMessage.test.tsx** + +Copy test file, update: +- Import: `from "../MessageBubble"` -> `from "../ChatMessage"` +- References: `MessageBubble` -> `ChatMessage` +- Describe block: `"MessageBubble"` -> `"ChatMessage"` + +**Step 2: Delete old MessageBubble.test.tsx** + +### Task 3: Update ChatWindow import + +**Files:** +- Modify: `widget/src/components/ChatWindow.tsx` + +**Step 1: Update import and JSX usage** + +Change: +```tsx +import { MessageBubble } from "./MessageBubble"; +``` +to: +```tsx +import { ChatMessage } from "./ChatMessage"; +``` + +Change JSX ` void; @@ -165,7 +158,7 @@ export function ChatWindow({ )} {messages.map((msg) => ( - { +describe("ChatMessage", () => { it("renders user message with correct styling", () => { - render(); + render(); const bubble = screen.getByText("Hello!"); expect(bubble).toBeInTheDocument(); // ml-auto is on the outer wrapper div (parent of the bubble div) @@ -20,7 +20,7 @@ describe("MessageBubble", () => { }); it("renders assistant message with correct styling", () => { - render(); + render(); const bubble = screen.getByText("How can I help?"); expect(bubble).toBeInTheDocument(); // mr-auto is on the outer wrapper div (parent of the bubble div) @@ -30,7 +30,7 @@ describe("MessageBubble", () => { it("renders links as clickable anchors", () => { render( - @@ -43,7 +43,7 @@ describe("MessageBubble", () => { it("renders source icon for assistant messages with sources", () => { render( - { it("does not render source icon for user messages", () => { render( - { it("does not render source icon when no sources", () => { render( - + ); expect(screen.queryByRole("button", { name: /view sources/i })).not.toBeInTheDocument(); }); @@ -79,7 +79,7 @@ describe("MessageBubble", () => { const user = userEvent.setup(); const onSourceClick = vi.fn(); render( -