@bbki.ng/bb-msg-history 0.2.0 → 0.4.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.
Files changed (45) hide show
  1. package/README.md +44 -0
  2. package/dist/component.d.ts +37 -0
  3. package/dist/component.js +178 -0
  4. package/dist/const/authors.d.ts +10 -0
  5. package/dist/const/authors.js +29 -0
  6. package/dist/const/styles.d.ts +12 -0
  7. package/dist/const/styles.js +360 -0
  8. package/dist/const/theme.d.ts +6 -0
  9. package/dist/const/theme.js +32 -0
  10. package/dist/index.d.ts +4 -41
  11. package/dist/index.dev.js +8 -542
  12. package/dist/index.js +1 -1
  13. package/dist/types/index.d.ts +33 -0
  14. package/dist/types/index.js +4 -0
  15. package/dist/utils/author-resolver.d.ts +11 -0
  16. package/dist/utils/author-resolver.js +71 -0
  17. package/dist/utils/avatar.d.ts +4 -0
  18. package/dist/utils/avatar.js +18 -0
  19. package/dist/utils/html.d.ts +12 -0
  20. package/dist/utils/html.js +33 -0
  21. package/dist/utils/message-builder.d.ts +13 -0
  22. package/dist/utils/message-builder.js +49 -0
  23. package/dist/utils/message-parser.d.ts +6 -0
  24. package/dist/utils/message-parser.js +22 -0
  25. package/dist/utils/registration.d.ts +8 -0
  26. package/dist/utils/registration.js +29 -0
  27. package/dist/utils/scroll-button.d.ts +4 -0
  28. package/dist/utils/scroll-button.js +12 -0
  29. package/dist/utils/tooltip.d.ts +5 -0
  30. package/dist/utils/tooltip.js +17 -0
  31. package/package.json +7 -6
  32. package/src/component.ts +217 -0
  33. package/src/const/authors.ts +32 -0
  34. package/src/const/styles.ts +363 -0
  35. package/src/const/theme.ts +34 -0
  36. package/src/index.ts +11 -602
  37. package/src/types/index.ts +37 -0
  38. package/src/utils/author-resolver.ts +81 -0
  39. package/src/utils/avatar.ts +19 -0
  40. package/src/utils/html.ts +35 -0
  41. package/src/utils/message-builder.ts +58 -0
  42. package/src/utils/message-parser.ts +27 -0
  43. package/src/utils/registration.ts +35 -0
  44. package/src/utils/scroll-button.ts +12 -0
  45. package/src/utils/tooltip.ts +16 -0
