Skip to main content

@pressw/chat-ui

Pre-built React components for creating beautiful chat interfaces. This package provides customizable UI components that work seamlessly with the @pressw/threads system.

Overview

@pressw/chat-ui offers a complete set of React components for building chat applications:

  • 💬 Message Components - Display messages with avatars, timestamps, and rich content
  • 📝 Input Components - Text input with emoji support and file attachments
  • 🎨 Customizable Themes - Built-in themes and easy customization
  • Accessible - WCAG compliant with keyboard navigation
  • 📱 Responsive - Mobile-first design that works on all devices
  • Optimized - Virtualized scrolling for large message lists

Installation

npm install @pressw/chat-ui @pressw/threads

# Peer dependencies
npm install react react-dom

Quick Start

Basic Chat Window

import { ChatWindow, ChatProvider } from '@pressw/chat-ui';
import { useThread } from '@pressw/threads';

function MyChat({ threadId }: { threadId: string }) {
const { data: thread } = useThread(threadId);

return (
<ChatProvider>
<ChatWindow
thread={thread}
onSendMessage={async (message) => {
// Handle message sending
console.log('Sending:', message);
}}
/>
</ChatProvider>
);
}

Custom Styling

import { ChatWindow, ChatTheme } from '@pressw/chat-ui';

const customTheme: ChatTheme = {
colors: {
primary: '#007bff',
background: '#f8f9fa',
surface: '#ffffff',
text: '#212529',
textSecondary: '#6c757d',
},
spacing: {
xs: '0.25rem',
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
xl: '2rem',
},
borderRadius: {
message: '1rem',
input: '0.5rem',
},
};

function ThemedChat() {
return (
<ChatProvider theme={customTheme}>
<ChatWindow />
</ChatProvider>
);
}

Components

ChatWindow

The main chat interface component that includes message list and input.

<ChatWindow
thread={thread}
messages={messages}
onSendMessage={handleSend}
placeholder="Type a message..."
showTypingIndicator={isTyping}
allowFileUpload
maxFileSize={10 * 1024 * 1024} // 10MB
/>

MessageList

Displays a list of messages with virtualization for performance.

<MessageList
messages={messages}
currentUserId={userId}
onMessageClick={handleMessageClick}
onLoadMore={handleLoadMore}
hasMore={hasMoreMessages}
loading={isLoading}
/>

MessageInput

Input component with rich features.

<MessageInput
onSend={handleSend}
onTyping={handleTyping}
placeholder="Type your message..."
allowEmoji
allowFileAttachment
maxLength={1000}
disabled={isSending}
/>

Message

Individual message component.

<Message
content="Hello, world!"
author={{
id: 'user-123',
name: 'John Doe',
avatar: '/avatar.jpg',
}}
timestamp={new Date()}
isCurrentUser={false}
status="delivered"
/>

TypingIndicator

Shows when other users are typing.

<TypingIndicator
users={[
{ id: 'user-1', name: 'Alice' },
{ id: 'user-2', name: 'Bob' },
]}
/>

Features

Message Types

Support for various message content types:

// Text message
<Message content="Hello!" type="text" />

// Image message
<Message
type="image"
content={{
url: '/image.jpg',
alt: 'Shared image',
width: 400,
height: 300,
}}
/>

// File attachment
<Message
type="file"
content={{
name: 'document.pdf',
size: 1024000,
url: '/download/document.pdf',
}}
/>

// System message
<Message
type="system"
content="Alice joined the conversation"
/>

Reactions

Add emoji reactions to messages:

<Message
content="Great idea!"
reactions={[
{ emoji: '👍', count: 3, users: ['user-1', 'user-2', 'user-3'] },
{ emoji: '❤️', count: 1, users: ['user-4'] },
]}
onReact={(emoji) => handleReaction(messageId, emoji)}
/>

Message Actions

Context menu for message actions:

<Message
content="Important message"
actions={[
{ label: 'Reply', icon: ReplyIcon, onClick: handleReply },
{ label: 'Edit', icon: EditIcon, onClick: handleEdit },
{ label: 'Delete', icon: DeleteIcon, onClick: handleDelete, danger: true },
]}
/>

File Upload

Built-in file upload with preview:

<MessageInput
allowFileAttachment
acceptedFileTypes={['image/*', '.pdf', '.doc', '.docx']}
maxFileSize={10 * 1024 * 1024}
onFileSelect={(files) => {
// Handle file upload
console.log('Selected files:', files);
}}
/>

Customization

CSS Variables

Override CSS variables for quick theming:

.chat-window {
--chat-primary-color: #007bff;
--chat-bg-color: #f8f9fa;
--chat-message-bg: #ffffff;
--chat-message-current-bg: #007bff;
--chat-text-color: #212529;
--chat-border-radius: 1rem;
}

Custom Components

Replace any component with your own:

<ChatWindow
components={{
Message: CustomMessage,
Avatar: CustomAvatar,
Timestamp: CustomTimestamp,
}}
/>

Localization

Support for multiple languages:

import { ChatProvider } from '@pressw/chat-ui';
import { enUS, frFR, esES } from '@pressw/chat-ui/locales';

<ChatProvider locale={frFR}>
<ChatWindow />
</ChatProvider>;

Accessibility

All components follow WCAG 2.1 guidelines:

  • Keyboard navigation support
  • Screen reader announcements
  • Focus management
  • High contrast mode support
  • Reduced motion support

Performance

Virtualization

Large message lists are automatically virtualized:

<MessageList
messages={messages} // Can handle thousands of messages
overscan={5} // Number of items to render outside visible area
estimatedItemSize={80} // Estimated height of each message
/>

Lazy Loading

Images and files are lazy loaded:

<Message
type="image"
content={{
url: '/large-image.jpg',
thumbnail: '/thumbnail.jpg', // Shows while loading
lazy: true,
}}
/>

Integration with @pressw/threads

The components are designed to work seamlessly with the threads system:

import { ChatWindow } from '@pressw/chat-ui';
import { useThread, useCreateMessage } from '@pressw/threads';

function ThreadChat({ threadId }: { threadId: string }) {
const { data: thread } = useThread(threadId);
const createMessage = useCreateMessage();

return (
<ChatWindow
thread={thread}
onSendMessage={async (content) => {
await createMessage.mutateAsync({
threadId,
content,
});
}}
/>
);
}

Examples

API Reference

For detailed API documentation, see the Components Reference.

Next Steps