hermes-chat-react 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.d.cts CHANGED
@@ -1,9 +1,222 @@
1
- import { HermesClient, Message, SendMessageInput, Room, CreateDirectRoomInput, CreateGroupRoomInput, Reaction, UploadResult, HermesUser } from './index.cjs';
2
- export { ConnectResponse, ConnectionStatus, DeliveryStatus, HermesConfig, HermesEvents, LastSeenEvent, MessageHistoryResult, MessageType, PresenceEvent, ReactionEvent, ReceiptEvent, RoomType, TypingEvent } from './index.cjs';
3
- import React from 'react';
1
+ import { HermesClient, HermesUser, Room as Room$1, Message as Message$1, SendMessageInput, DeliveryStatus, CreateDirectRoomInput, CreateGroupRoomInput, Reaction, UploadResult } from './index.cjs';
2
+ export { ConnectResponse, ConnectionStatus, HermesConfig, HermesEvents, LastSeenEvent, MessageHistoryResult, MessageType, PresenceEvent, ReactionEvent, ReceiptEvent, RoomType, TypingEvent } from './index.cjs';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import React, { PropsWithChildren } from 'react';
5
+
6
+ type CustomClasses = Partial<Record<"chat" | "roomList" | "room" | "messageList" | "message" | "thread" | "window", string>>;
7
+ interface ChatContextValue {
8
+ /** The HermesClient instance powering the SDK */
9
+ client: HermesClient;
10
+ /** The currently connected user */
11
+ currentUser: HermesUser | null;
12
+ /** Visual theme identifier */
13
+ theme: string;
14
+ /** The currently active room */
15
+ activeRoom?: Room$1;
16
+ /** Set the active room */
17
+ setActiveRoom: (room?: Room$1) => void;
18
+ /** Open mobile navigation */
19
+ openMobileNav: () => void;
20
+ /** Close mobile navigation */
21
+ closeMobileNav: () => void;
22
+ /** Whether mobile nav is open */
23
+ navOpen: boolean;
24
+ /** Custom CSS class overrides for main SDK containers */
25
+ customClasses?: CustomClasses;
26
+ }
27
+ declare const ChatContext: React.Context<ChatContextValue | undefined>;
28
+ declare const ChatProvider: ({ children, value, }: PropsWithChildren<{
29
+ value: ChatContextValue;
30
+ }>) => react_jsx_runtime.JSX.Element;
31
+ /**
32
+ * Access the ChatContext. Must be used within a `<Chat>` component.
33
+ */
34
+ declare const useChatContext: (componentName?: string) => ChatContextValue;
35
+
36
+ interface RoomStateContextValue {
37
+ /** The Room object for this context */
38
+ room: Room$1;
39
+ /** Messages in the current room */
40
+ messages: Message$1[];
41
+ /** Whether messages are initially loading */
42
+ loading: boolean;
43
+ /** Whether older messages are being loaded */
44
+ loadingMore: boolean;
45
+ /** Whether there are more messages to load */
46
+ hasMore: boolean;
47
+ /** Error during message fetching */
48
+ error: string | null;
49
+ /** Members of the room */
50
+ members: string[];
51
+ /** The active thread parent message (null if no thread open) */
52
+ thread: Message$1 | null;
53
+ /** Messages within the active thread */
54
+ threadMessages: Message$1[];
55
+ /** Whether the thread has more messages to load */
56
+ threadHasMore: boolean;
57
+ /** Whether thread is loading more messages */
58
+ threadLoadingMore: boolean;
59
+ /** Pinned messages in the room */
60
+ pinnedMessages: Message$1[];
61
+ }
62
+ declare const RoomStateContext: React.Context<RoomStateContextValue | undefined>;
63
+ declare const RoomStateProvider: ({ children, value, }: PropsWithChildren<{
64
+ value: RoomStateContextValue;
65
+ }>) => react_jsx_runtime.JSX.Element;
66
+ /**
67
+ * Access the RoomStateContext. Must be used within a `<Room>` component.
68
+ */
69
+ declare const useRoomStateContext: (componentName?: string) => RoomStateContextValue;
70
+
71
+ interface RoomActionContextValue {
72
+ /** Send a message to the current room */
73
+ sendMessage: (input: Omit<SendMessageInput, "roomId">) => Promise<Message$1>;
74
+ /** Edit a message */
75
+ editMessage: (messageId: string, text: string) => Promise<Message$1>;
76
+ /** Delete a message */
77
+ deleteMessage: (messageId: string) => Promise<void>;
78
+ /** Add a reaction to a message */
79
+ addReaction: (messageId: string, emoji: string) => Promise<void>;
80
+ /** Load older messages */
81
+ loadMore: () => Promise<void>;
82
+ /** Mark room as seen */
83
+ markRead: (lastMessageId: string) => Promise<void>;
84
+ /** Open a thread for a specific message */
85
+ openThread: (message: Message$1) => void;
86
+ /** Close the currently open thread */
87
+ closeThread: () => void;
88
+ /** Load more thread replies */
89
+ loadMoreThread: () => Promise<void>;
90
+ }
91
+ declare const RoomActionContext: React.Context<RoomActionContextValue | undefined>;
92
+ declare const RoomActionProvider: ({ children, value, }: PropsWithChildren<{
93
+ value: RoomActionContextValue;
94
+ }>) => react_jsx_runtime.JSX.Element;
95
+ /**
96
+ * Access the RoomActionContext. Must be used within a `<Room>` component.
97
+ */
98
+ declare const useRoomActionContext: (componentName?: string) => RoomActionContextValue;
99
+
100
+ type GroupStyle = "top" | "middle" | "bottom" | "single";
101
+ interface MessageContextValue {
102
+ /** The message object */
103
+ message: Message$1;
104
+ /** Whether actions (edit, delete, flag, etc.) are enabled */
105
+ actionsEnabled: boolean;
106
+ /** Whether this message belongs to the current user */
107
+ isMyMessage: boolean;
108
+ /** Handle editing the message */
109
+ handleEdit: (text: string) => Promise<void>;
110
+ /** Handle deleting the message */
111
+ handleDelete: () => Promise<void>;
112
+ /** Handle adding a reaction */
113
+ handleReaction: (emoji: string) => Promise<void>;
114
+ /** Handle replying (inline quote) */
115
+ handleReply: () => void;
116
+ /** Handle opening a thread */
117
+ handleOpenThread: () => void;
118
+ /** Message delivery status */
119
+ deliveryStatus: DeliveryStatus;
120
+ /** Users who have seen this message */
121
+ readBy: string[];
122
+ /** Group style for visual grouping of consecutive messages from the same sender */
123
+ groupStyle: GroupStyle;
124
+ /** Whether this message is highlighted (e.g. jump-to-message) */
125
+ highlighted?: boolean;
126
+ /** Whether this message is in a thread list */
127
+ threadList?: boolean;
128
+ /** Custom date formatter */
129
+ formatDate?: (date: Date) => string;
130
+ }
131
+ declare const MessageContext: React.Context<MessageContextValue | undefined>;
132
+ declare const MessageProvider: ({ children, value, }: PropsWithChildren<{
133
+ value: MessageContextValue;
134
+ }>) => react_jsx_runtime.JSX.Element;
135
+ /**
136
+ * Access the MessageContext. Must be used within a `<Message>` component.
137
+ */
138
+ declare const useMessageContext: (componentName?: string) => MessageContextValue;
139
+
140
+ /**
141
+ * ComponentContext allows developers to override any internal UI component
142
+ * with their own implementation. This is the Inversion of Control (IoC) pattern
143
+ * used by Stream Chat React.
144
+ *
145
+ * Usage:
146
+ * ```tsx
147
+ * <Room roomId={id} Avatar={MyCustomAvatar} Message={MyCustomMessage}>
148
+ * <MessageList />
149
+ * </Room>
150
+ * ```
151
+ */
152
+ interface ComponentContextValue {
153
+ /** Custom Avatar component */
154
+ Avatar?: React.ComponentType<any>;
155
+ /** Custom Message bubble component */
156
+ Message?: React.ComponentType<any>;
157
+ /** Custom MessageStatus component (delivery indicators) */
158
+ MessageStatus?: React.ComponentType<any>;
159
+ /** Custom MessageActions component (hover toolbar) */
160
+ MessageActions?: React.ComponentType<any>;
161
+ /** Custom DateSeparator component */
162
+ DateSeparator?: React.ComponentType<any>;
163
+ /** Custom EmptyStateIndicator component */
164
+ EmptyStateIndicator?: React.ComponentType<any>;
165
+ /** Custom LoadingIndicator component */
166
+ LoadingIndicator?: React.ComponentType<any>;
167
+ /** Custom LoadingErrorIndicator component */
168
+ LoadingErrorIndicator?: React.ComponentType<any>;
169
+ /** Custom ReactionPicker component */
170
+ ReactionPicker?: React.ComponentType<any>;
171
+ /** Custom TypingIndicator component */
172
+ TypingIndicator?: React.ComponentType<any>;
173
+ /** Custom MediaMessage (attachment renderer) component */
174
+ MediaMessage?: React.ComponentType<any>;
175
+ /** Custom ThreadHeader component */
176
+ ThreadHeader?: React.ComponentType<any>;
177
+ /** Custom Modal component */
178
+ Modal?: React.ComponentType<any>;
179
+ /** Custom ChatInput component */
180
+ ChatInput?: React.ComponentType<any>;
181
+ /** Custom RoomListItem component */
182
+ RoomListItem?: React.ComponentType<any>;
183
+ /** Custom Search component */
184
+ Search?: React.ComponentType<any>;
185
+ /** Custom OnlineBadge component */
186
+ OnlineBadge?: React.ComponentType<any>;
187
+ }
188
+ declare const ComponentContext: React.Context<ComponentContextValue>;
189
+ declare const ComponentProvider: ({ children, value, }: PropsWithChildren<{
190
+ value: Partial<ComponentContextValue>;
191
+ }>) => react_jsx_runtime.JSX.Element;
192
+ /**
193
+ * Access component overrides. Returns an empty object if no overrides are set.
194
+ */
195
+ declare const useComponentContext: (_componentName?: string) => ComponentContextValue;
196
+
197
+ interface TypingContextValue {
198
+ /** Map of userId → displayName for users currently typing */
199
+ typingUsers: Map<string, string>;
200
+ /** Human-readable typing indicator text (e.g. "Alice is typing...") */
201
+ typingText: string | null;
202
+ /** Whether anyone is currently typing */
203
+ isAnyoneTyping: boolean;
204
+ /** Emit a typing start event */
205
+ startTyping: () => void;
206
+ /** Emit a typing stop event */
207
+ stopTyping: () => void;
208
+ }
209
+ declare const TypingContext: React.Context<TypingContextValue | undefined>;
210
+ declare const TypingProvider: ({ children, value, }: PropsWithChildren<{
211
+ value: TypingContextValue;
212
+ }>) => react_jsx_runtime.JSX.Element;
213
+ /**
214
+ * Access typing state for the current room. Must be within a `<Room>` component.
215
+ */
216
+ declare const useTypingContext: (componentName?: string) => TypingContextValue;
4
217
 
