@bloonio/chat-angular 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/README.md +112 -0
- package/esm2022/bloonio-chat-angular.mjs +5 -0
- package/esm2022/index.mjs +25 -0
- package/esm2022/lib/bloonio-chat.service.mjs +311 -0
- package/esm2022/lib/bloonio-chat.token.mjs +46 -0
- package/esm2022/lib/components/input-bar.component.mjs +91 -0
- package/esm2022/lib/components/launcher.component.mjs +81 -0
- package/esm2022/lib/components/message-list.component.mjs +58 -0
- package/esm2022/lib/components/panel.component.mjs +211 -0
- package/esm2022/lib/components/quick-replies.component.mjs +58 -0
- package/esm2022/lib/components/thread.component.mjs +103 -0
- package/fesm2022/bloonio-chat-angular.mjs +958 -0
- package/fesm2022/bloonio-chat-angular.mjs.map +1 -0
- package/index.d.ts +27 -0
- package/lib/bloonio-chat.service.d.ts +79 -0
- package/lib/bloonio-chat.token.d.ts +67 -0
- package/lib/components/input-bar.component.d.ts +18 -0
- package/lib/components/launcher.component.d.ts +14 -0
- package/lib/components/message-list.component.d.ts +8 -0
- package/lib/components/panel.component.d.ts +31 -0
- package/lib/components/quick-replies.component.d.ts +10 -0
- package/lib/components/thread.component.d.ts +27 -0
- package/package.json +38 -0
- package/src/lib/styles/chat.css +268 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @bloonio/chat-angular global styles.
|
|
3
|
+
*
|
|
4
|
+
* Consumers import this once — typically in their global stylesheet:
|
|
5
|
+
*
|
|
6
|
+
* @import "@bloonio/chat-angular/styles.css";
|
|
7
|
+
*
|
|
8
|
+
* Or via app.config.ts → styles array. All selectors are scoped under
|
|
9
|
+
* `.bch-*` so the rules don't collide with the host application.
|
|
10
|
+
*
|
|
11
|
+
* Theme tokens (--bch-primary etc.) are inherited from `.bch-root` so a
|
|
12
|
+
* tenant's branding_primary_color applied at runtime flows to every
|
|
13
|
+
* descendant. To override globally, set `--bch-primary` on `:root` or any
|
|
14
|
+
* ancestor of the chat components.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
.bch-root {
|
|
18
|
+
--bch-primary: #5b47c0;
|
|
19
|
+
--bch-primary-contrast: #ffffff;
|
|
20
|
+
--bch-bg: #ffffff;
|
|
21
|
+
--bch-surface: #f7f8fa;
|
|
22
|
+
--bch-text: #1f2937;
|
|
23
|
+
--bch-text-muted: #6b7280;
|
|
24
|
+
--bch-border: #e5e7eb;
|
|
25
|
+
--bch-radius: 12px;
|
|
26
|
+
--bch-shadow: 0 10px 32px rgba(0, 0, 0, 0.14);
|
|
27
|
+
--bch-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
28
|
+
|
|
29
|
+
position: fixed;
|
|
30
|
+
bottom: 24px;
|
|
31
|
+
z-index: 2147483000;
|
|
32
|
+
font-family: var(--bch-font);
|
|
33
|
+
color: var(--bch-text);
|
|
34
|
+
font-size: 14px;
|
|
35
|
+
line-height: 1.5;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.bch-root[data-position="right"] { right: 24px; }
|
|
39
|
+
.bch-root[data-position="left"] { left: 24px; }
|
|
40
|
+
|
|
41
|
+
/* Inline mode — when the component is used inside the page flow rather
|
|
42
|
+
* than as a floating widget, drop the `fixed` positioning. */
|
|
43
|
+
.bch-root[data-mode="docked"],
|
|
44
|
+
.bch-root[data-mode="inline"] {
|
|
45
|
+
position: static;
|
|
46
|
+
width: 100%;
|
|
47
|
+
height: 100%;
|
|
48
|
+
bottom: auto;
|
|
49
|
+
right: auto;
|
|
50
|
+
left: auto;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* ── Launcher ─────────────────────────────────────────────────────────── */
|
|
54
|
+
|
|
55
|
+
.bch-launcher {
|
|
56
|
+
display: flex; align-items: center; gap: 10px;
|
|
57
|
+
background: transparent; border: 0; padding: 0;
|
|
58
|
+
cursor: pointer; font: inherit; color: inherit;
|
|
59
|
+
}
|
|
60
|
+
.bch-launcher-bubble {
|
|
61
|
+
width: 56px; height: 56px;
|
|
62
|
+
border-radius: 9999px;
|
|
63
|
+
background: var(--bch-primary); color: var(--bch-primary-contrast);
|
|
64
|
+
display: flex; align-items: center; justify-content: center;
|
|
65
|
+
box-shadow: var(--bch-shadow);
|
|
66
|
+
transition: transform 120ms ease;
|
|
67
|
+
}
|
|
68
|
+
.bch-launcher:hover .bch-launcher-bubble { transform: translateY(-2px); }
|
|
69
|
+
.bch-launcher-bubble svg { width: 26px; height: 26px; }
|
|
70
|
+
|
|
71
|
+
.bch-launcher-label {
|
|
72
|
+
background: var(--bch-bg); color: var(--bch-text);
|
|
73
|
+
padding: 8px 14px; border-radius: 9999px;
|
|
74
|
+
box-shadow: var(--bch-shadow);
|
|
75
|
+
white-space: nowrap; max-width: 220px;
|
|
76
|
+
overflow: hidden; text-overflow: ellipsis;
|
|
77
|
+
}
|
|
78
|
+
.bch-root[data-position="left"] .bch-launcher { flex-direction: row-reverse; }
|
|
79
|
+
|
|
80
|
+
/* ── Panel ────────────────────────────────────────────────────────────── */
|
|
81
|
+
|
|
82
|
+
.bch-panel {
|
|
83
|
+
position: absolute;
|
|
84
|
+
bottom: 76px;
|
|
85
|
+
width: 360px;
|
|
86
|
+
max-width: calc(100vw - 48px);
|
|
87
|
+
height: 560px;
|
|
88
|
+
max-height: calc(100vh - 120px);
|
|
89
|
+
background: var(--bch-bg);
|
|
90
|
+
border-radius: var(--bch-radius);
|
|
91
|
+
box-shadow: var(--bch-shadow);
|
|
92
|
+
display: flex; flex-direction: column;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
/* Closed state — smooth slide + fade out from the launcher corner. */
|
|
95
|
+
opacity: 0;
|
|
96
|
+
visibility: hidden;
|
|
97
|
+
pointer-events: none;
|
|
98
|
+
transform: translateY(12px) scale(0.96);
|
|
99
|
+
transform-origin: bottom right;
|
|
100
|
+
transition:
|
|
101
|
+
opacity 200ms ease,
|
|
102
|
+
transform 260ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
103
|
+
visibility 0s linear 260ms;
|
|
104
|
+
}
|
|
105
|
+
.bch-root[data-position="right"] .bch-panel { right: 0; }
|
|
106
|
+
.bch-root[data-position="left"] .bch-panel { left: 0; transform-origin: bottom left; }
|
|
107
|
+
.bch-root.bch-open .bch-panel {
|
|
108
|
+
opacity: 1;
|
|
109
|
+
visibility: visible;
|
|
110
|
+
pointer-events: auto;
|
|
111
|
+
transform: translateY(0) scale(1);
|
|
112
|
+
transition:
|
|
113
|
+
opacity 200ms ease,
|
|
114
|
+
transform 260ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
115
|
+
visibility 0s;
|
|
116
|
+
}
|
|
117
|
+
@media (prefers-reduced-motion: reduce) {
|
|
118
|
+
.bch-panel { transition: none; }
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.bch-root[data-mode="docked"] .bch-panel,
|
|
122
|
+
.bch-root[data-mode="inline"] .bch-panel {
|
|
123
|
+
position: static;
|
|
124
|
+
width: 100%;
|
|
125
|
+
height: 100%;
|
|
126
|
+
max-width: none; max-height: none;
|
|
127
|
+
bottom: auto; right: auto; left: auto;
|
|
128
|
+
border-radius: 0;
|
|
129
|
+
box-shadow: none;
|
|
130
|
+
/* Always-on layouts: no open/close animation. */
|
|
131
|
+
opacity: 1;
|
|
132
|
+
visibility: visible;
|
|
133
|
+
pointer-events: auto;
|
|
134
|
+
transform: none;
|
|
135
|
+
transition: none;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* ── Header ───────────────────────────────────────────────────────────── */
|
|
139
|
+
|
|
140
|
+
.bch-header {
|
|
141
|
+
background: var(--bch-primary); color: var(--bch-primary-contrast);
|
|
142
|
+
padding: 16px 16px 18px;
|
|
143
|
+
display: flex; align-items: center; gap: 12px;
|
|
144
|
+
}
|
|
145
|
+
.bch-header-avatar {
|
|
146
|
+
width: 38px; height: 38px; border-radius: 9999px;
|
|
147
|
+
background: rgba(255, 255, 255, 0.18);
|
|
148
|
+
display: flex; align-items: center; justify-content: center;
|
|
149
|
+
overflow: hidden; flex-shrink: 0;
|
|
150
|
+
}
|
|
151
|
+
.bch-header-avatar img { width: 100%; height: 100%; object-fit: cover; }
|
|
152
|
+
.bch-header-title { flex: 1; min-width: 0; }
|
|
153
|
+
.bch-header-name {
|
|
154
|
+
font-weight: 600; font-size: 15px;
|
|
155
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
156
|
+
}
|
|
157
|
+
.bch-header-status {
|
|
158
|
+
font-size: 12px; opacity: 0.85; margin-top: 2px;
|
|
159
|
+
display: flex; align-items: center; gap: 6px;
|
|
160
|
+
}
|
|
161
|
+
.bch-header-status-dot { width: 8px; height: 8px; border-radius: 9999px; }
|
|
162
|
+
.bch-header-status-dot[data-online="true"] { background: #2ecc71; }
|
|
163
|
+
.bch-header-status-dot[data-online="false"] { background: #cbd5e1; }
|
|
164
|
+
.bch-header-close {
|
|
165
|
+
background: transparent; border: 0; color: inherit; cursor: pointer;
|
|
166
|
+
padding: 6px; border-radius: 8px; opacity: 0.85;
|
|
167
|
+
display: flex; align-items: center; justify-content: center;
|
|
168
|
+
}
|
|
169
|
+
.bch-header-close:hover { opacity: 1; background: rgba(255, 255, 255, 0.12); }
|
|
170
|
+
.bch-header-close svg { width: 18px; height: 18px; }
|
|
171
|
+
|
|
172
|
+
/* ── Messages ─────────────────────────────────────────────────────────── */
|
|
173
|
+
|
|
174
|
+
.bch-messages {
|
|
175
|
+
flex: 1; overflow-y: auto;
|
|
176
|
+
padding: 16px; background: var(--bch-surface);
|
|
177
|
+
display: flex; flex-direction: column; gap: 10px;
|
|
178
|
+
}
|
|
179
|
+
.bch-messages::-webkit-scrollbar { width: 8px; }
|
|
180
|
+
.bch-messages::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 4px; }
|
|
181
|
+
|
|
182
|
+
.bch-bubble {
|
|
183
|
+
max-width: 80%; padding: 10px 14px; border-radius: 16px;
|
|
184
|
+
word-wrap: break-word; white-space: pre-wrap;
|
|
185
|
+
}
|
|
186
|
+
.bch-bubble[data-from="visitor"] {
|
|
187
|
+
align-self: flex-end;
|
|
188
|
+
background: var(--bch-primary); color: var(--bch-primary-contrast);
|
|
189
|
+
border-bottom-right-radius: 4px;
|
|
190
|
+
}
|
|
191
|
+
.bch-bubble[data-from="bot"],
|
|
192
|
+
.bch-bubble[data-from="agent"] {
|
|
193
|
+
align-self: flex-start;
|
|
194
|
+
background: var(--bch-bg); color: var(--bch-text);
|
|
195
|
+
border: 1px solid var(--bch-border);
|
|
196
|
+
border-bottom-left-radius: 4px;
|
|
197
|
+
}
|
|
198
|
+
.bch-bubble[data-from="system"] {
|
|
199
|
+
align-self: center;
|
|
200
|
+
background: transparent; color: var(--bch-text-muted);
|
|
201
|
+
font-size: 12px; font-style: italic;
|
|
202
|
+
}
|
|
203
|
+
.bch-bubble[data-pending="true"] { opacity: 0.7; }
|
|
204
|
+
|
|
205
|
+
.bch-typing {
|
|
206
|
+
align-self: flex-start;
|
|
207
|
+
display: flex; gap: 4px;
|
|
208
|
+
padding: 10px 14px; background: var(--bch-bg);
|
|
209
|
+
border: 1px solid var(--bch-border);
|
|
210
|
+
border-radius: 16px; border-bottom-left-radius: 4px;
|
|
211
|
+
}
|
|
212
|
+
.bch-typing span {
|
|
213
|
+
width: 6px; height: 6px; border-radius: 50%;
|
|
214
|
+
background: var(--bch-text-muted);
|
|
215
|
+
animation: bch-typing-bounce 1.2s infinite;
|
|
216
|
+
}
|
|
217
|
+
.bch-typing span:nth-child(2) { animation-delay: 0.15s; }
|
|
218
|
+
.bch-typing span:nth-child(3) { animation-delay: 0.3s; }
|
|
219
|
+
@keyframes bch-typing-bounce {
|
|
220
|
+
0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
|
|
221
|
+
40% { transform: scale(1); opacity: 1; }
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* ── Input ────────────────────────────────────────────────────────────── */
|
|
225
|
+
|
|
226
|
+
.bch-input {
|
|
227
|
+
background: var(--bch-bg); border-top: 1px solid var(--bch-border);
|
|
228
|
+
padding: 10px 12px;
|
|
229
|
+
display: flex; align-items: center; gap: 8px;
|
|
230
|
+
}
|
|
231
|
+
.bch-input textarea {
|
|
232
|
+
flex: 1; resize: none; border: 0; outline: 0;
|
|
233
|
+
font: inherit; color: var(--bch-text); background: transparent;
|
|
234
|
+
padding: 8px 0; min-height: 24px; max-height: 96px; line-height: 1.4;
|
|
235
|
+
}
|
|
236
|
+
.bch-input textarea::placeholder { color: var(--bch-text-muted); }
|
|
237
|
+
.bch-input-send {
|
|
238
|
+
flex-shrink: 0; width: 36px; height: 36px;
|
|
239
|
+
border-radius: 9999px;
|
|
240
|
+
background: var(--bch-primary); color: var(--bch-primary-contrast);
|
|
241
|
+
border: 0; cursor: pointer;
|
|
242
|
+
display: flex; align-items: center; justify-content: center;
|
|
243
|
+
transition: opacity 120ms ease;
|
|
244
|
+
}
|
|
245
|
+
.bch-input-send:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
246
|
+
.bch-input-send svg { width: 18px; height: 18px; }
|
|
247
|
+
|
|
248
|
+
.bch-footer {
|
|
249
|
+
text-align: center; font-size: 11px; color: var(--bch-text-muted);
|
|
250
|
+
padding: 6px 0 10px; background: var(--bch-bg);
|
|
251
|
+
}
|
|
252
|
+
.bch-footer a { color: inherit; text-decoration: none; }
|
|
253
|
+
.bch-footer a:hover { text-decoration: underline; }
|
|
254
|
+
|
|
255
|
+
/* ── Quick-reply chips (tenant opening prompts) ──────────────────────────── */
|
|
256
|
+
.bch-quick-replies {
|
|
257
|
+
display: flex; flex-direction: column; align-items: flex-end;
|
|
258
|
+
gap: 8px; padding: 0 14px 10px; background: var(--bch-bg);
|
|
259
|
+
}
|
|
260
|
+
.bch-quick-reply {
|
|
261
|
+
max-width: 85%;
|
|
262
|
+
border: 1.5px solid var(--bch-primary);
|
|
263
|
+
background: transparent; color: var(--bch-primary);
|
|
264
|
+
border-radius: 9999px; padding: 9px 16px;
|
|
265
|
+
font-size: 14px; line-height: 1.3; text-align: right; cursor: pointer;
|
|
266
|
+
transition: background 120ms ease, color 120ms ease;
|
|
267
|
+
}
|
|
268
|
+
.bch-quick-reply:hover { background: var(--bch-primary); color: var(--bch-primary-contrast); }
|