tolky-chat
v1.14.6
Published
React component library for rendering chat conversation UIs. Supports text, media (image, audio, video, document), admin messages, ticket events, markdown, reply threading, and i18n.
Maintainers
Keywords
Readme
tolky-chat
React component library for rendering chat conversation UIs. Supports text, media (image, audio, video, document), admin messages, ticket events, markdown, reply threading, and i18n.
Installation
npm install tolky-chatPeer dependencies: react >= 18.2.0 < 20, react-dom same range.
CSS
Import once in your app entry point:
import "tolky-chat/dist/chat.css";Basic usage
import { Conversation } from "tolky-chat";
import "tolky-chat/dist/chat.css";
<Conversation
conversation={messages}
language="pt"
location="manager"
colors={{ user: { background: "#DCF8C6" } }}
onMessageInfoClick={(msg) => console.log(msg)}
onReplyMessageClick={(msg) => console.log(msg)}
/>ConversationProps
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| conversation | Message[] | required | Ordered array of messages to render |
| colors | Colors | undefined | Per-role color overrides |
| location | "webchat" \| "manager" \| "minichat" | "webchat" | Surface context; controls which UI chrome is shown |
| language | "pt" \| "en" \| "es" | "pt" | UI string language and date locale |
| onMessageInfoClick | (message) => void | undefined | Fired when info icon clicked. Active at location: "manager" on user messages only. |
| onReplyMessageClick | (message) => void | undefined | Fired when reply button clicked. Enabled at location: "manager". |
Message types
MessageCore
{
id?: string;
role: "user" | "system" | "assistant";
content: string | string[];
createdAt?: string; // ISO 8601
userId?: string | null;
media?: Media[];
type?: "ticket" | "document" | "audio" | "video" | string | null;
status?: "sent" | "delivered" | "accepted" | "read" | "failed" | null;
reason?: string | null; // Tooltip text when status="failed"
}MessageWithSource — human agent message
Extends MessageCore with:
{
source: {
type: string | null;
userName: string | null; // Displayed below the bubble
authUserId: string | null; // Must be truthy to trigger admin rendering
from: string | null;
}
}MessageWithTicket — ticket lifecycle event
Extends MessageCore with:
{
type: "ticket";
ticket: Ticket;
}Media
{
url?: string;
convertedUrl?: string | null;
type: "img" | "audio" | "video" | "document" | string | null;
description?: string | null; // <img_description> or <document_description> tags
transcription? string | null; // <audio_transcription> or <img_transcription> tags
fileName?: string | null;
}Ticket types
TicketWithStatus
{
type: "status";
id: string;
level: number;
color: string; // "#3182CE" or "3182CE" — both accepted
label: string;
timestamp: Date | string;
levelConfigId?: string;
href?: string;
protocol?: string;
}TicketWithMessage
{
type: "messageBox";
id: string;
timestamp: Date | string;
levelConfigId?: string;
protocol?: string;
sentBy: { authUserId: string; userName: string; };
sendingMethods: Array<{
type: "email" | "wpp";
format: "html" | "markdown";
content: string;
}>;
}TicketWithFeedback
{
type: "feedback";
id: string;
content: string;
score: number;
color: string;
label: string;
timestamp: Date | string;
levelConfigId?: string;
protocol?: string;
}TicketWithInfo
{
type: "info";
id: string;
content: string;
timestamp: Date | string;
levelConfigId?: string;
protocol?: string;
}
TicketWithInfoonly renders whenlocation === "manager".
Colors
type Colors = {
user?: ColorElements;
system?: ColorElements;
admin?: ColorElements;
}
type ColorElements = {
background?: string | null;
text?: string | null;
textLink?: string | null;
backgroundLink?: string | null;
bgTableHeader?: string | null;
borderTable?: string | null;
colorCreationTime?: string | null;
}Extended fields (runtime-only)
Not in the exported TypeScript types, but accepted at runtime:
type MyMessage = Message & {
repliedMessageId?: string | { replyMetaId: string } | null;
};Passing repliedMessageId shows a quoted preview above the bubble and enables scroll-to-original on click.
Behavior notes
content: string[]— joined with\nbefore Markdown rendering- Markdown rendered via
react-markdown+remark-gfm+rehype-highlight(tables, code blocks, GFM) - Bare
www.links auto-prefixed withhttps:// role: "system"+type: "text"messages are silently suppressed (no output)status: ""treated same asnull— no indicator shown- Date separators inserted automatically between messages from different calendar days
Development
npm install
npm run dev
# Edit mock data in src/main.tsx
# Edit source in lib/Publishing
# Bump version in package.json, then:
npm login
npm publish