React UI Base
Loading...
Overview
Reference for unstyled base primitives in @tambo-ai/react-ui-base.
The @tambo-ai/react-ui-base package exposes behavior-focused primitives. These components are intentionally unstyled and designed for composition in your own UI layer.
The same components — Message, MessageInput, and their sub-parts — can produce wildly different interfaces just by changing styles. Use the Theme control below to see three variations built with the exact same primitives.
import { Message } from "@tambo-ai/react-ui-base/message";import { MessageInput } from "@tambo-ai/react-ui-base/message-input";import type { TamboThreadMessage } from "@tambo-ai/react";const messages: TamboThreadMessage[] = [ { id: "1", role: "user", content: [{ type: "text", text: "What's the weather in Tokyo?" }] }, { id: "2", role: "assistant", content: [{ type: "text", text: "It's 18°C and clear!" }] },];// Modern minimal: rounded bubbles, avatars, role-based colorsexport function MinimalChat() { return ( <div style={{ borderRadius: 12, border: "1px solid #e5e7eb", overflow: "hidden" }}> <div style={{ padding: 16, display: "flex", flexDirection: "column", gap: 12 }}> {messages.map((msg) => ( <Message.Root key={msg.id} message={msg} role={msg.role} style={{ display: "flex", gap: 8, ...(msg.role === "user" ? { flexDirection: "row-reverse" } : {}) }}> <div style={{ width: 28, height: 28, borderRadius: "50%", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 12, fontWeight: 700, backgroundColor: msg.role === "user" ? "#3b82f6" : "#e5e7eb", color: msg.role === "user" ? "#fff" : "#4b5563", }}>{msg.role === "user" ? "U" : "A"}</div> <div style={{ padding: "9px 14px", borderRadius: 18, backgroundColor: msg.role === "user" ? "#3b82f6" : "#f3f4f6", color: msg.role === "user" ? "#fff" : "#1f2937", }}> <Message.Content style={{ fontSize: 14, lineHeight: 1.5 }} /> </div> </Message.Root> ))} </div> <MessageInput.Root style={{ borderTop: "1px solid #e5e7eb", padding: "10px 12px" }}> <MessageInput.Content style={{ display: "flex", gap: 8 }}> <MessageInput.Textarea placeholder="Type a message..." style={{ flex: 1, border: "1px solid #d1d5db", borderRadius: 20, padding: "8px 14px", fontSize: 14, outline: "none" }} /> <MessageInput.SubmitButton style={{ padding: "8px 16px", borderRadius: 20, border: "none", backgroundColor: "#3b82f6", color: "#fff", fontWeight: 600, cursor: "pointer" }}> Send </MessageInput.SubmitButton> </MessageInput.Content> </MessageInput.Root> </div> );}Primitives
- Message — message display, content blocks, images, loading
- MessageInput — input, submit, stop, file upload, elicitation
- ThreadContent — thread-level message list and empty/loading states
- ThreadHistory — sidebar thread list with search
- ThreadDropdown — compact thread switcher dropdown
- ToolcallInfo — tool call status and details
- ReasoningInfo — AI reasoning step display
- Elicitation — MCP elicitation form
- McpPrompts — MCP prompt picker
- McpResources — MCP resource picker
- GenerationStage — generation status indicators
Ownership model
@tambo-ai/react-ui-base: behavior, state, and composition contracts.@tambo-ai/ui-registry: styled components and block-level orchestration.
Key patterns
Role-based styling
Each component exposes data-role attributes. Style user and assistant messages differently:
<Message.Root message={message} role={message.role}
style={{ flexDirection: message.role === "user" ? "row-reverse" : "row" }}>No CSS framework required
The examples above use plain inline styles — no Tailwind, no CSS modules, no styled-components. The base components work with any styling approach.