@cdevhub/ngx-chat 1.0.6
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/README.md +382 -0
- package/fesm2022/cdevhub-ngx-chat-testing.mjs +950 -0
- package/fesm2022/cdevhub-ngx-chat-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-chat.mjs +11973 -0
- package/fesm2022/cdevhub-ngx-chat.mjs.map +1 -0
- package/package.json +55 -0
- package/types/cdevhub-ngx-chat-testing.d.ts +362 -0
- package/types/cdevhub-ngx-chat.d.ts +6973 -0
package/README.md
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# ngx-chat
|
|
2
|
+
|
|
3
|
+
A pure presentational Angular 21 library for building chat interfaces. Supports AI chat, peer-to-peer messaging, group chat, support chat, and bot interactions.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Signals-based**: Built with Angular signals (`signal`, `computed`, `input`, `output`)
|
|
8
|
+
- **Virtual scrolling**: Handle 10,000+ messages efficiently
|
|
9
|
+
- **Markdown rendering**: Full markdown support with syntax highlighting
|
|
10
|
+
- **File attachments**: Images, files, video, and audio support
|
|
11
|
+
- **Interactive actions**: Confirm dialogs, select, multi-select, button groups
|
|
12
|
+
- **Accessibility**: WCAG 2.1 AA compliant
|
|
13
|
+
- **RTL support**: Full right-to-left language support
|
|
14
|
+
- **Theming**: Dark/light/auto themes via CSS custom properties
|
|
15
|
+
- **Fully typed**: Complete TypeScript interfaces
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install ngx-chat
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Peer Dependencies
|
|
24
|
+
|
|
25
|
+
Install required peer dependencies:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @angular/animations @angular/cdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Required versions:
|
|
32
|
+
- `@angular/core` ^21.0.0
|
|
33
|
+
- `@angular/common` ^21.0.0
|
|
34
|
+
- `@angular/animations` ^21.0.0
|
|
35
|
+
- `@angular/cdk` ^21.0.0
|
|
36
|
+
|
|
37
|
+
### Optional Dependencies
|
|
38
|
+
|
|
39
|
+
For markdown rendering with syntax highlighting:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install marked dompurify highlight.js
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
### 1. Configure the provider
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// app.config.ts
|
|
51
|
+
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
|
52
|
+
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
|
53
|
+
import { provideChat } from 'ngx-chat';
|
|
54
|
+
|
|
55
|
+
export const appConfig: ApplicationConfig = {
|
|
56
|
+
providers: [
|
|
57
|
+
provideZoneChangeDetection({ eventCoalescing: true }),
|
|
58
|
+
provideAnimationsAsync(),
|
|
59
|
+
provideChat() // Uses defaults
|
|
60
|
+
]
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. Use the component
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// app.component.ts
|
|
68
|
+
import { Component, signal } from '@angular/core';
|
|
69
|
+
import { ChatComponent, ChatMessage, ChatSendEvent } from 'ngx-chat';
|
|
70
|
+
|
|
71
|
+
@Component({
|
|
72
|
+
selector: 'app-root',
|
|
73
|
+
standalone: true,
|
|
74
|
+
imports: [ChatComponent],
|
|
75
|
+
template: `
|
|
76
|
+
<ngx-chat
|
|
77
|
+
[messages]="messages()"
|
|
78
|
+
[isTyping]="isTyping()"
|
|
79
|
+
(send)="onSend($event)"
|
|
80
|
+
/>
|
|
81
|
+
`,
|
|
82
|
+
styles: [`
|
|
83
|
+
ngx-chat {
|
|
84
|
+
height: 600px;
|
|
85
|
+
display: block;
|
|
86
|
+
}
|
|
87
|
+
`]
|
|
88
|
+
})
|
|
89
|
+
export class AppComponent {
|
|
90
|
+
messages = signal<ChatMessage[]>([]);
|
|
91
|
+
isTyping = signal(false);
|
|
92
|
+
|
|
93
|
+
onSend(event: ChatSendEvent): void {
|
|
94
|
+
const userMessage: ChatMessage = {
|
|
95
|
+
id: crypto.randomUUID(),
|
|
96
|
+
content: event.content,
|
|
97
|
+
timestamp: new Date(),
|
|
98
|
+
sender: { id: 'user', name: 'You', type: 'self' },
|
|
99
|
+
status: 'sent'
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
this.messages.update(msgs => [...msgs, userMessage]);
|
|
103
|
+
|
|
104
|
+
// Send to your backend/AI service
|
|
105
|
+
this.sendToBackend(event.content);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private sendToBackend(content: string): void {
|
|
109
|
+
// Your implementation
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Configuration
|
|
115
|
+
|
|
116
|
+
Configure ngx-chat via `provideChat()` in your app config:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
provideChat({
|
|
120
|
+
config: {
|
|
121
|
+
// Behavior settings
|
|
122
|
+
behavior: {
|
|
123
|
+
sendOnEnter: true, // Send message on Enter key
|
|
124
|
+
showTimestamps: true, // Display timestamps on messages
|
|
125
|
+
autoScroll: true, // Auto-scroll to new messages
|
|
126
|
+
groupMessages: true, // Group consecutive messages from same sender
|
|
127
|
+
showSenderName: true, // Show sender name on messages
|
|
128
|
+
showAvatar: true, // Show avatar on messages
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// Message validation
|
|
132
|
+
validation: {
|
|
133
|
+
maxMessageLength: 5000, // Max characters per message
|
|
134
|
+
sanitize: true, // Sanitize HTML in messages
|
|
135
|
+
trimWhitespace: true, // Trim leading/trailing whitespace
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
// Markdown rendering
|
|
139
|
+
markdown: {
|
|
140
|
+
enabled: true, // Enable markdown rendering
|
|
141
|
+
syntaxHighlighting: true, // Enable code syntax highlighting
|
|
142
|
+
externalLinksNewTab: true,// Open external links in new tab
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
// File attachments
|
|
146
|
+
attachments: {
|
|
147
|
+
enabled: true, // Enable file attachments
|
|
148
|
+
maxFileSize: 10485760, // 10 MB max file size
|
|
149
|
+
maxFilesPerMessage: 5, // Max files per message
|
|
150
|
+
dragAndDrop: true, // Enable drag and drop
|
|
151
|
+
pasteFromClipboard: true, // Enable paste from clipboard
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
// Virtual scrolling
|
|
155
|
+
virtualScroll: {
|
|
156
|
+
enabled: true, // Enable virtual scrolling
|
|
157
|
+
threshold: 100, // Min messages before activating
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
// Error recovery
|
|
161
|
+
errorRecovery: {
|
|
162
|
+
autoRetry: true, // Auto-retry failed messages
|
|
163
|
+
maxRetries: 3, // Max retry attempts
|
|
164
|
+
offlineQueue: true, // Queue messages when offline
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
// Keyboard shortcuts
|
|
168
|
+
keyboard: {
|
|
169
|
+
sendOnEnter: true, // Send on Enter
|
|
170
|
+
sendOnCtrlEnter: false, // Send on Ctrl+Enter
|
|
171
|
+
escToCancelAction: true, // Escape to cancel action
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
// Theme and direction
|
|
175
|
+
theme: 'auto', // 'light' | 'dark' | 'auto'
|
|
176
|
+
direction: 'auto', // 'ltr' | 'rtl' | 'auto'
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
// Internationalization
|
|
180
|
+
i18n: {
|
|
181
|
+
send: 'Send',
|
|
182
|
+
placeholder: 'Type a message...',
|
|
183
|
+
typing: '{name} is typing...',
|
|
184
|
+
// ... see full i18n options below
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### i18n Options
|
|
190
|
+
|
|
191
|
+
All user-facing strings can be customized:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
provideChat({
|
|
195
|
+
i18n: {
|
|
196
|
+
// Buttons
|
|
197
|
+
send: 'Send',
|
|
198
|
+
cancel: 'Cancel',
|
|
199
|
+
confirm: 'Confirm',
|
|
200
|
+
submit: 'Submit',
|
|
201
|
+
retry: 'Retry',
|
|
202
|
+
|
|
203
|
+
// Input
|
|
204
|
+
placeholder: 'Type a message...',
|
|
205
|
+
emptyState: 'No messages yet',
|
|
206
|
+
|
|
207
|
+
// Typing indicator
|
|
208
|
+
typing: '{name} is typing...',
|
|
209
|
+
someoneTyping: 'Someone is typing...',
|
|
210
|
+
|
|
211
|
+
// Message status
|
|
212
|
+
sending: 'Sending...',
|
|
213
|
+
sent: 'Sent',
|
|
214
|
+
delivered: 'Delivered',
|
|
215
|
+
read: 'Read',
|
|
216
|
+
error: 'Failed to send',
|
|
217
|
+
|
|
218
|
+
// Attachments
|
|
219
|
+
addAttachment: 'Add attachment',
|
|
220
|
+
removeAttachment: 'Remove attachment',
|
|
221
|
+
fileTooLarge: 'File is too large. Maximum size is {maxSize}.',
|
|
222
|
+
|
|
223
|
+
// Loading
|
|
224
|
+
loading: 'Loading...',
|
|
225
|
+
loadMore: 'Load more messages',
|
|
226
|
+
|
|
227
|
+
// ARIA labels
|
|
228
|
+
ariaMessageList: 'Chat messages',
|
|
229
|
+
ariaMessageInput: 'Message input',
|
|
230
|
+
ariaSendButton: 'Send message',
|
|
231
|
+
}
|
|
232
|
+
})
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## API Reference
|
|
236
|
+
|
|
237
|
+
### Components
|
|
238
|
+
|
|
239
|
+
| Component | Selector | Description |
|
|
240
|
+
|-----------|----------|-------------|
|
|
241
|
+
| `ChatComponent` | `ngx-chat` | Main chat container |
|
|
242
|
+
| `ChatHeaderComponent` | `ngx-chat-header` | Chat header with title |
|
|
243
|
+
| `ChatMessagesComponent` | `ngx-chat-messages` | Messages container with virtual scroll |
|
|
244
|
+
| `ChatSenderComponent` | `ngx-chat-sender` | Message input and send button |
|
|
245
|
+
| `ChatMarkdownComponent` | `ngx-chat-markdown` | Markdown renderer |
|
|
246
|
+
| `ChatErrorBoundaryComponent` | `ngx-chat-error-boundary` | Error boundary wrapper |
|
|
247
|
+
|
|
248
|
+
### Main Component Inputs
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
// ChatComponent inputs
|
|
252
|
+
messages: ChatMessage[] // Array of messages to display
|
|
253
|
+
isTyping: boolean // Show typing indicator
|
|
254
|
+
typingLabel: string // Custom typing label
|
|
255
|
+
disabled: boolean // Disable chat interactions
|
|
256
|
+
loading: boolean // Show loading state
|
|
257
|
+
config: ChatConfigInput // Configuration overrides
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Main Component Outputs
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// ChatComponent outputs
|
|
264
|
+
send: ChatSendEvent // User sends a message
|
|
265
|
+
typing: ChatTypingEvent // User typing state changes
|
|
266
|
+
action: MessageActionEvent // User responds to an action
|
|
267
|
+
retry: ChatRetryEvent // User retries a failed message
|
|
268
|
+
loadMore: ChatLoadMoreEvent // User scrolls to load more
|
|
269
|
+
attachmentClick: AttachmentClickEvent // User clicks attachment
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Models
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
// Message model
|
|
276
|
+
interface ChatMessage {
|
|
277
|
+
id: string;
|
|
278
|
+
content: string;
|
|
279
|
+
timestamp: Date;
|
|
280
|
+
sender: MessageSender;
|
|
281
|
+
status: MessageStatus;
|
|
282
|
+
attachments?: MessageAttachment[];
|
|
283
|
+
action?: MessageAction;
|
|
284
|
+
error?: ChatMessageError;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Sender model
|
|
288
|
+
interface MessageSender {
|
|
289
|
+
id: string;
|
|
290
|
+
name: string;
|
|
291
|
+
type: 'self' | 'other' | 'system';
|
|
292
|
+
avatarUrl?: string;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Status type
|
|
296
|
+
type MessageStatus = 'sending' | 'sent' | 'delivered' | 'read' | 'error';
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Provider Function
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
import { provideChat, ProvideChatOptions } from 'ngx-chat';
|
|
303
|
+
|
|
304
|
+
// In app.config.ts providers array
|
|
305
|
+
provideChat(options?: ProvideChatOptions): EnvironmentProviders
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Injection Tokens
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
import { CHAT_CONFIG, CHAT_I18N } from 'ngx-chat';
|
|
312
|
+
|
|
313
|
+
// Inject configuration
|
|
314
|
+
const config = inject(CHAT_CONFIG);
|
|
315
|
+
const i18n = inject(CHAT_I18N);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## Theming
|
|
319
|
+
|
|
320
|
+
ngx-chat uses CSS custom properties for theming. Override these in your styles:
|
|
321
|
+
|
|
322
|
+
```css
|
|
323
|
+
ngx-chat {
|
|
324
|
+
/* Background colors */
|
|
325
|
+
--ngx-chat-bg: #ffffff;
|
|
326
|
+
--ngx-chat-surface: #f8f9fa;
|
|
327
|
+
--ngx-chat-border: #e9ecef;
|
|
328
|
+
|
|
329
|
+
/* Text colors */
|
|
330
|
+
--ngx-chat-text: #212529;
|
|
331
|
+
--ngx-chat-text-secondary: #6c757d;
|
|
332
|
+
--ngx-chat-text-muted: #adb5bd;
|
|
333
|
+
|
|
334
|
+
/* Self message (current user) */
|
|
335
|
+
--ngx-chat-self-bg: #0d6efd;
|
|
336
|
+
--ngx-chat-self-text: #ffffff;
|
|
337
|
+
|
|
338
|
+
/* Other message (other participants) */
|
|
339
|
+
--ngx-chat-other-bg: #f1f3f4;
|
|
340
|
+
--ngx-chat-other-text: #202124;
|
|
341
|
+
|
|
342
|
+
/* Input */
|
|
343
|
+
--ngx-chat-input-bg: #ffffff;
|
|
344
|
+
--ngx-chat-input-border: #ced4da;
|
|
345
|
+
--ngx-chat-input-focus-border: #86b7fe;
|
|
346
|
+
|
|
347
|
+
/* Spacing */
|
|
348
|
+
--ngx-chat-spacing: 16px;
|
|
349
|
+
--ngx-chat-spacing-sm: 8px;
|
|
350
|
+
--ngx-chat-spacing-lg: 24px;
|
|
351
|
+
|
|
352
|
+
/* Message bubble */
|
|
353
|
+
--ngx-chat-bubble-radius: 16px;
|
|
354
|
+
--ngx-chat-bubble-max-width: 85%;
|
|
355
|
+
|
|
356
|
+
/* Avatar */
|
|
357
|
+
--ngx-chat-avatar-size: 32px;
|
|
358
|
+
--ngx-chat-avatar-bg: #e5e7eb;
|
|
359
|
+
|
|
360
|
+
/* Animation */
|
|
361
|
+
--ngx-chat-animation-duration: 200ms;
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Browser Support
|
|
366
|
+
|
|
367
|
+
| Browser | Version |
|
|
368
|
+
|---------|---------|
|
|
369
|
+
| Chrome | Latest 2 versions |
|
|
370
|
+
| Firefox | Latest 2 versions |
|
|
371
|
+
| Safari | Latest 2 versions |
|
|
372
|
+
| Edge | Latest 2 versions |
|
|
373
|
+
|
|
374
|
+
Requires browsers with support for:
|
|
375
|
+
- ES2022
|
|
376
|
+
- CSS Custom Properties
|
|
377
|
+
- ResizeObserver
|
|
378
|
+
- IntersectionObserver
|
|
379
|
+
|
|
380
|
+
## License
|
|
381
|
+
|
|
382
|
+
MIT
|