advanced-chat-kai 0.1.0
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/LICENSE +21 -0
- package/README.md +349 -0
- package/dist/advanced-chat-kai.cjs.js +1949 -0
- package/dist/advanced-chat-kai.es.js +4057 -0
- package/dist/consts/index.d.ts +8 -0
- package/dist/consts/index.d.ts.map +1 -0
- package/dist/index-BAqe5cNa.cjs +4 -0
- package/dist/index-ChjDCgwc.cjs +4 -0
- package/dist/index-DII6YJVm.js +2661 -0
- package/dist/index-FIDC6lfi.js +1422 -0
- package/dist/types/event.d.ts +54 -0
- package/dist/types/event.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/props.d.ts +101 -0
- package/dist/types/props.d.ts.map +1 -0
- package/package.json +94 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Akinori Hoshina
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# advanced-chat-kai
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
[](https://opensource.org/licenses/MIT) [](https://codecov.io/gh/spider-hand/advanced-chat-kai)
|
|
8
|
+
|
|
9
|
+
A highly customizable Web Component for building chat interfaces
|
|
10
|
+
|
|
11
|
+
> "Kai" (改) means "improved" in Japanese - this is a modern, lightweight, and framework-agnostic chat component built for flexibility and ease of integration.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- Framework-agnostic - Can be used with any frontend framework or none at all
|
|
16
|
+
- Backend-agnostic - No assumptions about your backend; integrate freely
|
|
17
|
+
- Lightweight - Built with Lit for minimal bundle size and high performance
|
|
18
|
+
- Logic-free - You own the data, state and behavior; components only handle UI
|
|
19
|
+
- Theming support - Built-in light and dark themes
|
|
20
|
+
- Customizable style - Easily style components with CSS variables
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
npm install advanced-chat-kai
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<advanced-chat-kai></advanced-chat-kai>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| ------------------------------ | ------------------------------------------------- | -------- | ---------------------- | --------------------------------------------------------------------------------- |
|
|
38
|
+
| `currentUserId` | string \| null | false | `null` | The current user id using the chat |
|
|
39
|
+
| `rooms` | [ChatRoom](#chatroom)[] | false | `[]` | The list of chat rooms showing in the sidebar |
|
|
40
|
+
| `messages` | [ChatItemType](#chatitemtype)[] | false | `[]` | The list of messages in the room currently selected |
|
|
41
|
+
| `attachments` | [ChatMessageAttachment](#chatmessageattachment)[] | false | `[]` | The list of attachments in the message |
|
|
42
|
+
| `suggestions` | [ChatMessageSuggestion](#chatmessagesuggestion)[] | false | `[]` | The list of message suggestions |
|
|
43
|
+
| `replyTo` | [ChatMessageReply](#chatmessagereply) \| null | false | `null` | The message being replied to, if any |
|
|
44
|
+
| `selectedRoomId` | string \| null | false | `null` | The id of the room currently selected |
|
|
45
|
+
| `isLoadingRoom` | boolean | false | `false` | Whether the list of the initial rooms are loading or not |
|
|
46
|
+
| `isLoadingMessage` | boolean | false | `false` | Whether the list of the initial messages are loading or not |
|
|
47
|
+
| `isLoadingMoreRooms` | boolean | false | `false` | Whether more rooms are loading or not |
|
|
48
|
+
| `isLoadingMoreMessages` | boolean | false | `false` | Whether more messages are loading or not |
|
|
49
|
+
| `inputMessage` | string | false | `""` | The current message input used for two-way binding |
|
|
50
|
+
| `roomActions` | [ChatAction<ChatActionType>](#chataction)[] | false | `[]` | The list of actions available for the rooms |
|
|
51
|
+
| `myMessageActions` | [ChatAction<ChatActionType>](#chataction)[] | false | `[]` | The list of actions available for the user's messages |
|
|
52
|
+
| `theirMessageActions` | [ChatAction<ChatActionType>](#chataction)[] | false | `[]` | The list of actions available for other user's messages |
|
|
53
|
+
| `isMobile` | boolean | false | `false` | Whether the chat component should be rendered in mobile mode or not |
|
|
54
|
+
| `isSingleRoom` | boolean | false | `false` | Whether the sidebar and toggle button should be rendered or not |
|
|
55
|
+
| `isEmojiPickerAvailable` | boolean | false | `true` | Whether the emoji picker on the footer should be rendered or not |
|
|
56
|
+
| `isEmojiReactionAvailable` | boolean | false | `true` | Whether the emoji reaction button on the message should be rendered or not |
|
|
57
|
+
| `isReplyAvailable` | boolean | false | `true` | Whether the reply button on the message should be rendered or not |
|
|
58
|
+
| `isMessageAttachmentAvailable` | boolean | false | `true` | Whether the message attachment button on the footer should be rendered or not |
|
|
59
|
+
| `isMarkdownAvailable` | boolean | false | `false` | Whether the markdown message format should be rendered or not |
|
|
60
|
+
| `isTyping` | boolean | false | `false` | Whether the typing indicator should be rendered or not |
|
|
61
|
+
| `showRoomAvatar` | boolean | false | `true` | Whether the room avatar on the list of rooms should be rendered or not |
|
|
62
|
+
| `showTheirAvatar` | boolean | false | `true` | Whether the other user's avatar on the message should be rendered or not |
|
|
63
|
+
| `dialog` | [Dialog](#dialog) \| null | false | `null` | The dialog to be rendered |
|
|
64
|
+
| `height` | string | false | `"60em"` | The height of the chat component |
|
|
65
|
+
| `width` | string | false | `"80em"` | The width of the chat component |
|
|
66
|
+
| `i18n` | [PartialI18nType](#i18ntype) | false | [See below](#i18ntype) | The i18n object to be used for translations |
|
|
67
|
+
| `theme` | ThemeType | false | `"light"` | The theme to be used for the chat component. It must be either `light` or `dark`. |
|
|
68
|
+
|
|
69
|
+
### Interfaces
|
|
70
|
+
|
|
71
|
+
##### ChatRoom
|
|
72
|
+
|
|
73
|
+
Notes:
|
|
74
|
+
|
|
75
|
+
- The footer will be hidden if `hasEnded` is true and `selectedRoomId` matches the room’s `id`.
|
|
76
|
+
|
|
77
|
+
Example:
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
rooms = [
|
|
81
|
+
{
|
|
82
|
+
id: "1",
|
|
83
|
+
headerTitle: "title",
|
|
84
|
+
headerSubtitle: "subtitle",
|
|
85
|
+
sidebarTitle: "title",
|
|
86
|
+
siderbarSubtitle: "subtitle",
|
|
87
|
+
avatar: "/avatar.png",
|
|
88
|
+
meta: "May 1",
|
|
89
|
+
badge: {
|
|
90
|
+
type: "success",
|
|
91
|
+
label: "Success",
|
|
92
|
+
},
|
|
93
|
+
hasEnded: false,
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
##### ChatItemType
|
|
99
|
+
|
|
100
|
+
Notes:
|
|
101
|
+
|
|
102
|
+
- `type` must be either `divider` or `message`.
|
|
103
|
+
- `reactions` represents the emoji reactions and the list of user IDs who reacted with each emoji.
|
|
104
|
+
- `isSelected` can be used to indicate that an action (such as editing) is currently active on the message.
|
|
105
|
+
|
|
106
|
+
Example:
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
messages = [
|
|
110
|
+
{
|
|
111
|
+
id: "0",
|
|
112
|
+
type: "divider",
|
|
113
|
+
roomId: "1",
|
|
114
|
+
content: "May 1",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: "1",
|
|
118
|
+
type: "message",
|
|
119
|
+
roomId: "1",
|
|
120
|
+
senderId: "1",
|
|
121
|
+
senderName: "User 1",
|
|
122
|
+
senderAvatar: "/avatar.png",
|
|
123
|
+
content: "Hello, world",
|
|
124
|
+
timestamp: "12:34 PM",
|
|
125
|
+
reactions: new Map<string, Set<string>>([
|
|
126
|
+
["👍", new Set(["2", "3"])],
|
|
127
|
+
["🎉", new Set(["1", "4", "5"])],
|
|
128
|
+
]),
|
|
129
|
+
attachments: [
|
|
130
|
+
{
|
|
131
|
+
name: "file1.txt",
|
|
132
|
+
meta: "20 KB",
|
|
133
|
+
id: "0",
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
isDeleted: false,
|
|
137
|
+
isSelected: false,
|
|
138
|
+
replyTo: null,
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
##### ChatMessageAttachment
|
|
144
|
+
|
|
145
|
+
Example:
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
attachments = [
|
|
149
|
+
{
|
|
150
|
+
name: "file1.txt",
|
|
151
|
+
meta: "20 KB",
|
|
152
|
+
id: "0",
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "image.png",
|
|
156
|
+
meta: "2 MB",
|
|
157
|
+
id: "1",
|
|
158
|
+
imageUrl: "/image.png",
|
|
159
|
+
},
|
|
160
|
+
];
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
##### ChatMessageSuggestion
|
|
164
|
+
|
|
165
|
+
Example:
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
suggestions = [
|
|
169
|
+
{
|
|
170
|
+
text: "Hello",
|
|
171
|
+
value: "hello",
|
|
172
|
+
},
|
|
173
|
+
];
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
##### ChatMessageReply
|
|
177
|
+
|
|
178
|
+
Example:
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
chatMessageReply = {
|
|
182
|
+
id: "1",
|
|
183
|
+
type: "message",
|
|
184
|
+
roomId: "1",
|
|
185
|
+
senderId: "1",
|
|
186
|
+
senderName: "User 1",
|
|
187
|
+
senderAvatar: "/avatar.png",
|
|
188
|
+
content: "Hello, world",
|
|
189
|
+
timestamp: "12:34 PM",
|
|
190
|
+
reactions: new Map<string, Set<string>>([
|
|
191
|
+
["👍", new Set(["2", "3"])],
|
|
192
|
+
["🎉", new Set(["1", "4", "5"])],
|
|
193
|
+
]),
|
|
194
|
+
attachments: [
|
|
195
|
+
{
|
|
196
|
+
name: "file1.txt",
|
|
197
|
+
meta: "20 KB",
|
|
198
|
+
id: "0",
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
isDeleted: false,
|
|
202
|
+
isSelected: false,
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
##### ChatAction
|
|
207
|
+
|
|
208
|
+
Example:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
myMessageActions = [
|
|
212
|
+
{
|
|
213
|
+
label: "Edit",
|
|
214
|
+
value: "edit-message",
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
label: "Delete",
|
|
218
|
+
value: "delete-message",
|
|
219
|
+
},
|
|
220
|
+
];
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
##### Dialog
|
|
224
|
+
|
|
225
|
+
Example:
|
|
226
|
+
|
|
227
|
+
```js
|
|
228
|
+
dialog = {
|
|
229
|
+
event: "confirm-deletion-message",
|
|
230
|
+
body: "Are you sure you want to delete this message?",
|
|
231
|
+
leftButton: {
|
|
232
|
+
text: "Cancel",
|
|
233
|
+
},
|
|
234
|
+
rightButton: {
|
|
235
|
+
text: "OK",
|
|
236
|
+
variant: "danger",
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
##### I18nType
|
|
242
|
+
|
|
243
|
+
The default value is shown below. You can override only the fields you want to customize.
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
i18n = {
|
|
247
|
+
deletedMessage: "This message has been deleted.",
|
|
248
|
+
chatFooterTextareaPlaceholder: "Write a message..",
|
|
249
|
+
chatSearchPlaceholder: "Search room",
|
|
250
|
+
closedRoomMessage: "This chat has been ended.",
|
|
251
|
+
newMeessageNotification: "New messages",
|
|
252
|
+
};
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### ⚠️ Note on updating arrays and objects
|
|
256
|
+
|
|
257
|
+
Lit uses shallow comparison to detect changes to reactive properties. When working with arrays or objects, you must assign a new reference to trigger updates. Mutating the existing object or array in place (e.g. using `push()` or modifying a property directly) will not cause the component to update.
|
|
258
|
+
|
|
259
|
+
✅ Correct:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
this.messages = [...this.messages, newMessage];
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
❌ Won’t work:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
this.messages.push(newMessage);
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Events
|
|
272
|
+
|
|
273
|
+
| Name | Detail / Payload | Fires when a user |
|
|
274
|
+
| ----------------------- | ------------------------------------- | -------------------------------------------------- |
|
|
275
|
+
| `add-room` | - | Clicked the add button on the sidebar |
|
|
276
|
+
| `search-room` | `{ value }` | Changed the input on the searchbox |
|
|
277
|
+
| `select-room-action` | `{ label, value, roomId }` | Selected an action on the room |
|
|
278
|
+
| `load-more-rooms` | - | Reached the bottom of the room list |
|
|
279
|
+
| `select-room` | `{ room }` | Selected a room in the list |
|
|
280
|
+
| `load-more-messages` | - | Reached the top of the message list |
|
|
281
|
+
| `select-message-action` | `{ label, value, messageId }` | Selected an action on the message |
|
|
282
|
+
| `select-suggestion` | `{ suggestion }` | Selected a suggestion in the list |
|
|
283
|
+
| `select-emoji` | `{ messageId, currentUserId, emoji }` | Selected an emoji reaction in picker for a message |
|
|
284
|
+
| `reply-to-message` | `{ replyTo }` | Clicked the reply button on a message |
|
|
285
|
+
| `click-reaction` | `{ messageId, reaction }` | Clicked an existing emoji reaction on a message |
|
|
286
|
+
| `download-attachment` | `{ attachment }` | Clicked the download button on an attachment |
|
|
287
|
+
| `remove-attachment` | `{ attachment }` | Clicked the close button on an attachment |
|
|
288
|
+
| `cancel-reply` | - | Clicked the close button on the reply message |
|
|
289
|
+
| `select-file` | `{ file }` | Selected a file |
|
|
290
|
+
| `send-message` | `{ roomId, senderId, content }` | Clicked the send button on the footer |
|
|
291
|
+
| `click-dialog-button` | `{ event, side }` | Clicked a button on a dialog |
|
|
292
|
+
|
|
293
|
+
## Styling
|
|
294
|
+
|
|
295
|
+
The `--surface-50` to `--surface-950` variables define the primary surface color scale, used across light and dark themes for backgrounds and component surfaces.
|
|
296
|
+
|
|
297
|
+
| Variable | Description |
|
|
298
|
+
| -------------------------------------- | --------------------------------------------------- |
|
|
299
|
+
| `--base-font-size` | The base font size of the chat component |
|
|
300
|
+
| `--white` | |
|
|
301
|
+
| `--black` | |
|
|
302
|
+
| `--success` | |
|
|
303
|
+
| `--danger` | |
|
|
304
|
+
| `--warning` | |
|
|
305
|
+
| `--info` | |
|
|
306
|
+
| `--surface-50` | |
|
|
307
|
+
| `--surface-100` | |
|
|
308
|
+
| `--surface-200` | |
|
|
309
|
+
| `--surface-300` | |
|
|
310
|
+
| `--surface-400` | |
|
|
311
|
+
| `--surface-500` | |
|
|
312
|
+
| `--surface-600` | |
|
|
313
|
+
| `--surface-700` | |
|
|
314
|
+
| `--surface-800` | |
|
|
315
|
+
| `--surface-900` | |
|
|
316
|
+
| `--surface-950` | |
|
|
317
|
+
| `--text` | The default text color |
|
|
318
|
+
| `--border` | The default border color |
|
|
319
|
+
| `--floating-item-border` | The default border color for floating items |
|
|
320
|
+
| `--floating-item-box-shadow` | The default box shadow for floating items |
|
|
321
|
+
| `--placeholder` | The default placeholder color |
|
|
322
|
+
| `--deleted` | The default background color for deleted messages |
|
|
323
|
+
| `--overlay` | The default background color for overlay |
|
|
324
|
+
| `--chat-notification-badge-background` | The default background color for notification badge |
|
|
325
|
+
| `--chat-notification-badge-text` | The default text color for notification badge |
|
|
326
|
+
|
|
327
|
+
You can override the component's style using CSS custom properties (variables). These are applied directly to `advanced-chat-kai` element:
|
|
328
|
+
|
|
329
|
+
```css
|
|
330
|
+
advanced-chat-kai {
|
|
331
|
+
--success: green;
|
|
332
|
+
--danger: red;
|
|
333
|
+
--warning: yellow;
|
|
334
|
+
--info: blue;
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
All styles are encapsulated in Shadow DOM, so direct CSS selectors from outside will not apply - only CSS variables can be used for styling.
|
|
339
|
+
|
|
340
|
+
## Contributing
|
|
341
|
+
|
|
342
|
+
- Bug fix PRs are always welcome.
|
|
343
|
+
- UI changes or new features should not be submitted without prior discussion. Please open an issue first to propose and discuss them.
|
|
344
|
+
|
|
345
|
+
Thanks for your understanding and contributions.
|
|
346
|
+
|
|
347
|
+
## License
|
|
348
|
+
|
|
349
|
+
[MIT](./LICENSE)
|