@xcelsior/ui-chat 1.0.4 → 1.0.5

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.
@@ -0,0 +1,5 @@
1
+
2
+ > @xcelsior/ui-chat@1.0.0 lint /Users/tuannguyen/Work/xcelsior-packages/packages/ui/ui-chat
3
+ > biome check .
4
+
5
+ Checked 24 files in 17ms. No fixes applied.
@@ -0,0 +1,269 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface IUser {
4
+ name: string;
5
+ email: string;
6
+ avatar?: string;
7
+ type: 'customer' | 'agent';
8
+ status?: 'online' | 'offline' | 'away' | 'busy';
9
+ }
10
+ type MessageType = 'text' | 'image' | 'file' | 'system';
11
+ type MessageStatus = 'sent' | 'delivered' | 'read';
12
+ interface IMessage {
13
+ id: string;
14
+ conversationId: string;
15
+ senderId: string;
16
+ senderType: 'customer' | 'agent' | 'system';
17
+ content: string;
18
+ messageType: MessageType;
19
+ createdAt: string;
20
+ status: MessageStatus;
21
+ metadata?: Record<string, unknown>;
22
+ }
23
+ type ConversationStatus = 'open' | 'pending' | 'closed' | 'archived';
24
+ type ConversationPriority = 'low' | 'medium' | 'high' | 'urgent';
25
+ type ConversationChannel = 'web' | 'mobile' | 'email';
26
+ interface IConversation {
27
+ id: string;
28
+ customerId: string;
29
+ assignedAgentId?: string;
30
+ status: ConversationStatus;
31
+ priority: ConversationPriority;
32
+ subject?: string;
33
+ channel: ConversationChannel;
34
+ tags?: string[];
35
+ createdAt: string;
36
+ updatedAt: string;
37
+ closedAt?: string;
38
+ lastMessageAt?: string;
39
+ messageCount?: number;
40
+ unreadCount?: number;
41
+ satisfaction?: 1 | 2 | 3 | 4 | 5;
42
+ metadata?: Record<string, unknown>;
43
+ }
44
+ interface IWebSocketMessage {
45
+ type: 'message' | 'typing' | 'read' | 'connected' | 'error' | 'system';
46
+ data: any;
47
+ }
48
+ interface ISendMessageData {
49
+ conversationId: string;
50
+ content: string;
51
+ messageType?: MessageType;
52
+ }
53
+ interface ITypingData {
54
+ conversationId: string;
55
+ isTyping: boolean;
56
+ }
57
+ interface IReadMessageData {
58
+ messageId: string;
59
+ conversationId: string;
60
+ }
61
+ interface IFileUploadConfig {
62
+ uploadUrl: string;
63
+ maxFileSize?: number;
64
+ allowedTypes?: string[];
65
+ headers?: Record<string, string>;
66
+ }
67
+ interface IUploadedFile {
68
+ url: string;
69
+ name: string;
70
+ size: number;
71
+ type: string;
72
+ markdown?: string;
73
+ }
74
+ interface IChatConfig {
75
+ websocketUrl: string;
76
+ conversationId?: string;
77
+ apiKey: string;
78
+ currentUser: IUser;
79
+ fileUpload?: IFileUploadConfig;
80
+ httpApiUrl?: string;
81
+ headers?: Record<string, string>;
82
+ enableEmoji?: boolean;
83
+ enableFileUpload?: boolean;
84
+ enableTypingIndicator?: boolean;
85
+ enableReadReceipts?: boolean;
86
+ /**
87
+ * For agents, set this to true to disable creating a WebSocket connection in the chat widget.
88
+ * Agents should have a global WebSocket connection instead.
89
+ * @default false
90
+ */
91
+ disableWebSocket?: boolean;
92
+ onMessageSent?: (message: IMessage) => void;
93
+ onMessageReceived?: (message: IMessage) => void;
94
+ onConversationChange?: (conversation: IConversation) => void;
95
+ onConnectionChange?: (connected: boolean) => void;
96
+ onError?: (error: Error) => void;
97
+ toast?: {
98
+ success: (message: string) => void;
99
+ error: (message: string) => void;
100
+ info: (message: string) => void;
101
+ };
102
+ }
103
+ interface IApiResponse<T> {
104
+ success: boolean;
105
+ data?: T;
106
+ error?: {
107
+ code: string;
108
+ message: string;
109
+ };
110
+ pagination?: {
111
+ nextPageToken?: string;
112
+ };
113
+ }
114
+
115
+ interface ChatWidgetProps {
116
+ config: IChatConfig;
117
+ className?: string;
118
+ /**
119
+ * Variant of the chat widget:
120
+ * - 'popover': Fixed positioned floating widget (default)
121
+ * - 'fullPage': Full page layout that fills the container
122
+ */
123
+ variant?: 'popover' | 'fullPage';
124
+ /**
125
+ * External WebSocket connection (for agents with global connection)
126
+ */
127
+ externalWebSocket?: WebSocket | null;
128
+ }
129
+ declare function ChatWidget({ config, className, variant, externalWebSocket, }: ChatWidgetProps): react_jsx_runtime.JSX.Element | null;
130
+
131
+ interface ChatWidgetWrapperProps {
132
+ /**
133
+ * Base configuration for the chat widget (without user info and conversationId)
134
+ */
135
+ config: Omit<IChatConfig, 'currentUser' | 'conversationId' | 'userId'> & {
136
+ currentUser?: Partial<IUser>;
137
+ conversationId?: string;
138
+ };
139
+ /**
140
+ * Custom className for the wrapper
141
+ */
142
+ className?: string;
143
+ /**
144
+ * Storage key prefix for persisting user data
145
+ * Defaults to 'xcelsior_chat'
146
+ */
147
+ storageKeyPrefix?: string;
148
+ /**
149
+ * Callback when user submits the pre-chat form
150
+ */
151
+ onPreChatSubmit?: (user: IUser) => void;
152
+ }
153
+ /**
154
+ * Chat component that handles:
155
+ * - Automatic conversation ID generation
156
+ * - Pre-chat form for collecting user information
157
+ * - Session persistence in localStorage
158
+ */
159
+ declare function Chat({ config, className, storageKeyPrefix, onPreChatSubmit, }: ChatWidgetWrapperProps): react_jsx_runtime.JSX.Element | null;
160
+
161
+ interface ChatHeaderProps {
162
+ agent?: IUser;
163
+ onClose?: () => void;
164
+ onMinimize?: () => void;
165
+ }
166
+ declare function ChatHeader({ agent, onClose, onMinimize }: ChatHeaderProps): react_jsx_runtime.JSX.Element;
167
+
168
+ interface UseFileUploadReturn {
169
+ uploadFile: (file: File) => Promise<IUploadedFile | null>;
170
+ isUploading: boolean;
171
+ uploadProgress: number;
172
+ error: Error | null;
173
+ canUpload: boolean;
174
+ }
175
+ declare function useFileUpload(apiKey: string, config?: IFileUploadConfig): UseFileUploadReturn;
176
+
177
+ interface ChatInputProps {
178
+ onSend: (message: string) => void;
179
+ onTyping?: (isTyping: boolean) => void;
180
+ config: IChatConfig;
181
+ fileUpload: UseFileUploadReturn;
182
+ disabled?: boolean;
183
+ }
184
+ declare function ChatInput({ onSend, onTyping, config, fileUpload, disabled, }: ChatInputProps): react_jsx_runtime.JSX.Element;
185
+
186
+ interface MessageItemProps {
187
+ message: IMessage;
188
+ currentUser: IUser;
189
+ showAvatar?: boolean;
190
+ showTimestamp?: boolean;
191
+ }
192
+ declare function MessageItem({ message, currentUser, showAvatar, showTimestamp, }: MessageItemProps): react_jsx_runtime.JSX.Element;
193
+
194
+ interface MessageListProps {
195
+ messages: IMessage[];
196
+ currentUser: IUser;
197
+ isLoading?: boolean;
198
+ isTyping?: boolean;
199
+ typingUser?: string;
200
+ autoScroll?: boolean;
201
+ onLoadMore?: () => void;
202
+ hasMore?: boolean;
203
+ isLoadingMore?: boolean;
204
+ }
205
+ declare function MessageList({ messages, currentUser, isLoading, isTyping, typingUser, autoScroll, onLoadMore, hasMore, isLoadingMore, }: MessageListProps): react_jsx_runtime.JSX.Element;
206
+
207
+ interface TypingIndicatorProps {
208
+ isTyping: boolean;
209
+ userName?: string;
210
+ }
211
+ declare function TypingIndicator({ isTyping, userName }: TypingIndicatorProps): react_jsx_runtime.JSX.Element | null;
212
+
213
+ interface PreChatFormProps {
214
+ onSubmit: (name: string, email: string) => void;
215
+ className?: string;
216
+ initialName?: string;
217
+ initialEmail?: string;
218
+ }
219
+ /**
220
+ * PreChatForm component for collecting user information before starting chat
221
+ */
222
+ declare function PreChatForm({ onSubmit, className, initialName, initialEmail, }: PreChatFormProps): react_jsx_runtime.JSX.Element;
223
+
224
+ interface UseWebSocketReturn {
225
+ isConnected: boolean;
226
+ sendMessage: (action: string, data: any) => void;
227
+ lastMessage: IWebSocketMessage | null;
228
+ error: Error | null;
229
+ reconnect: () => void;
230
+ }
231
+ /**
232
+ * Hook for WebSocket connection in chat widget.
233
+ * Can use an external WebSocket connection (for agents) via the externalWebSocket prop.
234
+ */
235
+ declare function useWebSocket(config: IChatConfig, externalWebSocket?: WebSocket | null): UseWebSocketReturn;
236
+
237
+ interface UseMessagesReturn {
238
+ messages: IMessage[];
239
+ addMessage: (message: IMessage) => void;
240
+ updateMessageStatus: (messageId: string, status: IMessage['status']) => void;
241
+ clearMessages: () => void;
242
+ isLoading: boolean;
243
+ error: Error | null;
244
+ loadMore: () => Promise<void>;
245
+ hasMore: boolean;
246
+ isLoadingMore: boolean;
247
+ }
248
+ declare function useMessages(websocket: UseWebSocketReturn, config: IChatConfig): UseMessagesReturn;
249
+
250
+ interface UseTypingIndicatorReturn {
251
+ isTyping: boolean;
252
+ typingUsers: string[];
253
+ }
254
+ declare function useTypingIndicator(websocket: UseWebSocketReturn): UseTypingIndicatorReturn;
255
+
256
+ interface FetchMessagesParams {
257
+ conversationId: string;
258
+ limit?: number;
259
+ pageToken?: string;
260
+ }
261
+ /**
262
+ * Fetch messages for a conversation from the REST API
263
+ */
264
+ declare function fetchMessages(baseUrl: string, params: FetchMessagesParams, headers?: Record<string, string>): Promise<{
265
+ data: IMessage[];
266
+ nextPageToken: string | undefined;
267
+ }>;
268
+
269
+ export { Chat, ChatHeader, ChatInput, ChatWidget, type ChatWidgetProps, type ConversationChannel, type ConversationPriority, type ConversationStatus, type IApiResponse, type IChatConfig, type IConversation, type IFileUploadConfig, type IMessage, type IReadMessageData, type ISendMessageData, type ITypingData, type IUploadedFile, type IUser, type IWebSocketMessage, MessageItem, MessageList, type MessageStatus, type MessageType, PreChatForm, TypingIndicator, fetchMessages, useFileUpload, useMessages, useTypingIndicator, useWebSocket };
@@ -0,0 +1,269 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface IUser {
4
+ name: string;
5
+ email: string;
6
+ avatar?: string;
7
+ type: 'customer' | 'agent';
8
+ status?: 'online' | 'offline' | 'away' | 'busy';
9
+ }
10
+ type MessageType = 'text' | 'image' | 'file' | 'system';
11
+ type MessageStatus = 'sent' | 'delivered' | 'read';
12
+ interface IMessage {
13
+ id: string;
14
+ conversationId: string;
15
+ senderId: string;
16
+ senderType: 'customer' | 'agent' | 'system';
17
+ content: string;
18
+ messageType: MessageType;
19
+ createdAt: string;
20
+ status: MessageStatus;
21
+ metadata?: Record<string, unknown>;
22
+ }
23
+ type ConversationStatus = 'open' | 'pending' | 'closed' | 'archived';
24
+ type ConversationPriority = 'low' | 'medium' | 'high' | 'urgent';
25
+ type ConversationChannel = 'web' | 'mobile' | 'email';
26
+ interface IConversation {
27
+ id: string;
28
+ customerId: string;
29
+ assignedAgentId?: string;
30
+ status: ConversationStatus;
31
+ priority: ConversationPriority;
32
+ subject?: string;
33
+ channel: ConversationChannel;
34
+ tags?: string[];
35
+ createdAt: string;
36
+ updatedAt: string;
37
+ closedAt?: string;
38
+ lastMessageAt?: string;
39
+ messageCount?: number;
40
+ unreadCount?: number;
41
+ satisfaction?: 1 | 2 | 3 | 4 | 5;
42
+ metadata?: Record<string, unknown>;
43
+ }
44
+ interface IWebSocketMessage {
45
+ type: 'message' | 'typing' | 'read' | 'connected' | 'error' | 'system';
46
+ data: any;
47
+ }
48
+ interface ISendMessageData {
49
+ conversationId: string;
50
+ content: string;
51
+ messageType?: MessageType;
52
+ }
53
+ interface ITypingData {
54
+ conversationId: string;
55
+ isTyping: boolean;
56
+ }
57
+ interface IReadMessageData {
58
+ messageId: string;
59
+ conversationId: string;
60
+ }
61
+ interface IFileUploadConfig {
62
+ uploadUrl: string;
63
+ maxFileSize?: number;
64
+ allowedTypes?: string[];
65
+ headers?: Record<string, string>;
66
+ }
67
+ interface IUploadedFile {
68
+ url: string;
69
+ name: string;
70
+ size: number;
71
+ type: string;
72
+ markdown?: string;
73
+ }
74
+ interface IChatConfig {
75
+ websocketUrl: string;
76
+ conversationId?: string;
77
+ apiKey: string;
78
+ currentUser: IUser;
79
+ fileUpload?: IFileUploadConfig;
80
+ httpApiUrl?: string;
81
+ headers?: Record<string, string>;
82
+ enableEmoji?: boolean;
83
+ enableFileUpload?: boolean;
84
+ enableTypingIndicator?: boolean;
85
+ enableReadReceipts?: boolean;
86
+ /**
87
+ * For agents, set this to true to disable creating a WebSocket connection in the chat widget.
88
+ * Agents should have a global WebSocket connection instead.
89
+ * @default false
90
+ */
91
+ disableWebSocket?: boolean;
92
+ onMessageSent?: (message: IMessage) => void;
93
+ onMessageReceived?: (message: IMessage) => void;
94
+ onConversationChange?: (conversation: IConversation) => void;
95
+ onConnectionChange?: (connected: boolean) => void;
96
+ onError?: (error: Error) => void;
97
+ toast?: {
98
+ success: (message: string) => void;
99
+ error: (message: string) => void;
100
+ info: (message: string) => void;
101
+ };
102
+ }
103
+ interface IApiResponse<T> {
104
+ success: boolean;
105
+ data?: T;
106
+ error?: {
107
+ code: string;
108
+ message: string;
109
+ };
110
+ pagination?: {
111
+ nextPageToken?: string;
112
+ };
113
+ }
114
+
115
+ interface ChatWidgetProps {
116
+ config: IChatConfig;
117
+ className?: string;
118
+ /**
119
+ * Variant of the chat widget:
120
+ * - 'popover': Fixed positioned floating widget (default)
121
+ * - 'fullPage': Full page layout that fills the container
122
+ */
123
+ variant?: 'popover' | 'fullPage';
124
+ /**
125
+ * External WebSocket connection (for agents with global connection)
126
+ */
127
+ externalWebSocket?: WebSocket | null;
128
+ }
129
+ declare function ChatWidget({ config, className, variant, externalWebSocket, }: ChatWidgetProps): react_jsx_runtime.JSX.Element | null;
130
+
131
+ interface ChatWidgetWrapperProps {
132
+ /**
133
+ * Base configuration for the chat widget (without user info and conversationId)
134
+ */
135
+ config: Omit<IChatConfig, 'currentUser' | 'conversationId' | 'userId'> & {
136
+ currentUser?: Partial<IUser>;
137
+ conversationId?: string;
138
+ };
139
+ /**
140
+ * Custom className for the wrapper
141
+ */
142
+ className?: string;
143
+ /**
144
+ * Storage key prefix for persisting user data
145
+ * Defaults to 'xcelsior_chat'
146
+ */
147
+ storageKeyPrefix?: string;
148
+ /**
149
+ * Callback when user submits the pre-chat form
150
+ */
151
+ onPreChatSubmit?: (user: IUser) => void;
152
+ }
153
+ /**
154
+ * Chat component that handles:
155
+ * - Automatic conversation ID generation
156
+ * - Pre-chat form for collecting user information
157
+ * - Session persistence in localStorage
158
+ */
159
+ declare function Chat({ config, className, storageKeyPrefix, onPreChatSubmit, }: ChatWidgetWrapperProps): react_jsx_runtime.JSX.Element | null;
160
+
161
+ interface ChatHeaderProps {
162
+ agent?: IUser;
163
+ onClose?: () => void;
164
+ onMinimize?: () => void;
165
+ }
166
+ declare function ChatHeader({ agent, onClose, onMinimize }: ChatHeaderProps): react_jsx_runtime.JSX.Element;
167
+
168
+ interface UseFileUploadReturn {
169
+ uploadFile: (file: File) => Promise<IUploadedFile | null>;
170
+ isUploading: boolean;
171
+ uploadProgress: number;
172
+ error: Error | null;
173
+ canUpload: boolean;
174
+ }
175
+ declare function useFileUpload(apiKey: string, config?: IFileUploadConfig): UseFileUploadReturn;
176
+
177
+ interface ChatInputProps {
178
+ onSend: (message: string) => void;
179
+ onTyping?: (isTyping: boolean) => void;
180
+ config: IChatConfig;
181
+ fileUpload: UseFileUploadReturn;
182
+ disabled?: boolean;
183
+ }
184
+ declare function ChatInput({ onSend, onTyping, config, fileUpload, disabled, }: ChatInputProps): react_jsx_runtime.JSX.Element;
185
+
186
+ interface MessageItemProps {
187
+ message: IMessage;
188
+ currentUser: IUser;
189
+ showAvatar?: boolean;
190
+ showTimestamp?: boolean;
191
+ }
192
+ declare function MessageItem({ message, currentUser, showAvatar, showTimestamp, }: MessageItemProps): react_jsx_runtime.JSX.Element;
193
+
194
+ interface MessageListProps {
195
+ messages: IMessage[];
196
+ currentUser: IUser;
197
+ isLoading?: boolean;
198
+ isTyping?: boolean;
199
+ typingUser?: string;
200
+ autoScroll?: boolean;
201
+ onLoadMore?: () => void;
202
+ hasMore?: boolean;
203
+ isLoadingMore?: boolean;
204
+ }
205
+ declare function MessageList({ messages, currentUser, isLoading, isTyping, typingUser, autoScroll, onLoadMore, hasMore, isLoadingMore, }: MessageListProps): react_jsx_runtime.JSX.Element;
206
+
207
+ interface TypingIndicatorProps {
208
+ isTyping: boolean;
209
+ userName?: string;
210
+ }
211
+ declare function TypingIndicator({ isTyping, userName }: TypingIndicatorProps): react_jsx_runtime.JSX.Element | null;
212
+
213
+ interface PreChatFormProps {
214
+ onSubmit: (name: string, email: string) => void;
215
+ className?: string;
216
+ initialName?: string;
217
+ initialEmail?: string;
218
+ }
219
+ /**
220
+ * PreChatForm component for collecting user information before starting chat
221
+ */
222
+ declare function PreChatForm({ onSubmit, className, initialName, initialEmail, }: PreChatFormProps): react_jsx_runtime.JSX.Element;
223
+
224
+ interface UseWebSocketReturn {
225
+ isConnected: boolean;
226
+ sendMessage: (action: string, data: any) => void;
227
+ lastMessage: IWebSocketMessage | null;
228
+ error: Error | null;
229
+ reconnect: () => void;
230
+ }
231
+ /**
232
+ * Hook for WebSocket connection in chat widget.
233
+ * Can use an external WebSocket connection (for agents) via the externalWebSocket prop.
234
+ */
235
+ declare function useWebSocket(config: IChatConfig, externalWebSocket?: WebSocket | null): UseWebSocketReturn;
236
+
237
+ interface UseMessagesReturn {
238
+ messages: IMessage[];
239
+ addMessage: (message: IMessage) => void;
240
+ updateMessageStatus: (messageId: string, status: IMessage['status']) => void;
241
+ clearMessages: () => void;
242
+ isLoading: boolean;
243
+ error: Error | null;
244
+ loadMore: () => Promise<void>;
245
+ hasMore: boolean;
246
+ isLoadingMore: boolean;
247
+ }
248
+ declare function useMessages(websocket: UseWebSocketReturn, config: IChatConfig): UseMessagesReturn;
249
+
250
+ interface UseTypingIndicatorReturn {
251
+ isTyping: boolean;
252
+ typingUsers: string[];
253
+ }
254
+ declare function useTypingIndicator(websocket: UseWebSocketReturn): UseTypingIndicatorReturn;
255
+
256
+ interface FetchMessagesParams {
257
+ conversationId: string;
258
+ limit?: number;
259
+ pageToken?: string;
260
+ }
261
+ /**
262
+ * Fetch messages for a conversation from the REST API
263
+ */
264
+ declare function fetchMessages(baseUrl: string, params: FetchMessagesParams, headers?: Record<string, string>): Promise<{
265
+ data: IMessage[];
266
+ nextPageToken: string | undefined;
267
+ }>;
268
+
269
+ export { Chat, ChatHeader, ChatInput, ChatWidget, type ChatWidgetProps, type ConversationChannel, type ConversationPriority, type ConversationStatus, type IApiResponse, type IChatConfig, type IConversation, type IFileUploadConfig, type IMessage, type IReadMessageData, type ISendMessageData, type ITypingData, type IUploadedFile, type IUser, type IWebSocketMessage, MessageItem, MessageList, type MessageStatus, type MessageType, PreChatForm, TypingIndicator, fetchMessages, useFileUpload, useMessages, useTypingIndicator, useWebSocket };