5
218
  declare const useMessages: (client: HermesClient, roomId: string | null) => {
6
- messages: Message[];
219
+ messages: Message$1[];
7
220
  loading: boolean;
8
221
  loadingMore: boolean;
9
222
  hasMore: boolean;
@@ -12,19 +225,19 @@ declare const useMessages: (client: HermesClient, roomId: string | null) => {
12
225
  userId: string;
13
226
  displayName: string;
14
227
  }[];
15
- sendMessage: (input: Omit<SendMessageInput, "roomId">) => Promise<Message>;
16
- editMessage: (messageId: string, text: string) => Promise<Message>;
228
+ sendMessage: (input: Omit<SendMessageInput, "roomId">) => Promise<Message$1>;
229
+ editMessage: (messageId: string, text: string) => Promise<Message$1>;
17
230
  deleteMessage: (messageId: string) => Promise<void>;
18
231
  addReaction: (messageId: string, emoji: string) => Promise<void>;
19
232
  loadMore: () => Promise<void>;
20
233
  };
21
234
 
22
235
  declare const useRooms: (client: HermesClient) => {
23
- rooms: Room[];
236
+ rooms: Room$1[];
24
237
  loading: boolean;
25
238
  error: string | null;
26
- createDirect: (input: CreateDirectRoomInput) => Promise<Room>;
27
- createGroup: (input: CreateGroupRoomInput) => Promise<Room>;
239
+ createDirect: (input: CreateDirectRoomInput) => Promise<Room$1>;
240
+ createGroup: (input: CreateGroupRoomInput) => Promise<Room$1>;
28
241
  deleteRoom: (roomId: string) => Promise<void>;
29
242
  addMember: (roomId: string, userId: string) => Promise<void>;
30
243
  removeMember: (roomId: string, userId: string) => Promise<void>;
@@ -60,62 +273,216 @@ declare const useReactions: (client: HermesClient, roomId: string | null) => {
60
273
 
61
274
  declare const useUpload: (client: HermesClient) => {
62
275
  upload: (file: File) => Promise<UploadResult | null>;
63
- sendFile: (roomId: string, file: File, replyTo?: string) => Promise<Message | null>;
276
+ sendFile: (roomId: string, file: File, replyTo?: string) => Promise<Message$1 | null>;
64
277
  validate: (file: File, maxMb?: number) => string | null;
65
278
  uploading: boolean;
66
279
  error: string | null;
67
280
  lastUpload: UploadResult | null;
68
281
  };
69
282
 
283
+ interface ChatProps {
284
+ /** The HermesClient instance */
285
+ client: HermesClient;
286
+ /** Visual theme identifier, defaults to "light" */
287
+ theme?: string;
288
+ /** Custom CSS class overrides */
289
+ customClasses?: CustomClasses;
290
+ /** Initial mobile nav state */
291
+ initialNavOpen?: boolean;
292
+ }
293
+ /**
294
+ * Root wrapper component for the Hermes Chat SDK.
295
+ *
296
+ * Provides `ChatContext` to all child components. Place this at the top
297
+ * of your chat UI tree.
298
+ *
299
+ * @example
300
+ * ```tsx
301
+ * const client = new HermesClient({ endpoint, apiKey, secret, userId, displayName });
302
+ * await client.connect();
303
+ *
304
+ * <Chat client={client} theme="dark">
305
+ * <RoomList />
306
+ * <Room roomId={activeRoomId}>
307
+ * <Window>
308
+ * <MessageList />
309
+ * <ChatInput />
310
+ * </Window>
311
+ * </Room>
312
+ * </Chat>
313
+ * ```
314
+ */
315
+ declare const Chat: ({ client, theme, customClasses, initialNavOpen, children, }: PropsWithChildren<ChatProps>) => react_jsx_runtime.JSX.Element;
316
+
317
+ interface RoomProps extends Partial<ComponentContextValue> {
318
+ /** The room ID to load */
319
+ roomId: string;
320
+ }
321
+ /**
322
+ * Wraps a single room/channel, initialising all per-room state and making it
323
+ * available to children via `RoomStateContext`, `RoomActionContext`, and
324
+ * `TypingContext`.
325
+ *
326
+ * @example
327
+ * ```tsx
328
+ * <Room roomId="abc123">
329
+ * <Window>
330
+ * <MessageList />
331
+ * <ChatInput />
332
+ * </Window>
333
+ * <Thread />
334
+ * </Room>
335
+ * ```
336
+ */
337
+ declare const Room: ({ roomId, children, Avatar, Message: MessageOverride, MessageStatus, MessageActions, DateSeparator, EmptyStateIndicator, LoadingIndicator, LoadingErrorIndicator, ReactionPicker, TypingIndicator, MediaMessage, ThreadHeader, Modal, ChatInput, RoomListItem, Search, OnlineBadge, }: PropsWithChildren<RoomProps>) => react_jsx_runtime.JSX.Element;
338
+
339
+ interface WindowProps {
340
+ /** Additional class name */
341
+ className?: string;
342
+ }
343
+ /**
344
+ * Layout wrapper for the message area. Renders a flex-column container
345
+ * that holds `<MessageList />` and `<ChatInput />`.
346
+ *
347
+ * @example
348
+ * ```tsx
349
+ * <Window>
350
+ * <MessageList />
351
+ * <ChatInput />
352
+ * </Window>
353
+ * ```
354
+ */
355
+ declare const Window: ({ className, children, }: PropsWithChildren<WindowProps>) => react_jsx_runtime.JSX.Element;
356
+
70
357
  interface MessageListProps {
71
- messages: Message[];
72
- currentUser: HermesUser;
358
+ /** Messages array (optional if inside <Room>) */
359
+ messages?: Message$1[];
360
+ /** Current user (optional if inside <Chat>) */
361
+ currentUser?: HermesUser;
362
+ /** Loading state */
73
363
  loading?: boolean;
364
+ /** Loading more state */
74
365
  loadingMore?: boolean;
366
+ /** Has more messages */
75
367
  hasMore?: boolean;
368
+ /** Load more callback */
76
369
  onLoadMore?: () => void;
370
+ /** Edit callback */
77
371
  onEdit?: (messageId: string, text: string) => void;
372
+ /** Delete callback */
78
373
  onDelete?: (messageId: string) => void;
374
+ /** Reaction callback */
79
375
  onReact?: (messageId: string, emoji: string) => void;
80
- onReply?: (message: Message) => void;
81
- renderMessage?: (message: Message, isOwn: boolean) => React.ReactNode;
376
+ /** Reply (quote) callback */
377
+ onReply?: (message: Message$1) => void;
378
+ /** Thread open callback */
379
+ onOpenThread?: (message: Message$1) => void;
380
+ /** Custom message renderer (full override) */
381
+ renderMessage?: (message: Message$1, isOwn: boolean) => React.ReactNode;
382
+ /** Custom avatar renderer */
82
383
  renderAvatar?: (senderId: string) => React.ReactNode;
384
+ /** Additional class name */
83
385
  className?: string;
386
+ /** Auto-scroll to bottom on new messages */
84
387
  autoScroll?: boolean;
388
+ /** Typing users (optional if inside <Room>) */
85
389
  typingUsers?: {
86
390
  userId: string;
87
391
  displayName: string;
88
392
  }[];
393
+ /** Whether to show date separators between days */
394
+ disableDateSeparator?: boolean;
395
+ /** Typing indicator text (optional if inside <Room>) */
396
+ typingText?: string | null;
89
397
  }
398
+ /**
399
+ * Displays a scrollable list of messages with date separators,
400
+ * typing indicators, and infinite scroll.
401
+ *
402
+ * **Context-aware:** When used inside `<Room>`, reads messages, loading state,
403
+ * and typing state automatically. When used standalone, accepts all data via props.
404
+ *
405
+ * @example
406
+ * ```tsx
407
+ * // Context-aware (recommended)
408
+ * <Room roomId={id}>
409
+ * <Window>
410
+ * <MessageList />
411
+ * <ChatInput />
412
+ * </Window>
413
+ * </Room>
414
+ *
415
+ * // Standalone (prop-driven)
416
+ * <MessageList
417
+ * messages={messages}
418
+ * currentUser={user}
419
+ * onEdit={handleEdit}
420
+ * onDelete={handleDelete}
421
+ * />
422
+ * ```
423
+ */
90
424
  declare const MessageList: React.FC<MessageListProps>;
91
425
 
92
426
  interface ChatInputProps {
93
- onSendText: (text: string) => Promise<void> | void;
427
+ /** Send text callback (optional if inside <Room>) */
428
+ onSendText?: (text: string) => Promise<void> | void;
429
+ /** Send file callback */
94
430
  onSendFile?: (file: File) => Promise<void> | void;
431
+ /** Typing start callback (optional if inside <Room>) */
95
432
  onTypingStart?: () => void;
433
+ /** Typing stop callback (optional if inside <Room>) */
96
434
  onTypingStop?: () => void;
97
- replyingTo?: Message | null;
435
+ /** Message being replied to */
436
+ replyingTo?: Message$1 | null;
437
+ /** Cancel reply callback */
98
438
  onCancelReply?: () => void;
439
+ /** Whether input is disabled */
99
440
  disabled?: boolean;
441
+ /** Placeholder text */
100
442
  placeholder?: string;
443
+ /** Maximum character length */
101
444
  maxLength?: number;
445
+ /** Additional class name */
102
446
  className?: string;
447
+ /** Input element class name */
103
448
  inputClassName?: string;
449
+ /** Custom attach icon renderer */
104
450
  renderAttachIcon?: () => React.ReactNode;
451
+ /** Custom send icon renderer */
105
452
  renderSendIcon?: () => React.ReactNode;
106
453
  }
454
+ /**
455
+ * Message composer with text input, file upload, and reply preview.
456
+ *
457
+ * **Context-aware:** When used inside `<Room>`, automatically binds to
458
+ * `sendMessage` and typing events. When used standalone, accepts all callbacks via props.
459
+ *
460
+ * @example
461
+ * ```tsx
462
+ * // Context-aware
463
+ * <Room roomId={id}>
464
+ * <Window>
465
+ * <MessageList />
466
+ * <ChatInput />
467
+ * </Window>
468
+ * </Room>
469
+ *
470
+ * // Standalone
471
+ * <ChatInput onSendText={handleSend} onSendFile={handleFile} />
472
+ * ```
473
+ */
107
474
  declare const ChatInput: React.FC<ChatInputProps>;
108
475
 
109
476
  interface RoomListProps {
110
- rooms: Room[];
477
+ rooms: Room$1[];
111
478
  activeRoomId?: string | null;
112
479
  currentUserId: string;
113
480
  loading?: boolean;
114
- onSelectRoom: (room: Room) => void;
481
+ onSelectRoom: (room: Room$1) => void;
115
482
  onCreateDirect?: () => void;
116
483
  onCreateGroup?: () => void;
117
- renderRoomItem?: (room: Room, isActive: boolean) => React.ReactNode;
118
- renderAvatar?: (room: Room) => React.ReactNode;
484
+ renderRoomItem?: (room: Room$1, isActive: boolean) => React.ReactNode;
485
+ renderAvatar?: (room: Room$1) => React.ReactNode;
119
486
  renderEmpty?: () => React.ReactNode;
120
487
  className?: string;
121
488
  itemClassName?: string;
@@ -146,10 +513,245 @@ interface ReactionPickerProps {
146
513
  declare const ReactionPicker: React.FC<ReactionPickerProps>;
147
514
 
148
515
  interface MediaMessageProps {
149
- message: Message;
516
+ message: Message$1;
150
517
  className?: string;
151
518
  maxWidth?: number | string;
152
519
  }
153
520
  declare const MediaMessage: React.FC<MediaMessageProps>;
154
521
 
155
- export { ChatInput, CreateDirectRoomInput, CreateGroupRoomInput, HermesClient, HermesUser, MediaMessage, Message, MessageList, OnlineBadge, Reaction, ReactionPicker, Room, RoomList, SendMessageInput, TypingIndicator, UploadResult, useMessages, usePresence, useReactions, useReadReceipts, useRooms, useTyping, useUpload };
522
+ interface MessageProps {
523
+ message: Message$1;
524
+ isOwn: boolean;
525
+ /** Callbacks (optional — will fall back to context if available) */
526
+ onEdit?: (messageId: string, text: string) => void;
527
+ onDelete?: (messageId: string) => void;
528
+ onReact?: (messageId: string, emoji: string) => void;
529
+ onReply?: (message: Message$1) => void;
530
+ onOpenThread?: (message: Message$1) => void;
531
+ onPin?: (message: Message$1) => void;
532
+ /** Avatar customization */
533
+ renderAvatar?: (senderId: string) => React.ReactNode;
534
+ /** Sender display name (for avatar fallback) */
535
+ senderName?: string;
536
+ /** Sender avatar URL */
537
+ senderImage?: string;
538
+ /** Group style for visual grouping */
539
+ groupStyle?: "top" | "middle" | "bottom" | "single";
540
+ /** Additional class name */
541
+ className?: string;
542
+ /** Whether to show the avatar */
543
+ showAvatar?: boolean;
544
+ }
545
+ /**
546
+ * A single message bubble with avatar, content, reactions, delivery status,
547
+ * and action toolbar. This is the primary message rendering component.
548
+ *
549
+ * Can be used standalone or within a `<MessageList>`.
550
+ */
551
+ declare const Message: React.FC<MessageProps>;
552
+
553
+ interface MessageStatusProps {
554
+ /** The delivery status of the message */
555
+ status: DeliveryStatus;
556
+ /** Number of users who have seen the message */
557
+ seenCount?: number;
558
+ /** Whether this message was sent by the current user */
559
+ isMyMessage?: boolean;
560
+ /** Additional class name */
561
+ className?: string;
562
+ }
563
+ /**
564
+ * Renders delivery status indicators: ✓ (sent), ✓✓ (delivered), ✓✓ blue (seen).
565
+ * Only shown for the current user's own messages.
566
+ */
567
+ declare const MessageStatus: React.FC<MessageStatusProps>;
568
+
569
+ interface MessageActionsProps {
570
+ /** Whether the current user owns the message */
571
+ isOwn: boolean;
572
+ /** Whether the message is a text message (enables edit) */
573
+ isText: boolean;
574
+ /** Whether the message has a thread */
575
+ hasThread?: boolean;
576
+ /** Reply count for threads */
577
+ replyCount?: number;
578
+ /** Callbacks */
579
+ onReact?: () => void;
580
+ onReply?: () => void;
581
+ onThread?: () => void;
582
+ onEdit?: () => void;
583
+ onDelete?: () => void;
584
+ onPin?: () => void;
585
+ /** Additional class name */
586
+ className?: string;
587
+ }
588
+ /**
589
+ * Hover toolbar for message actions: React, Reply, Thread, Edit, Delete, Pin.
590
+ */
591
+ declare const MessageActions: React.FC<MessageActionsProps>;
592
+
593
+ interface ThreadProps {
594
+ /** Additional class name */
595
+ className?: string;
596
+ /** Whether to auto-focus the composer when thread opens */
597
+ autoFocus?: boolean;
598
+ }
599
+ /**
600
+ * Thread component renders a parent message with a list of replies
601
+ * and a composer for new replies. It reads state from `RoomStateContext`
602
+ * and actions from `RoomActionContext`.
603
+ *
604
+ * @example
605
+ * ```tsx
606
+ * <Room roomId={id}>
607
+ * <Window>
608
+ * <MessageList />
609
+ * <ChatInput />
610
+ * </Window>
611
+ * <Thread />
612
+ * </Room>
613
+ * ```
614
+ */
615
+ declare const Thread: React.FC<ThreadProps>;
616
+
617
+ interface ThreadHeaderProps {
618
+ /** The parent message of the thread */
619
+ thread: Message$1;
620
+ /** Close the thread panel */
621
+ onClose: () => void;
622
+ /** Additional class name */
623
+ className?: string;
624
+ }
625
+ /**
626
+ * Header for the thread panel showing parent message preview and close button.
627
+ */
628
+ declare const ThreadHeader: React.FC<ThreadHeaderProps>;
629
+
630
+ interface AvatarProps {
631
+ /** Image URL */
632
+ image?: string;
633
+ /** User's display name (used for fallback initials) */
634
+ name?: string;
635
+ /** Size in pixels */
636
+ size?: number;
637
+ /** Shape of the avatar */
638
+ shape?: "circle" | "square" | "rounded";
639
+ /** Additional class name */
640
+ className?: string;
641
+ /** Whether the user is online */
642
+ online?: boolean;
643
+ }
644
+ /**
645
+ * Displays a user avatar with fallback initials and optional online indicator.
646
+ *
647
+ * @example
648
+ * ```tsx
649
+ * <Avatar image={user.avatar} name={user.displayName} size={40} online />
650
+ * ```
651
+ */
652
+ declare const Avatar: React.FC<AvatarProps>;
653
+
654
+ interface DateSeparatorProps {
655
+ /** The date to display */
656
+ date: Date;
657
+ /** Custom date formatter */
658
+ formatDate?: (date: Date) => string;
659
+ /** Additional class name */
660
+ className?: string;
661
+ }
662
+ /**
663
+ * Renders a date divider between message groups from different days.
664
+ *
665
+ * @example
666
+ * ```tsx
667
+ * <DateSeparator date={new Date("2024-01-15")} />
668
+ * ```
669
+ */
670
+ declare const DateSeparator: React.FC<DateSeparatorProps>;
671
+
672
+ interface LoadingIndicatorProps {
673
+ /** Size of the spinner in pixels */
674
+ size?: number;
675
+ /** Spinner color */
676
+ color?: string;
677
+ /** Loading text */
678
+ text?: string;
679
+ /** Additional class name */
680
+ className?: string;
681
+ }
682
+ /**
683
+ * A simple animated loading spinner.
684
+ */
685
+ declare const LoadingIndicator: React.FC<LoadingIndicatorProps>;
686
+ interface LoadingErrorIndicatorProps {
687
+ /** The error to display */
688
+ error?: Error | string | null;
689
+ /** Retry callback */
690
+ onRetry?: () => void;
691
+ /** Additional class name */
692
+ className?: string;
693
+ }
694
+ /**
695
+ * Displays an error state with an optional retry button.
696
+ */
697
+ declare const LoadingErrorIndicator: React.FC<LoadingErrorIndicatorProps>;
698
+
699
+ interface EmptyStateIndicatorProps {
700
+ /** The type of list that is empty */
701
+ listType?: "message" | "room" | "thread" | "search";
702
+ /** Custom text to display */
703
+ text?: string;
704
+ /** Additional class name */
705
+ className?: string;
706
+ }
707
+ /**
708
+ * Shown when a list (messages, rooms, threads, search results) is empty.
709
+ *
710
+ * @example
711
+ * ```tsx
712
+ * <EmptyStateIndicator listType="message" />
713
+ * ```
714
+ */
715
+ declare const EmptyStateIndicator: React.FC<EmptyStateIndicatorProps>;
716
+
717
+ interface ModalProps {
718
+ /** Whether the modal is open */
719
+ open: boolean;
720
+ /** Close handler */
721
+ onClose: () => void;
722
+ /** Additional class name */
723
+ className?: string;
724
+ }
725
+ /**
726
+ * Overlay modal for image previews, confirmations, and dialogs.
727
+ *
728
+ * @example
729
+ * ```tsx
730
+ * <Modal open={showPreview} onClose={() => setShowPreview(false)}>
731
+ * <img src="..." alt="preview" />
732
+ * </Modal>
733
+ * ```
734
+ */
735
+ declare const Modal: React.FC<PropsWithChildren<ModalProps>>;
736
+
737
+ interface SearchProps {
738
+ /** Messages to search through */
739
+ messages?: Message$1[];
740
+ /** Callback when a result is selected */
741
+ onSelectResult?: (message: Message$1) => void;
742
+ /** Placeholder text */
743
+ placeholder?: string;
744
+ /** Additional class name */
745
+ className?: string;
746
+ }
747
+ /**
748
+ * Client-side search component that filters messages.
749
+ *
750
+ * @example
751
+ * ```tsx
752
+ * <Search messages={messages} onSelectResult={msg => jumpTo(msg._id)} />
753
+ * ```
754
+ */
755
+ declare const Search: React.FC<SearchProps>;
756
+
757
+ export { Avatar, type AvatarProps, Chat, ChatContext, type ChatContextValue, ChatInput, type ChatProps, ChatProvider, ComponentContext, type ComponentContextValue, ComponentProvider, CreateDirectRoomInput, CreateGroupRoomInput, type CustomClasses, DateSeparator, type DateSeparatorProps, DeliveryStatus, EmptyStateIndicator, type EmptyStateIndicatorProps, type GroupStyle, HermesClient, HermesUser, LoadingErrorIndicator, type LoadingErrorIndicatorProps, LoadingIndicator, type LoadingIndicatorProps, MediaMessage, Message, MessageActions, type MessageActionsProps, MessageContext, type MessageContextValue, MessageList, type MessageProps, MessageProvider, MessageStatus, type MessageStatusProps, Modal, type ModalProps, OnlineBadge, Reaction, ReactionPicker, Room, RoomActionContext, type RoomActionContextValue, RoomActionProvider, RoomList, type RoomProps, RoomStateContext, type RoomStateContextValue, RoomStateProvider, Search, type SearchProps, SendMessageInput, Thread, ThreadHeader, type ThreadHeaderProps, type ThreadProps, TypingContext, type TypingContextValue, TypingIndicator, TypingProvider, UploadResult, Window, type WindowProps, useChatContext, useComponentContext, useMessageContext, useMessages, usePresence, useReactions, useReadReceipts, useRoomActionContext, useRoomStateContext, useRooms, useTyping, useTypingContext, useUpload };