Skip to content

feat(chat): fork ChatMessage into a local sandbox-ui component#47

Closed
vutuanlinh2k2 wants to merge 1 commit into
mainfrom
feat/local-chat-message
Closed

feat(chat): fork ChatMessage into a local sandbox-ui component#47
vutuanlinh2k2 wants to merge 1 commit into
mainfrom
feat/local-chat-message

Conversation

@vutuanlinh2k2
Copy link
Copy Markdown
Contributor

Summary

Stops re-exporting ChatMessage from @tangle-network/ui/chat and provides a local implementation in src/chat/chat-message.tsx. This gives sandbox-ui ownership of the component's markup and styling, independent of the upstream @tangle-network/ui package, while the rest of the chat surface continues to be re-exported from upstream.

What changed

  • New src/chat/chat-message.tsx — a self-contained ChatMessage component:
    • Supports user / assistant / system roles (user messages mirror layout to the right).
    • Optional avatar — default User/Bot icons or a caller-supplied avatar node; can be hidden via hideAvatar.
    • Role label (userLabel / assistantLabel, defaults "You" / "Agent") + optional timestamp, both hideable via hideRoleLabel.
    • Assistant content rendered through Markdown; user content rendered as pre-wrapped plain text.
    • Streaming cursor when isStreaming is set, plus a toolCalls slot.
  • src/chat/index.tsChatMessage, ChatMessageProps, and MessageRole now come from the local module; all other chat exports (ChatContainer, ChatInput, MessageList, ThinkingIndicator, UserMessage, etc.) still forward to @tangle-network/ui/chat.
  • src/__tests__/re-export-identity.test.ts — since ChatMessage is no longer a forwarded re-export, its identity assertion against the upstream component is removed and replaced with a presence check that sandbox-ui provides its own ChatMessage.

Styling approach

The component uses inline Tailwind utility classes backed by CSS-variable theming tokens (--radius-*, --font-size-*, --avatar-size, --accent-*, --brand-cool, --chat-message-*), each with sensible fallbacks. As a result it needs no companion globals.css rules — there are no stylesheet changes in this PR.

Note: an earlier iteration of this work used semantic .tangle-chat-message__* classes defined in globals.css; that approach was dropped in favor of the inline-utility version landed here.

Testing

  • npx vitest run src/__tests__/re-export-identity.test.ts13 passed.

🤖 Generated with Claude Code

Stop re-exporting ChatMessage from @tangle-network/ui/chat and provide a
local implementation in src/chat/chat-message.tsx instead. This lets
sandbox-ui own the component's markup and styling independently of the
upstream package.

The local component is styled with inline Tailwind utilities backed by
CSS-variable theming tokens (radius/font/avatar/accent), so it needs no
companion globals.css rules. It supports user/assistant/system roles,
optional avatar (default or custom), role label + timestamp, markdown
rendering for assistant content, a streaming cursor, and a tool-calls slot.

chat/index.ts now sources ChatMessage, ChatMessageProps, and MessageRole
locally while continuing to re-export the rest of the chat surface from
@tangle-network/ui/chat. The re-export identity test is updated: since
ChatMessage is no longer forwarded, the identity assertion is replaced
with a presence check that sandbox-ui provides its own ChatMessage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tangletools
Copy link
Copy Markdown
Contributor

tangletools commented May 22, 2026

✅ No Blockers — 701c8627

Readiness 92/100 · Confidence 95/100 · 2 findings (2 low)

kimi-code: Correctness 90 · Security 95 · Testing 75 · Architecture 85

I read all three changed files, the upstream source in node_modules/@tangle-network/ui/src/chat/chat-message.tsx, and verified build + 292 passing tests. The new ChatMessage is a near-identical fork of the upstream component with valid CSS fallbacks and a welcome aria-hidden improvement, but it introduces a minor timestamp styling regression. Missing JSDoc on props and the absence of component-level unit tests are the other gaps.

🟡 LOW Missing JSDoc on props — src/chat/chat-message.tsx

Lines 8-20: The upstream component had JSDoc comments explaining each prop (e.g., /** Custom user label. Default: "You" */). Their absence makes the API harder to discover for consumers. Copy the doc comments from the upstream source.

🟡 LOW Timestamp styling regression — src/chat/chat-message.tsx

Lines 69-77: The role-label div applies uppercase, font-[var(--chat-label-weight,600)], and tracking-[var(--chat-label-tracking,0.14em)] to the entire flex container, so the timestamp span inherits these styles. In the upstream version these styles were scoped only to the label span, leaving the timestamp at normal weight/tracking/case. Move the text styling back to the label <span> to match upstream behavior.


tangletools · 2026-05-22T06:27:49Z · trace

@vutuanlinh2k2 vutuanlinh2k2 marked this pull request as draft May 22, 2026 06:24
Copy link
Copy Markdown
Contributor

@tangletools tangletools left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Approved — 2 non-blocking findings — 701c8627

I read all three changed files, the upstream source in node_modules/@tangle-network/ui/src/chat/chat-message.tsx, and verified build + 292 passing tests. The new ChatMessage is a near-identical fork of the upstream component with valid CSS fallbacks and a welcome aria-hidden improvement, but it introduces a minor timestamp styling regression. Missing JSDoc on props and the absence of component-lev

Full findings and scores: review summary


tangletools · 2026-05-22T06:27:49Z · trace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants