No description
|
Some checks failed
Publish / publish (push) Failing after 1s
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| src | ||
| .gitignore | ||
| eslint.config.js | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
@lilith/ui-messaging
Messaging and chat components for real-time communication interfaces. Includes message bubbles, chat feeds, thread lists, and specialized messaging UIs.
Features
- Message bubbles with tapback reactions and media support
- Chat feeds with auto-scroll and loading states
- Thread lists for inbox views
- Message composer with attachments and typing indicators
- Specialized UIs - DM inbox, support chat, live chat, inquiry forms
- Voting and reporting controls
- Community access badges with ban levels
- Content moderation integration
Installation
pnpm add @lilith/ui-messaging
Peer Dependencies
{
"react": "^18.0.0",
"react-dom": "^18.0.0",
"styled-components": "^6.0.0"
}
Usage
MessageBubble
Individual message display with reactions:
import { MessageBubble, type MessageBubbleMessage } from '@lilith/ui-messaging';
const message: MessageBubbleMessage = {
id: '1',
content: 'Hello! How are you?',
senderId: 'user-1',
timestamp: new Date(),
type: 'text',
tapbacks: [{ type: 'heart', userId: 'user-2' }],
};
<MessageBubble
message={message}
isOwn={true}
senderName="Jane"
senderAvatar="https://example.com/avatar.jpg"
onTapback={(type) => addReaction(message.id, type)}
/>
ChatFeed
Complete chat interface with messages:
import { ChatFeed, type ChatFeedConfig } from '@lilith/ui-messaging';
const config: ChatFeedConfig = {
enableReactions: true,
enableReplies: true,
showTimestamps: true,
};
<ChatFeed
messages={messages}
currentUserId="user-1"
onSendMessage={(content) => sendMessage(content)}
onLoadMore={() => loadOlderMessages()}
isLoading={isLoading}
config={config}
/>
MessageThread
Threaded conversation view:
import { MessageThread, type MessageThreadConfig } from '@lilith/ui-messaging';
<MessageThread
threadId="thread-1"
messages={threadMessages}
currentUserId="user-1"
onSendReply={(content) => sendReply(content)}
onClose={() => closeThread()}
/>
ThreadList
List of conversation threads:
import { ThreadList } from '@lilith/ui-messaging';
<ThreadList
threads={threads}
selectedThreadId={selectedId}
onThreadSelect={(thread) => openThread(thread)}
onThreadDelete={(threadId) => deleteThread(threadId)}
/>
ThreadListItem
Individual thread preview:
import { ThreadListItem } from '@lilith/ui-messaging';
<ThreadListItem
avatarUrl="https://example.com/avatar.jpg"
name="Jane Doe"
preview="Hey, wanted to ask about..."
timestamp={new Date()}
unreadCount={3}
isOnline={true}
onClick={() => openConversation()}
/>
MessageInput
Standalone message input field:
import { MessageInput } from '@lilith/ui-messaging';
<MessageInput
value={message}
onChange={setMessage}
onSend={() => sendMessage(message)}
placeholder="Type a message..."
disabled={isLoading}
/>
MessageComposer
Full-featured composer with attachments:
import { MessageComposer, type Attachment } from '@lilith/ui-messaging';
<MessageComposer
onSend={(content, attachments) => sendMessage(content, attachments)}
onAttach={(files) => uploadFiles(files)}
attachments={pendingAttachments}
isTyping={isTyping}
maxAttachments={5}
/>
MailboxTabs
Tabbed inbox navigation:
import { MailboxTabs, type MailboxTab } from '@lilith/ui-messaging';
const tabs: MailboxTab[] = [
{ id: 'inbox', label: 'Inbox', count: 12 },
{ id: 'unread', label: 'Unread', count: 3 },
{ id: 'archived', label: 'Archived' },
];
<MailboxTabs
tabs={tabs}
activeTab="inbox"
onTabChange={(tabId) => setActiveTab(tabId)}
/>
VoteButton / VoteControl
Upvote/downvote controls:
import { VoteButton, VoteControl } from '@lilith/ui-messaging';
// Individual button
<VoteButton
type="up"
active={hasUpvoted}
count={42}
onClick={() => toggleVote('up')}
/>
// Combined control
<VoteControl
upvotes={42}
downvotes={3}
userVote={userVote}
onVote={(type) => submitVote(type)}
/>
ReportButton
Content reporting:
import { ReportButton, QuickReportButton } from '@lilith/ui-messaging';
// Full report dialog
<ReportButton
onReport={(reason, details) => submitReport(reason, details)}
/>
// Quick report with presets
<QuickReportButton
options={['spam', 'harassment', 'inappropriate']}
onReport={(option) => quickReport(option)}
/>
PriorityBadge
Message priority indicator:
import { PriorityBadge } from '@lilith/ui-messaging';
<PriorityBadge priority="high" />
<PriorityBadge priority="medium" />
<PriorityBadge priority="low" />
CommunityAccessBadge
User access level and ban status:
import { CommunityAccessBadge, StatusDot } from '@lilith/ui-messaging';
<CommunityAccessBadge
level="member"
banLevel={null}
/>
<CommunityAccessBadge
level="moderator"
banLevel="muted"
/>
// Online status indicator
<StatusDot status="online" />
<StatusDot status="away" />
<StatusDot status="offline" />
Specialized Components
DMInbox
Direct message inbox:
import { DMInbox } from '@lilith/ui-messaging';
<DMInbox
conversations={conversations}
currentUserId="user-1"
onConversationSelect={(conv) => openDM(conv)}
onNewMessage={() => startNewConversation()}
/>
SupportChat
Customer support chat interface:
import { SupportChat } from '@lilith/ui-messaging';
<SupportChat
messages={supportMessages}
onSendMessage={(msg) => sendToSupport(msg)}
agentName="Support Team"
agentAvatar="https://example.com/support.jpg"
isAgentOnline={true}
/>
LiveChat
Real-time live chat widget:
import { LiveChat } from '@lilith/ui-messaging';
<LiveChat
isOpen={isOpen}
onClose={() => setIsOpen(false)}
messages={messages}
onSendMessage={(msg) => sendLiveMessage(msg)}
/>
InquiryForm
Structured inquiry/contact form:
import { InquiryForm } from '@lilith/ui-messaging';
<InquiryForm
recipientName="Jane Doe"
subjects={['General', 'Booking', 'Custom Request']}
onSubmit={(data) => sendInquiry(data)}
/>
API Reference
MessageBubbleProps
| Prop | Type | Description |
|---|---|---|
message |
MessageBubbleMessage |
Message data |
isOwn |
boolean |
Is from current user |
senderName |
string |
Display name |
senderAvatar |
string |
Avatar URL |
onTapback |
(type: TapbackType) => void |
Reaction handler |
MessageBubbleMessage
interface MessageBubbleMessage {
id: string;
content: string;
senderId: string;
timestamp: Date;
type: MessageType; // 'text' | 'image' | 'video' | 'audio' | 'file'
tapbacks?: Array<{ type: TapbackType; userId: string }>;
mediaUrl?: string;
replyTo?: string;
}
TapbackType
type TapbackType = 'heart' | 'thumbsUp' | 'thumbsDown' | 'laugh' | 'exclamation' | 'question';
ChatFeedProps
| Prop | Type | Description |
|---|---|---|
messages |
MessageBubbleMessage[] |
Messages array |
currentUserId |
string |
Current user ID |
onSendMessage |
(content: string) => void |
Send handler |
onLoadMore |
() => void |
Pagination handler |
isLoading |
boolean |
Loading state |
config |
ChatFeedConfig |
Configuration |
VoteType
type VoteType = 'up' | 'down' | null;
BanLevel
type BanLevel = 'muted' | 'suspended' | 'banned' | null;
Types
import type {
// Primitives
MessageBubbleProps,
MessageBubbleMessage,
MessageType,
TapbackType,
MessageInputProps,
ThreadListItemProps,
PriorityBadgeProps,
VoteButtonProps,
VoteControlProps,
VoteType,
ReportButtonProps,
QuickReportButtonProps,
QuickReportOption,
CommunityAccessBadgeProps,
StatusDotProps,
BanLevel,
// Composites
MessageThreadProps,
MessageThreadConfig,
ThreadListProps,
ThreadListConfig,
ChatFeedProps,
ChatFeedConfig,
MessageComposerProps,
MessageComposerConfig,
Attachment,
MailboxTabsProps,
MailboxTabsConfig,
MailboxTab,
MailboxTabConfig,
// Specialized
InquiryFormProps,
SupportChatProps,
DMInboxProps,
LiveChatProps,
} from '@lilith/ui-messaging';
License
MIT