@cagent/chat-embedding-core 0.0.2 → 0.0.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/AGENTS.md +184 -184
- package/dist/web.js +1 -1
- package/docs/embedding-style-guide.md +417 -0
- package/package.json +4 -3
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
# Hướng dẫn chỉnh style khi nhúng chatbox vào website khác
|
|
2
|
+
|
|
3
|
+
Tài liệu này mô tả **toàn bộ các cách hợp lệ để thay đổi giao diện** của widget
|
|
4
|
+
`@cagent/chat-embedding-core` khi nhúng vào một website bên ngoài, và những giới hạn
|
|
5
|
+
kỹ thuật cần biết trước khi bắt đầu.
|
|
6
|
+
|
|
7
|
+
Nguồn: `src/features/bubble/types.ts`, `src/features/bubble/components/Bubble.tsx`,
|
|
8
|
+
`src/features/full/components/Full.tsx`, `src/assets/index.css`, `src/components/Bot.tsx`.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Điều quan trọng nhất: widget nằm trong Shadow DOM
|
|
13
|
+
|
|
14
|
+
Widget được đăng ký bằng `solid-element` (`src/register.tsx`) thành hai custom element:
|
|
15
|
+
|
|
16
|
+
| Element | Chế độ |
|
|
17
|
+
| ------------------------ | ---------------------------- |
|
|
18
|
+
| `<cagent-chatbot>` | Bubble / popup (`init`) |
|
|
19
|
+
| `<cagent-fullchatbot>` | Full page (`initFull`) |
|
|
20
|
+
|
|
21
|
+
Mỗi element tạo một **shadow root (`mode: "open"`)**. Hệ quả:
|
|
22
|
+
|
|
23
|
+
- **CSS của trang chủ (page CSS) KHÔNG với được vào bên trong widget.** Viết
|
|
24
|
+
`.chatbot-host-bubble { ... }` trong stylesheet của website sẽ không có tác dụng gì.
|
|
25
|
+
- Chỉ có **3 đường vào** để đổi style:
|
|
26
|
+
1. Các key `theme` có kiểu (mục 2) — cách được khuyến nghị.
|
|
27
|
+
2. `theme.customCSS` — CSS được tiêm vào *bên trong* shadow root (mục 3).
|
|
28
|
+
3. `::part()` từ page CSS — chỉ áp dụng cho 2 phần tử được expose (mục 4).
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 2. Cấu hình qua `theme` (khuyến nghị)
|
|
33
|
+
|
|
34
|
+
### 2.1. Khung nhúng
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<script type="module">
|
|
38
|
+
import Chatbot from 'https://cdn.jsdelivr.net/npm/@cagent/chat-embedding-core/dist/web.js';
|
|
39
|
+
|
|
40
|
+
Chatbot.init({
|
|
41
|
+
chatflowid: '<chatflowid>',
|
|
42
|
+
apiHost: 'https://your-backend',
|
|
43
|
+
theme: {
|
|
44
|
+
/* toàn bộ style nằm ở đây */
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Full page thì cần sẵn phần tử trên trang:
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<cagent-fullchatbot></cagent-fullchatbot>
|
|
54
|
+
<script type="module">
|
|
55
|
+
import Chatbot from 'https://cdn.jsdelivr.net/npm/@cagent/chat-embedding-core/dist/web.js';
|
|
56
|
+
Chatbot.initFull({ chatflowid: '<chatflowid>', apiHost: 'https://your-backend', theme: {} });
|
|
57
|
+
</script>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`initFull` cũng nhận `id` để trỏ tới một phần tử cụ thể:
|
|
61
|
+
`Chatbot.initFull({ id: 'my-chat', ... })`. Nếu không tìm thấy phần tử, hàm throw
|
|
62
|
+
`<cagent-fullchatbot> element not found.`
|
|
63
|
+
|
|
64
|
+
Với React, dùng `@cagent/chat-embedding-react` (`<BubbleChat>` / `<FullPageChat>`), prop
|
|
65
|
+
`theme` giữ nguyên cấu trúc bên dưới.
|
|
66
|
+
|
|
67
|
+
### 2.2. `theme.chatWindow` — cửa sổ chat
|
|
68
|
+
|
|
69
|
+
| Key | Kiểu | Mặc định | Tác dụng |
|
|
70
|
+
| ----------------------- | --------- | ---------------- | -------- |
|
|
71
|
+
| `showTitle` | boolean | `true` | Bật/tắt thanh tiêu đề cao 50px. **Lưu ý:** thanh này chứa nút *Clear* (xoá hội thoại) và *Full Screen*; tắt đi là mất luôn các nút đó. |
|
|
72
|
+
| `title` | string | – | Chữ trên thanh tiêu đề. Chỉ render khi khác rỗng. |
|
|
73
|
+
| `titleAvatarSrc` | string | – | Avatar bên trái tiêu đề. |
|
|
74
|
+
| `backgroundColor` | string | `#ffffff` | Màu nền cửa sổ chat. |
|
|
75
|
+
| `backgroundImage` | string | `none` | Ảnh nền (`cover` / `center` / `no-repeat`). |
|
|
76
|
+
| `height` | number | popup: `calc(100% - 150px)`, full: `100dvh` | Chiều cao, **đơn vị px, truyền số**. |
|
|
77
|
+
| `width` | number | popup: `400`, full: `100%` | Chiều rộng, px. |
|
|
78
|
+
| `fontSize` | number | `16` | Cỡ chữ (px) của bubble tin nhắn. |
|
|
79
|
+
| `poweredByTextColor` | string | `#303235` | Màu chữ footer khi `footer.textColor` không đặt. |
|
|
80
|
+
| `starterPromptFontSize` | number | `15` | Cỡ chữ gợi ý mở đầu. |
|
|
81
|
+
| `sourceDocsTitle` | string | – | Tiêu đề khối nguồn tài liệu. |
|
|
82
|
+
| `welcomeMessage` | string | từ backend | Tin nhắn chào. Bỏ trống để dùng cấu hình riêng của từng agent. |
|
|
83
|
+
| `secondMessage` | string | – | Tin nhắn thứ hai. |
|
|
84
|
+
| `errorMessage` | string | – | Thông báo lỗi. |
|
|
85
|
+
| `starterPrompts` | string[] | từ backend | Gợi ý mở đầu. Bỏ trống để dùng cấu hình của agent. |
|
|
86
|
+
| `showAgentMessages` | boolean | `false` | Hiện khối "Agent Messages" (reasoning). |
|
|
87
|
+
| `renderHTML` | boolean | – | Cho phép render HTML trong tin nhắn. |
|
|
88
|
+
| `showResponseTime` | boolean | `false` | Hiện thời gian phản hồi. |
|
|
89
|
+
| `clearChatOnReload` | boolean | – | Xoá hội thoại khi tải lại trang. |
|
|
90
|
+
| `dateTimeToggle` | `{date,time}` | – | Hiện ngày / giờ dưới mỗi tin nhắn. |
|
|
91
|
+
|
|
92
|
+
### 2.3. `theme.chatWindow.botMessage` / `userMessage`
|
|
93
|
+
|
|
94
|
+
| Key | Mặc định (bot / user) |
|
|
95
|
+
| ----------------- | -------------------------- |
|
|
96
|
+
| `backgroundColor` | `#f7f8ff` / `#3B81F6` |
|
|
97
|
+
| `textColor` | `#303235` / `#ffffff` |
|
|
98
|
+
| `showAvatar` | `false` |
|
|
99
|
+
| `avatarSrc` | – |
|
|
100
|
+
|
|
101
|
+
`border-radius` của bubble bị hardcode `6px` bằng inline style — muốn đổi phải dùng
|
|
102
|
+
`customCSS` với `!important`.
|
|
103
|
+
|
|
104
|
+
### 2.4. `theme.chatWindow.textInput`
|
|
105
|
+
|
|
106
|
+
| Key | Mặc định |
|
|
107
|
+
| ------------------------ | ------------------------------- |
|
|
108
|
+
| `backgroundColor` | `#ffffff` |
|
|
109
|
+
| `textColor` | `#303235` |
|
|
110
|
+
| `placeholder` | `Nhập nội dung cần giải đáp` |
|
|
111
|
+
| `sendButtonColor` | – |
|
|
112
|
+
| `maxChars` | – (không giới hạn) |
|
|
113
|
+
| `maxCharsWarningMessage` | – |
|
|
114
|
+
| `autoFocus` | – |
|
|
115
|
+
| `sendMessageSound` | – |
|
|
116
|
+
| `sendSoundLocation` | `send_message.mp3` |
|
|
117
|
+
| `receiveMessageSound` | – |
|
|
118
|
+
| `receiveSoundLocation` | `receive_message.mp3` |
|
|
119
|
+
|
|
120
|
+
### 2.5. `theme.chatWindow.footer`
|
|
121
|
+
|
|
122
|
+
| Key | Mặc định |
|
|
123
|
+
| -------------- | ------------------------- |
|
|
124
|
+
| `showFooter` | `true` |
|
|
125
|
+
| `text` | `Powered by` |
|
|
126
|
+
| `company` | `C-agent` |
|
|
127
|
+
| `companyLink` | `https://cmcts.com.vn/` |
|
|
128
|
+
| `textColor` | `#303235` |
|
|
129
|
+
|
|
130
|
+
`showFooter: false` **không xoá footer** mà chỉ render một dải trống cùng chiều cao
|
|
131
|
+
(~35px) — đây là hành vi cố ý trong `src/components/Badge.tsx`. Muốn thu hồi khoảng
|
|
132
|
+
trắng đó phải dùng `customCSS`. Ngoài ra một `MutationObserver` sẽ tự chèn lại badge
|
|
133
|
+
nếu bị xoá khỏi DOM, nên đừng cố xoá bằng JS.
|
|
134
|
+
|
|
135
|
+
### 2.6. `theme.chatWindow.feedback`
|
|
136
|
+
|
|
137
|
+
| Key | Mặc định | Tác dụng |
|
|
138
|
+
| ------- | --------- | --------------------------------- |
|
|
139
|
+
| `color` | `#303235` | Màu icon like/dislike/copy/edit. |
|
|
140
|
+
|
|
141
|
+
### 2.7. `theme.button` — bubble nổi (chỉ chế độ popup)
|
|
142
|
+
|
|
143
|
+
| Key | Mặc định | Ghi chú |
|
|
144
|
+
| ----------------- | ------------ | ------- |
|
|
145
|
+
| `backgroundColor` | `#3B81F6` | |
|
|
146
|
+
| `iconColor` | `white` | Cũng là màu icon *Clear* / *Full Screen* / nút đóng trên thanh tiêu đề — đây là cách duy nhất đổi màu các icon đó vì chúng dùng thuộc tính SVG `stroke`/`fill`, CSS `color` không với tới. |
|
|
147
|
+
| `customIconSrc` | – | Icon tuỳ chọn thay hình mặc định. |
|
|
148
|
+
| `dragAndDrop` | `false` | Cho kéo bubble ngang. |
|
|
149
|
+
| `size` | `48` | **Hiện không có hiệu lực** — `BubbleButton` luôn gọi `getBubbleButtonSize('medium')` → 48px. Muốn đổi phải dùng `customCSS` / `::part(button)`. |
|
|
150
|
+
| `bottom` / `right`| `20` | Chỉ ảnh hưởng vị trí *cửa sổ chat*; bản thân nút bị hardcode `right: 20px; bottom: 20px`. |
|
|
151
|
+
| `autoWindowOpen` | `{autoOpen, openDelay, autoOpenOnMobile}` | `openDelay` tính bằng giây (mặc định 2). |
|
|
152
|
+
|
|
153
|
+
### 2.8. `theme.tooltip`
|
|
154
|
+
|
|
155
|
+
`showTooltip`, `tooltipMessage`, `tooltipBackgroundColor` (mặc định `black`),
|
|
156
|
+
`tooltipTextColor` (`white`), `tooltipFontSize` (`12`).
|
|
157
|
+
|
|
158
|
+
### 2.9. `theme.disclaimer` — popup điều khoản
|
|
159
|
+
|
|
160
|
+
`title` (`Disclaimer`), `message` (nhận HTML), `textColor` (`black`),
|
|
161
|
+
`buttonColor` (`#3b82f6`), `buttonText` (`Start Chatting`), `buttonTextColor` (`white`),
|
|
162
|
+
`backgroundColor` (`white`), `blurredBackgroundColor` (`rgba(0,0,0,0.4)`).
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 3. `theme.customCSS` — cửa thoát duy nhất cho phần còn lại
|
|
167
|
+
|
|
168
|
+
```js
|
|
169
|
+
theme: {
|
|
170
|
+
customCSS: `
|
|
171
|
+
.chatbot-host-bubble.prose { max-width: 100%; }
|
|
172
|
+
`,
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 3.1. Hai luật bắt buộc phải nhớ
|
|
177
|
+
|
|
178
|
+
**a) `customCSS` được tiêm TRƯỚC stylesheet của widget.**
|
|
179
|
+
Trong cả `Full.tsx` và `Bubble.tsx`:
|
|
180
|
+
|
|
181
|
+
```jsx
|
|
182
|
+
<Show when={props.theme?.customCSS}><style>{props.theme?.customCSS}</style></Show>
|
|
183
|
+
<style>{styles}</style>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Vì `<style>` của widget đứng sau, **khi cùng độ đặc hiệu (specificity) thì widget
|
|
187
|
+
thắng**. Do đó rule của bạn phải:
|
|
188
|
+
|
|
189
|
+
- có specificity cao hơn (ví dụ `.chatbot-host-bubble.prose` — hai class), hoặc
|
|
190
|
+
- dùng `!important`.
|
|
191
|
+
|
|
192
|
+
Đây là lý do các rule ghi đè `:host { --chatbot-... }` **không hoạt động** nếu không có
|
|
193
|
+
`!important`: widget cũng khai báo `:host` với cùng specificity.
|
|
194
|
+
|
|
195
|
+
**b) Inline style luôn thắng CSS thường.** Rất nhiều màu được set bằng inline style
|
|
196
|
+
(nền bubble, nền cửa sổ, nền thanh tiêu đề…). Ghi đè chúng bắt buộc phải `!important`.
|
|
197
|
+
|
|
198
|
+
### 3.2. Bảng class hook (dùng cho `customCSS`)
|
|
199
|
+
|
|
200
|
+
| Selector | Phần tử |
|
|
201
|
+
| ----------------------------------------------- | ------- |
|
|
202
|
+
| `.chatbot-container` | Container ngoài cùng của bot (nơi set `font-family: 'Open Sans'`). |
|
|
203
|
+
| `.chatbot-chat-view` | Vùng cuộn danh sách tin nhắn (`max-width: 800px`). |
|
|
204
|
+
| `.host-container` | Hàng chứa tin nhắn của bot. |
|
|
205
|
+
| `.guest-container` | Hàng chứa tin nhắn của người dùng. |
|
|
206
|
+
| `.chatbot-host-bubble` | Bubble bot, gợi ý mở đầu, follow-up, nguồn, loading. |
|
|
207
|
+
| `.chatbot-host-bubble.prose` | Bubble bot có markdown — bị `max-width: 65ch` của Tailwind Typography. |
|
|
208
|
+
| `.chatbot-guest-bubble` | Bubble người dùng. |
|
|
209
|
+
| `.chatbot-input` | Khối ô nhập (wrapper, `border-radius: 12px`). |
|
|
210
|
+
| `.auto-expanding-textarea` | Chính `<textarea>` nhập liệu. |
|
|
211
|
+
| `.chatbot-button` | Các nút gửi / clear / full screen / feedback. |
|
|
212
|
+
| `.chatbot-button > .send-icon` | Icon trong nút. |
|
|
213
|
+
| `.rating-icon-container` | Khối icon đánh giá (SVG 42×42). |
|
|
214
|
+
| `.chatbot-host-bubble table` (+ `th`, `td`, `tr`)| Bảng trong câu trả lời markdown. |
|
|
215
|
+
| `.chart-bubble-container` | Khung chart. Widget khai báo `background-color: #fefefe !important` để chống ghi đè — ghi đè lại cần `!important` và specificity cao hơn. |
|
|
216
|
+
| `.lite-badge` | Link công ty trong footer. |
|
|
217
|
+
| `.messagelist`, `.markdownanswer`, `.apimessage`, `.usermessage` | Các class kế thừa từ layout cũ. |
|
|
218
|
+
| `.tooltip` | Tooltip của bubble. |
|
|
219
|
+
| `.spinner` | Vòng xoay loading. |
|
|
220
|
+
| `div[part='bot']` | Khung cửa sổ chat (chế độ popup). |
|
|
221
|
+
| `div[part='button']` | Nút bubble nổi. |
|
|
222
|
+
|
|
223
|
+
Thanh tiêu đề **không có class riêng**. Cách match ổn định nhất (giống chính stylesheet
|
|
224
|
+
của widget) là dựa vào utility class:
|
|
225
|
+
|
|
226
|
+
```css
|
|
227
|
+
div[class*="h-[50px]"][class*="absolute"] { background: transparent !important; }
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Đừng match theo full class string — thứ tự utility class có thể đổi sau mỗi bản build.
|
|
231
|
+
|
|
232
|
+
### 3.3. Biến CSS khai báo trên `:host`
|
|
233
|
+
|
|
234
|
+
Widget định nghĩa sẵn (`src/assets/index.css`):
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
--chatbot-container-bg-image, --chatbot-container-bg-color, --chatbot-container-font-family
|
|
238
|
+
--chatbot-button-bg-color, --chatbot-button-color
|
|
239
|
+
--chatbot-host-bubble-bg-color, --chatbot-host-bubble-color
|
|
240
|
+
--chatbot-guest-bubble-bg-color, --chatbot-guest-bubble-color
|
|
241
|
+
--chatbot-input-bg-color, --chatbot-input-color, --chatbot-input-placeholder-color
|
|
242
|
+
--chatbot-header-bg-color, --chatbot-header-color
|
|
243
|
+
--chatbot-border-radius
|
|
244
|
+
--tooltip-background-color, --tooltip-text-color, --tooltip-font-size
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Cảnh báo: **nhiều biến trong danh sách này không được stylesheet dùng tới** (ví dụ
|
|
248
|
+
`--chatbot-host-bubble-bg-color`, `--chatbot-input-bg-color`, `--chatbot-header-*` —
|
|
249
|
+
các chỗ tương ứng đang hardcode màu). Chỉ nên tin vào các biến thực sự được tham chiếu:
|
|
250
|
+
`--chatbot-border-radius`, `--chatbot-button-color`, `--chatbot-host-bubble-color`,
|
|
251
|
+
`--chatbot-guest-bubble-color`, `--chatbot-container-bg-*`, `--tooltip-*`.
|
|
252
|
+
|
|
253
|
+
Ghi đè phải kèm `!important` (xem 3.1a):
|
|
254
|
+
|
|
255
|
+
```css
|
|
256
|
+
:host { --chatbot-border-radius: 12px !important; }
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### 3.4. Những giá trị hardcode chỉ sửa được bằng `customCSS`
|
|
260
|
+
|
|
261
|
+
| Thứ | Giá trị hardcode | Cách xử lý |
|
|
262
|
+
| -------------------------------- | --------------------------------- | ---------- |
|
|
263
|
+
| Nền thanh tiêu đề | `#005FAB` (inline style) | `div[class*="h-[50px]"][class*="absolute"] { background: … !important }` |
|
|
264
|
+
| Nền / viền khối nhập liệu | `bg-[#F9F9F9]`, `border-[#E4E4E4]`| override qua `.chatbot-input > div` |
|
|
265
|
+
| Màu link trong tin nhắn | `#16bed7` | `.markdownanswer a`, `a` |
|
|
266
|
+
| Màu inline code | `#15cb19` | `.markdownanswer code` |
|
|
267
|
+
| Font chữ | `'Open Sans'` + fallback stack | `.chatbot-container { font-family: … !important }` |
|
|
268
|
+
| Bo góc bubble | `6px` (inline) | `!important` |
|
|
269
|
+
| Chiều rộng tối đa vùng chat | `max-width: 800px` | `.chatbot-chat-view` |
|
|
270
|
+
| Toàn bộ style bảng markdown | xem `index.css` dòng 218–258 | override selector tương ứng |
|
|
271
|
+
| Chiều cao thanh tiêu đề / offset | `h-[50px]`, `mt-[50px]`, `pt-[30px]` | override nếu đổi chiều cao thanh tiêu đề |
|
|
272
|
+
| `z-index` widget | `42424242` | override qua `::part()` nếu xung đột |
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 4. `::part()` — đường vào duy nhất từ page CSS
|
|
277
|
+
|
|
278
|
+
Widget expose hai part, nên **CSS của trang chủ có thể style trực tiếp** (không cần
|
|
279
|
+
`customCSS`):
|
|
280
|
+
|
|
281
|
+
```css
|
|
282
|
+
cagent-chatbot::part(bot) { border-radius: 16px; box-shadow: none; }
|
|
283
|
+
cagent-chatbot::part(button) { width: 56px; height: 56px; }
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
- `part="bot"` — khung cửa sổ chat (chế độ popup).
|
|
287
|
+
- `part="button"` — nút bubble nổi.
|
|
288
|
+
|
|
289
|
+
Đây là cách sạch nhất để đổi kích thước nút bubble (vì `theme.button.size` chưa có hiệu
|
|
290
|
+
lực) và để sửa `z-index` khi widget đè lên header của website.
|
|
291
|
+
|
|
292
|
+
Lưu ý: `::part()` chỉ chạm được phần tử gốc mang thuộc tính `part`, **không** đi sâu vào
|
|
293
|
+
con của nó.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## 5. Ghi chú theo từng chế độ
|
|
298
|
+
|
|
299
|
+
### 5.1. Full page
|
|
300
|
+
|
|
301
|
+
- Muốn thật sự full màn hình: `body { margin: 0 }` và **không set** `chatWindow.height`
|
|
302
|
+
/ `chatWindow.width`. Khi đó widget dùng `100dvh` × `100%`.
|
|
303
|
+
- Component tự set `document.body.style.margin = '0'`,
|
|
304
|
+
`document.documentElement.style.padding = '0'` và ghi đè thẻ meta `viewport` thành
|
|
305
|
+
`interactive-widget=resizes-content` khi hiển thị (khôi phục lúc unmount). Nếu trang
|
|
306
|
+
chủ dựa vào margin của body thì cần biết điều này.
|
|
307
|
+
- Bot chỉ khởi tạo khi phần tử vào viewport (`IntersectionObserver`) — phần tử ẩn hoàn
|
|
308
|
+
toàn sẽ không render.
|
|
309
|
+
- Chế độ này không vẽ nút bubble; `theme.button` khi đó chỉ còn tác dụng qua `iconColor`.
|
|
310
|
+
|
|
311
|
+
### 5.2. Popup / bubble
|
|
312
|
+
|
|
313
|
+
- Người dùng có thể **kéo đổi chiều rộng** (400–800px) và **đổi zoom** (80–120%, bước
|
|
314
|
+
5%). Hai giá trị này lưu ở `localStorage`: `cmcts:chatWindowWidth`, `cmcts:chatScale`,
|
|
315
|
+
và **ghi đè `theme.chatWindow.width`** ở các lần mở sau.
|
|
316
|
+
- Dưới **640px**, `index.css` buộc `div[part='bot']` thành fixed full-screen và bỏ mọi
|
|
317
|
+
bo góc bằng `!important`. Mọi rule responsive của bạn phải tính tới breakpoint này.
|
|
318
|
+
- Cửa sổ chat luôn bị chặn `max-height: 704px` (trừ chế độ full screen).
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## 6. Thứ tự ưu tiên khi giải quyết xung đột
|
|
323
|
+
|
|
324
|
+
1. Có key `theme` không? → dùng key đó. Bền nhất, không phụ thuộc tên class nội bộ.
|
|
325
|
+
2. Là màu icon SVG (`stroke`/`fill`)? → chỉ đi được qua `theme.button.iconColor` hoặc
|
|
326
|
+
`theme.chatWindow.feedback.color`; CSS `color` vô dụng.
|
|
327
|
+
3. Là phần tử `part="bot"` / `part="button"`? → page CSS `::part()`.
|
|
328
|
+
4. Còn lại → `theme.customCSS`, ưu tiên tăng specificity trước khi dùng `!important`.
|
|
329
|
+
|
|
330
|
+
**Rủi ro của `customCSS`:** nó phụ thuộc vào tên class và utility class nội bộ của
|
|
331
|
+
widget. Nếu bản build sau đổi tên, rule sẽ **âm thầm mất tác dụng** (quay về style gốc
|
|
332
|
+
của widget, không gây lỗi). Vì vậy hạn chế dùng, chỉ dùng cho những chỗ `theme` không
|
|
333
|
+
phủ tới, và ghi comment lý do.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## 7. Ví dụ hoàn chỉnh
|
|
338
|
+
|
|
339
|
+
```html
|
|
340
|
+
<script type="module">
|
|
341
|
+
import Chatbot from 'https://cdn.jsdelivr.net/npm/@cagent/chat-embedding-core/dist/web.js';
|
|
342
|
+
|
|
343
|
+
const ACCENT = '#0056DE';
|
|
344
|
+
const SURFACE_SUNKEN = '#F7F8FA';
|
|
345
|
+
const TEXT = '#101828';
|
|
346
|
+
const TEXT_MUTED = '#667085';
|
|
347
|
+
|
|
348
|
+
Chatbot.init({
|
|
349
|
+
chatflowid: '<chatflowid>',
|
|
350
|
+
apiHost: 'https://your-backend',
|
|
351
|
+
theme: {
|
|
352
|
+
chatWindow: {
|
|
353
|
+
// Giữ thanh tiêu đề để không mất nút Clear, nhưng bỏ chữ để tránh
|
|
354
|
+
// trùng heading của trang; nền thanh được làm trong suốt ở customCSS.
|
|
355
|
+
showTitle: true,
|
|
356
|
+
title: '',
|
|
357
|
+
backgroundColor: '#FFFFFF',
|
|
358
|
+
height: 640,
|
|
359
|
+
width: 420,
|
|
360
|
+
fontSize: 15,
|
|
361
|
+
botMessage: { backgroundColor: SURFACE_SUNKEN, textColor: TEXT, showAvatar: false },
|
|
362
|
+
userMessage: { backgroundColor: ACCENT, textColor: '#FFFFFF', showAvatar: false },
|
|
363
|
+
textInput: {
|
|
364
|
+
backgroundColor: '#FFFFFF',
|
|
365
|
+
textColor: TEXT,
|
|
366
|
+
sendButtonColor: ACCENT,
|
|
367
|
+
placeholder: 'Nhập câu hỏi của bạn',
|
|
368
|
+
autoFocus: true,
|
|
369
|
+
},
|
|
370
|
+
feedback: { color: TEXT_MUTED },
|
|
371
|
+
footer: { showFooter: false },
|
|
372
|
+
poweredByTextColor: TEXT_MUTED,
|
|
373
|
+
errorMessage: 'Không thể kết nối tới agent. Vui lòng thử lại.',
|
|
374
|
+
},
|
|
375
|
+
// Màu icon SVG trên thanh tiêu đề (Clear / Full Screen / đóng) — mặc định
|
|
376
|
+
// trắng, sẽ vô hình trên thanh nền sáng.
|
|
377
|
+
button: { backgroundColor: ACCENT, iconColor: TEXT_MUTED },
|
|
378
|
+
customCSS: `
|
|
379
|
+
/* Nền thanh tiêu đề bị hardcode #005FAB bằng inline style → cần !important. */
|
|
380
|
+
div[class*="h-[50px]"][class*="absolute"] { background: transparent !important; }
|
|
381
|
+
|
|
382
|
+
/* Bỏ giới hạn 65ch của Tailwind prose. Hai class → đủ specificity, không cần !important. */
|
|
383
|
+
.chatbot-host-bubble.prose { max-width: 100%; }
|
|
384
|
+
|
|
385
|
+
/* Font của website chủ. .chatbot-container hardcode 'Open Sans'. */
|
|
386
|
+
.chatbot-container { font-family: 'Inter', sans-serif !important; }
|
|
387
|
+
|
|
388
|
+
:host { --chatbot-border-radius: 10px !important; }
|
|
389
|
+
`,
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
</script>
|
|
393
|
+
|
|
394
|
+
<style>
|
|
395
|
+
/* Page CSS chỉ với được vào widget qua ::part(). */
|
|
396
|
+
cagent-chatbot::part(button) { width: 56px; height: 56px; }
|
|
397
|
+
cagent-chatbot::part(bot) { border-radius: 16px; }
|
|
398
|
+
</style>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## 8. Debug
|
|
404
|
+
|
|
405
|
+
1. Mở DevTools → chọn `<cagent-chatbot>` → mở `#shadow-root (open)` để xem cây DOM và
|
|
406
|
+
class thật.
|
|
407
|
+
2. Nếu rule không áp dụng: kiểm tra theo thứ tự (a) có bị inline style đè không,
|
|
408
|
+
(b) `customCSS` đứng trước stylesheet widget nên có bị cùng-specificity đè không,
|
|
409
|
+
(c) tên class có còn tồn tại trong bản build đang dùng không.
|
|
410
|
+
3. Liệt kê nhanh các theme key mà bản build hiện tại thực sự đọc:
|
|
411
|
+
```bash
|
|
412
|
+
grep -oE 'theme\?\.chatWindow\?\.[a-zA-Z]+' web.js | sort -u
|
|
413
|
+
```
|
|
414
|
+
4. Widget tự gọi `GET /api/v1/public-chatbotConfig/:chatflowid` và cache vào
|
|
415
|
+
`localStorage` key `chatbotConfig_<chatflowid>`. Config này chỉ điền vào chỗ trống:
|
|
416
|
+
`theme` truyền tường minh **luôn thắng**, trừ `welcomeMessage` và `starterPrompts` —
|
|
417
|
+
bỏ trống hai key đó thì cấu hình riêng của từng agent sẽ được dùng.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cagent/chat-embedding-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Javascript library to display the Agent Studio chatbot on your website",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,md,mdx}\"",
|
|
16
16
|
"prepare": "husky install",
|
|
17
17
|
"start": "node server.js",
|
|
18
|
-
"build-and-publish": "
|
|
19
|
-
"prepublishOnly": "
|
|
18
|
+
"build-and-publish": "npm publish",
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"postpublish": "node -e \"const fs=require('fs');const v=require('./package.json').version;const p='../cagent-frontend/package.json';const j=JSON.parse(fs.readFileSync(p));j.dependencies['@cagent/chat-embedding-core']=v;fs.writeFileSync(p,JSON.stringify(j,null,2)+'\\n')\""
|
|
20
21
|
},
|
|
21
22
|
"license": "MIT",
|
|
22
23
|
"dependencies": {
|