@@ -0,0 +1,363 @@
1
+ import { THEME } from './theme.js';
2
+
3
+ /**
4
+ * Main component styles
5
+ */
6
+ export const MAIN_STYLES = `
7
+ :host {
8
+ display: block;
9
+ position: relative;
10
+ font-family: "PT Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
11
+ "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
12
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
13
+ "Noto Color Emoji";
14
+ --bb-bg-color: ${THEME.gray[50]};
15
+ --bb-max-height: 600px;
16
+ }
17
+
18
+ .history {
19
+ margin: 0 auto;
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: 0.25rem;
23
+ max-height: var(--bb-max-height, 600px);
24
+ overflow-y: auto;
25
+ scroll-behavior: smooth;
26
+ background-color: transparent;
27
+ border-radius: 0.5rem;
28
+ /* Firefox scrollbar */
29
+ scrollbar-width: thin;
30
+ scrollbar-color: ${THEME.gray[400]} transparent;
31
+ }
32
+
33
+ /* Custom scrollbar for webkit browsers */
34
+ .history::-webkit-scrollbar {
35
+ width: 6px;
36
+ }
37
+
38
+ .history::-webkit-scrollbar-track {
39
+ background: transparent;
40
+ border-radius: 3px;
41
+ }
42
+
43
+ .history::-webkit-scrollbar-thumb {
44
+ background: ${THEME.gray[400]};
45
+ border-radius: 3px;
46
+ }
47
+
48
+ .history::-webkit-scrollbar-thumb:hover {
49
+ background: ${THEME.gray[500]};
50
+ }
51
+
52
+ /* Scroll to bottom button */
53
+ .scroll-to-bottom {
54
+ position: absolute;
55
+ bottom: 16px;
56
+ left: 50%;
57
+ width: 36px;
58
+ height: 36px;
59
+ border-radius: 50%;
60
+ background: transparent;
61
+ border: none;
62
+ color: ${THEME.gray[500]};
63
+ cursor: pointer;
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: center;
67
+ opacity: 0;
68
+ visibility: hidden;
69
+ transform: translateX(-50%) translateY(10px) scale(0.9);
70
+ transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s ease;
71
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
72
+ z-index: 10;
73
+ }
74
+
75
+ .scroll-to-bottom.visible {
76
+ opacity: 1;
77
+ visibility: visible;
78
+ transform: translateX(-50%) translateY(0) scale(1);
79
+ }
80
+
81
+ .scroll-to-bottom:hover {
82
+ color: ${THEME.gray[700]};
83
+ transform: translateX(-50%) translateY(-2px);
84
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
85
+ }
86
+
87
+ .scroll-to-bottom:active {
88
+ transform: translateX(-50%) translateY(0) scale(0.95);
89
+ }
90
+
91
+ .scroll-to-bottom svg {
92
+ width: 20px;
93
+ height: 20px;
94
+ }
95
+
96
+ /* Message row layout */
97
+ .msg-row {
98
+ display: flex;
99
+ align-items: flex-end;
100
+ gap: 0.5rem;
101
+ max-width: 80%;
102
+ }
103
+
104
+ .msg-row--left {
105
+ align-self: flex-start;
106
+ margin-right: auto;
107
+ }
108
+
109
+ .msg-row--right {
110
+ align-self: flex-end;
111
+ margin-left: auto;
112
+ }
113
+
114
+ .msg-row--subsequent {
115
+ margin-top: 0.125rem;
116
+ }
117
+
118
+ .msg-row--new-author {
119
+ margin-top: 0.75rem;
120
+ }
121
+
122
+ .msg-row--new-author:first-child {
123
+ margin-top: 0;
124
+ }
125
+
126
+ /* Avatar container */
127
+ .avatar-wrapper {
128
+ position: relative;
129
+ flex-shrink: 0;
130
+ width: 1.75rem;
131
+ height: 1.75rem;
132
+ background: #ffffff;
133
+ border-radius: 50%;
134
+ overflow: hidden;
135
+ cursor: help;
136
+ }
137
+
138
+ .avatar-wrapper--hidden {
139
+ opacity: 0;
140
+ pointer-events: none;
141
+ }
142
+
143
+ .avatar {
144
+ width: 100%;
145
+ height: 100%;
146
+ display: flex;
147
+ align-items: center;
148
+ justify-content: center;
149
+ border-radius: 50%;
150
+ overflow: hidden;
151
+ }
152
+
153
+ .avatar svg {
154
+ width: 100%;
155
+ height: 100%;
156
+ }
157
+
158
+ /* Hover tooltip */
159
+ .avatar-tooltip {
160
+ position: fixed;
161
+ padding: 0.25rem 0.5rem;
162
+ background: ${THEME.gray[800]};
163
+ color: ${THEME.gray[50]};
164
+ font-size: 0.75rem;
165
+ border-radius: 0.25rem;
166
+ white-space: nowrap;
167
+ opacity: 0;
168
+ visibility: hidden;
169
+ pointer-events: none;
170
+ z-index: 10;
171
+ font-weight: 500;
172
+ letter-spacing: 0.02em;
173
+ }
174
+
175
+ .avatar-tooltip::after {
176
+ content: '';
177
+ position: absolute;
178
+ top: calc(100% - 1px);
179
+ left: 50%;
180
+ transform: translateX(-50%);
181
+ border: 4px solid transparent;
182
+ border-top-color: ${THEME.gray[800]};
183
+ }
184
+
185
+ .avatar-wrapper:hover .avatar-tooltip {
186
+ opacity: 1;
187
+ visibility: visible;
188
+ }
189
+
190
+ /* Message content area */
191
+ .msg-content {
192
+ display: flex;
193
+ flex-direction: column;
194
+ }
195
+
196
+ .msg-bubble {
197
+ padding: 0.625rem 0.875rem;
198
+ font-size: 0.9375rem;
199
+ line-height: 1.5;
200
+ word-wrap: break-word;
201
+ overflow-wrap: anywhere;
202
+ word-break: break-word;
203
+ border-radius: 1rem;
204
+ }
205
+
206
+ /* Left bubble */
207
+ .msg-bubble--left {
208
+ border-bottom-left-radius: 0.25rem;
209
+ background-color: ${THEME.gray[200]};
210
+ color: ${THEME.gray[900]};
211
+ }
212
+
213
+ /* Right bubble */
214
+ .msg-bubble--right {
215
+ border-bottom-right-radius: 0.25rem;
216
+ }
217
+
218
+ /* Empty state */
219
+ .empty-state {
220
+ text-align: center;
221
+ padding: 2rem;
222
+ color: ${THEME.gray[400]};
223
+ font-size: 0.875rem;
224
+ }
225
+
226
+ /* Mobile responsive */
227
+ @media (max-width: 480px) {
228
+ .history {
229
+ max-height: var(--bb-max-height, 70vh);
230
+ }
231
+
232
+ .msg-row {
233
+ max-width: 85%;
234
+ }
235
+
236
+ .msg-bubble {
237
+ font-size: 0.9375rem;
238
+ padding: 0.5rem 0.75rem;
239
+ }
240
+
241
+ .avatar-wrapper {
242
+ width: 1.5rem;
243
+ height: 1.5rem;
244
+ }
245
+
246
+ .scroll-to-bottom {
247
+ width: 32px;
248
+ height: 32px;
249
+ bottom: 12px;
250
+ }
251
+
252
+ .scroll-to-bottom svg {
253
+ width: 18px;
254
+ height: 18px;
255
+ }
256
+ }
257
+
258
+ /* Dark mode */
259
+ @media (prefers-color-scheme: dark) {
260
+ :host {
261
+ --bb-bg-color: ${THEME.gray[900]};
262
+ }
263
+
264
+ .history {
265
+ background-color: transparent;
266
+ /* Firefox scrollbar dark mode */
267
+ scrollbar-color: ${THEME.gray[600]} transparent;
268
+ }
269
+
270
+ .history::-webkit-scrollbar-thumb {
271
+ background: ${THEME.gray[600]};
272
+ }
273
+
274
+ .history::-webkit-scrollbar-thumb:hover {
275
+ background: ${THEME.gray[500]};
276
+ }
277
+
278
+ .msg-bubble {
279
+ color: ${THEME.gray[100]};
280
+ }
281
+
282
+ .msg-bubble--left {
283
+ background-color: ${THEME.gray[700]};
284
+ color: ${THEME.gray[100]};
285
+ }
286
+
287
+ .avatar-wrapper {
288
+ background: ${THEME.gray[800]};
289
+ }
290
+
291
+ .empty-state {
292
+ color: ${THEME.gray[500]};
293
+ }
294
+
295
+ .scroll-to-bottom {
296
+ background: transparent;
297
+ border: none;
298
+ color: ${THEME.gray[400]};
299
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
300
+ }
301
+
302
+ .scroll-to-bottom:hover {
303
+ color: ${THEME.gray[300]};
304
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
305
+ }
306
+ }
307
+
308
+ /* Reduced motion */
309
+ @media (prefers-reduced-motion: reduce) {
310
+ .history {
311
+ scroll-behavior: auto;
312
+ }
313
+
314
+ .scroll-to-bottom {
315
+ transition: opacity 0.15s ease, visibility 0.15s ease;
316
+ transform: translateX(-50%);
317
+ }
318
+
319
+ .scroll-to-bottom.visible {
320
+ transform: translateX(-50%);
321
+ }
322
+
323
+ .scroll-to-bottom:hover {
324
+ transform: translateX(-50%);
325
+ }
326
+
327
+ .scroll-to-bottom:active {
328
+ transform: translateX(-50%);
329
+ }
330
+ }
331
+ `;
332
+
333
+ /**
334
+ * Empty state styles
335
+ */
336
+ export const EMPTY_STYLES = `
337
+ :host { display: block; }
338
+ .empty-state {
339
+ text-align: center;
340
+ padding: 2rem;
341
+ color: ${THEME.gray[400]};
342
+ font-size: 0.875rem;
343
+ font-family: inherit;
344
+ }
345
+ `;
346
+
347
+ /**
348
+ * Fallback styles for when custom elements are not supported
349
+ */
350
+ export const FALLBACK_STYLES = `
351
+ background: ${THEME.gray[100]};
352
+ padding: 1rem;
353
+ border-radius: 0.5rem;
354
+ overflow-x: auto;
355
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
356
+ font-size: 0.875rem;
357
+ line-height: 1.5;
358
+ color: ${THEME.gray[900]};
359
+ margin: 0;
360
+ white-space: pre-wrap;
361
+ word-wrap: break-word;
362
+ border: 1px solid ${THEME.gray[200]};
363
+ `;
@@ -0,0 +1,34 @@
1
+ import type { Theme } from '../types/index.js';
2
+
3
+ /**
4
+ * Theme color palette
5
+ * Based on Tailwind-like gray scale and custom pink colors
6
+ */
7
+ export const THEME: Theme = {
8
+ gray: {
9
+ 50: '#f9fafb',
10
+ 100: '#f3f4f6',
11
+ 200: '#e5e7eb',
12
+ 300: '#d1d5db',
13
+ 400: '#9ca3af',
14
+ 500: '#6b7280',
15
+ 600: '#4b5563',
16
+ 700: '#374151',
17
+ 800: '#1f2937',
18
+ 900: '#111827',
19
+ },
20
+ red: {
21
+ 50: '#fef2f2',
22
+ 100: '#fee2e2',
23
+ 200: '#fecaca',
24
+ 300: '#fca5a5',
25
+ 400: '#f87171',
26
+ 500: '#ef4444',
27
+ 600: '#dc2626',
28
+ },
29
+ yyPink: {
30
+ 50: '#fdf4f4',
31
+ 100: '#fbd1d2',
32
+ 150: '#f8babc',
33
+ }
34
+ };