tacel-chat 1.2.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 +1435 -0
- package/chat-api.js +436 -0
- package/chat-sync.js +65 -0
- package/chat.css +2573 -0
- package/chat.js +834 -0
- package/components/attachment.js +400 -0
- package/components/confirm.js +125 -0
- package/components/context-menu.js +461 -0
- package/components/files-panel.js +228 -0
- package/components/mention.js +198 -0
- package/components/message-area.js +612 -0
- package/components/message.js +200 -0
- package/components/new-chat.js +130 -0
- package/components/pinned-panel.js +184 -0
- package/components/presence.js +45 -0
- package/components/search-panel.js +201 -0
- package/components/sidebar.js +278 -0
- package/components/tabs.js +130 -0
- package/index.js +12 -0
- package/package.json +41 -0
- package/themes.js +495 -0
- package/utils/dom.js +75 -0
- package/utils/format.js +133 -0
- package/utils/linkify.js +80 -0
package/themes.js
ADDED
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in preset themes for the Tacel Chat Module.
|
|
3
|
+
* 30 themes — light, dark, colorful, professional, and app-specific palettes.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* // Use a preset by name
|
|
7
|
+
* chat.initialize(container, { theme: 'dark' });
|
|
8
|
+
*
|
|
9
|
+
* // Extend a preset with overrides
|
|
10
|
+
* const { themes } = require('tacel-chat');
|
|
11
|
+
* chat.initialize(container, {
|
|
12
|
+
* theme: { ...themes.dark, '--chat-accent': '#ff6600' }
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* // Fully custom (object of CSS variables)
|
|
16
|
+
* chat.initialize(container, { theme: { '--chat-bg': '#111', ... } });
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
function _t(o) {
|
|
20
|
+
const a = o.accent;
|
|
21
|
+
const ar = _hex2rgb(a);
|
|
22
|
+
return {
|
|
23
|
+
'--chat-bg': o.bg,
|
|
24
|
+
'--chat-sidebar-bg': o.sidebarBg || o.bg,
|
|
25
|
+
'--chat-border': o.border,
|
|
26
|
+
'--chat-shadow': o.shadow || '0 2px 8px rgba(0,0,0,0.08)',
|
|
27
|
+
'--chat-text': o.text,
|
|
28
|
+
'--chat-text-secondary': o.textSec,
|
|
29
|
+
'--chat-text-muted': o.textMuted,
|
|
30
|
+
'--chat-accent': a,
|
|
31
|
+
'--chat-accent-transparent': o.accentT || `rgba(${ar}, 0.1)`,
|
|
32
|
+
'--chat-accent-gradient': o.accentGrad || `linear-gradient(135deg, ${a}, ${o.accentDark || a})`,
|
|
33
|
+
'--chat-own-bubble-bg': o.ownBg || `rgba(${ar}, 0.1)`,
|
|
34
|
+
'--chat-own-bubble-border': o.ownBorder || `rgba(${ar}, 0.2)`,
|
|
35
|
+
'--chat-own-bubble-text': o.ownText || o.text,
|
|
36
|
+
'--chat-other-bubble-bg': o.otherBg || 'rgba(0,0,0,0.03)',
|
|
37
|
+
'--chat-other-bubble-border': o.otherBorder || 'rgba(0,0,0,0.08)',
|
|
38
|
+
'--chat-other-bubble-text': o.otherText || o.text,
|
|
39
|
+
'--chat-date-divider-bg': o.dividerBg || 'rgba(0,0,0,0.03)',
|
|
40
|
+
'--chat-date-divider-text': o.dividerText || a,
|
|
41
|
+
'--chat-date-divider-border': o.dividerBorder || o.border,
|
|
42
|
+
'--chat-avatar-bg': o.avatarBg || `rgba(${ar}, 0.1)`,
|
|
43
|
+
'--chat-avatar-text': o.avatarText || a,
|
|
44
|
+
'--chat-avatar-team-bg': o.avatarTeamBg || `rgba(${ar}, 0.15)`,
|
|
45
|
+
'--chat-online-color': o.online || '#4caf50',
|
|
46
|
+
'--chat-online-glow': o.onlineGlow || 'rgba(76,175,80,0.3)',
|
|
47
|
+
'--chat-offline-color': o.offline || 'rgba(0,0,0,0.3)',
|
|
48
|
+
'--chat-unread-bg': o.unreadBg || a,
|
|
49
|
+
'--chat-unread-text': o.unreadText || '#ffffff',
|
|
50
|
+
'--chat-input-bg': o.inputBg || 'rgba(0,0,0,0.02)',
|
|
51
|
+
'--chat-input-border': o.inputBorder || o.border,
|
|
52
|
+
'--chat-input-focus-border': o.inputFocus || a,
|
|
53
|
+
'--chat-send-bg': o.sendBg || o.accentGrad || `linear-gradient(135deg, ${a}, ${o.accentDark || a})`,
|
|
54
|
+
'--chat-send-text': o.sendText || '#ffffff',
|
|
55
|
+
'--chat-seen-color': o.seenColor || a,
|
|
56
|
+
'--chat-mention-bg': o.mentionBg || `rgba(${ar}, 0.15)`,
|
|
57
|
+
'--chat-mention-text': o.mentionText || a,
|
|
58
|
+
'--chat-mention-self-bg': o.mentionSelfBg || 'rgba(255,193,7,0.25)',
|
|
59
|
+
'--chat-mention-self-text': o.mentionSelfText || '#f57f17',
|
|
60
|
+
'--chat-attachment-bg': o.attachBg || 'rgba(0,0,0,0.04)',
|
|
61
|
+
'--chat-attachment-btn-bg': o.attachBtnBg || '#f0f0f0',
|
|
62
|
+
'--chat-attachment-btn-hover': o.attachBtnHover || '#e0e0e0',
|
|
63
|
+
'--chat-attachment-active-bg': o.attachActiveBg || '#4caf50',
|
|
64
|
+
'--chat-attachment-active-text': o.attachActiveText || '#ffffff',
|
|
65
|
+
'--chat-link-color': o.linkColor || a,
|
|
66
|
+
'--chat-tab-bg': o.tabBg || '#f5f5f5',
|
|
67
|
+
'--chat-tab-active-bg': o.tabActiveBg || o.bg,
|
|
68
|
+
'--chat-tab-active-color': o.tabActiveColor || a,
|
|
69
|
+
'--chat-tab-active-border': o.tabActiveBorder || a,
|
|
70
|
+
'--chat-tab-badge-bg': o.tabBadgeBg || '#ff5252',
|
|
71
|
+
'--chat-tab-badge-text': o.tabBadgeText || '#ffffff',
|
|
72
|
+
'--chat-modal-backdrop': o.modalBackdrop || 'rgba(0,0,0,0.5)',
|
|
73
|
+
'--chat-modal-bg': o.modalBg || o.bg,
|
|
74
|
+
'--chat-modal-shadow': o.modalShadow || '0 8px 32px rgba(0,0,0,0.2)',
|
|
75
|
+
'--chat-spinner-color': o.spinnerColor || a,
|
|
76
|
+
'--chat-spinner-track': o.spinnerTrack || 'rgba(0,0,0,0.08)',
|
|
77
|
+
'--chat-error-color': o.errorColor || '#e74c3c',
|
|
78
|
+
'--chat-current-user-bg': o.currentUserBg || `rgba(${ar}, 0.08)`,
|
|
79
|
+
'--chat-current-user-border': o.currentUserBorder || `rgba(${ar}, 0.15)`,
|
|
80
|
+
'--chat-current-user-avatar': o.currentUserAvatar || '#27ae60',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function _hex2rgb(hex) {
|
|
85
|
+
hex = hex.replace('#', '');
|
|
86
|
+
if (hex.length === 3) hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
|
|
87
|
+
const n = parseInt(hex, 16);
|
|
88
|
+
return `${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const THEMES = {
|
|
92
|
+
|
|
93
|
+
// ════════════════════════════════════════════
|
|
94
|
+
// 1. DEFAULT — CSS defaults, no overrides
|
|
95
|
+
// ════════════════════════════════════════════
|
|
96
|
+
default: {},
|
|
97
|
+
|
|
98
|
+
// ════════════════════════════════════════════
|
|
99
|
+
// 2. LIGHT — Clean white
|
|
100
|
+
// ════════════════════════════════════════════
|
|
101
|
+
light: _t({
|
|
102
|
+
bg: '#ffffff', border: 'rgba(0,0,0,0.1)', text: '#333333', textSec: '#666666', textMuted: '#999999',
|
|
103
|
+
accent: '#1976d2', accentDark: '#1565c0',
|
|
104
|
+
}),
|
|
105
|
+
|
|
106
|
+
// ════════════════════════════════════════════
|
|
107
|
+
// 3. DARK — Deep charcoal
|
|
108
|
+
// ════════════════════════════════════════════
|
|
109
|
+
dark: _t({
|
|
110
|
+
bg: '#1e1e2e', sidebarBg: '#181825', border: 'rgba(255,255,255,0.08)',
|
|
111
|
+
shadow: '0 2px 8px rgba(0,0,0,0.3)',
|
|
112
|
+
text: '#e0e0e0', textSec: '#a0a0a0', textMuted: '#666666',
|
|
113
|
+
accent: '#89b4fa', accentDark: '#74a8f7',
|
|
114
|
+
ownBg: 'rgba(137,180,250,0.12)', ownBorder: 'rgba(137,180,250,0.2)', ownText: '#e0e0e0',
|
|
115
|
+
otherBg: 'rgba(255,255,255,0.04)', otherBorder: 'rgba(255,255,255,0.08)', otherText: '#e0e0e0',
|
|
116
|
+
dividerBg: 'rgba(255,255,255,0.04)', dividerBorder: 'rgba(255,255,255,0.08)',
|
|
117
|
+
avatarBg: 'rgba(137,180,250,0.15)',
|
|
118
|
+
offline: 'rgba(255,255,255,0.2)',
|
|
119
|
+
inputBg: 'rgba(255,255,255,0.05)', inputBorder: 'rgba(255,255,255,0.1)',
|
|
120
|
+
attachBg: 'rgba(255,255,255,0.06)', attachBtnBg: 'rgba(255,255,255,0.08)', attachBtnHover: 'rgba(255,255,255,0.12)',
|
|
121
|
+
tabBg: '#181825', tabActiveBg: '#1e1e2e',
|
|
122
|
+
modalBackdrop: 'rgba(0,0,0,0.7)', modalBg: '#1e1e2e', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
123
|
+
spinnerTrack: 'rgba(255,255,255,0.08)',
|
|
124
|
+
currentUserBg: 'rgba(137,180,250,0.08)', currentUserBorder: 'rgba(137,180,250,0.15)', currentUserAvatar: '#a6e3a1',
|
|
125
|
+
}),
|
|
126
|
+
|
|
127
|
+
// ════════════════════════════════════════════
|
|
128
|
+
// 4. MIDNIGHT — Deep blue-black
|
|
129
|
+
// ════════════════════════════════════════════
|
|
130
|
+
midnight: _t({
|
|
131
|
+
bg: '#0f0f1a', sidebarBg: '#0a0a14', border: 'rgba(100,120,200,0.15)',
|
|
132
|
+
shadow: '0 2px 8px rgba(0,0,0,0.4)',
|
|
133
|
+
text: '#c8cdf0', textSec: '#8890b5', textMuted: '#555a7a',
|
|
134
|
+
accent: '#6c7bd4', accentDark: '#5a69c0',
|
|
135
|
+
ownBg: 'rgba(108,123,212,0.15)', ownBorder: 'rgba(108,123,212,0.25)', ownText: '#c8cdf0',
|
|
136
|
+
otherBg: 'rgba(255,255,255,0.03)', otherBorder: 'rgba(100,120,200,0.1)', otherText: '#c8cdf0',
|
|
137
|
+
dividerBg: 'rgba(100,120,200,0.06)', dividerBorder: 'rgba(100,120,200,0.1)',
|
|
138
|
+
offline: 'rgba(200,205,240,0.2)',
|
|
139
|
+
inputBg: 'rgba(100,120,200,0.06)', inputBorder: 'rgba(100,120,200,0.15)',
|
|
140
|
+
attachBtnBg: 'rgba(100,120,200,0.1)', attachBtnHover: 'rgba(100,120,200,0.18)',
|
|
141
|
+
tabBg: '#0a0a14', tabActiveBg: '#0f0f1a',
|
|
142
|
+
modalBackdrop: 'rgba(0,0,0,0.75)', modalBg: '#0f0f1a', modalShadow: '0 8px 32px rgba(0,0,0,0.6)',
|
|
143
|
+
spinnerTrack: 'rgba(100,120,200,0.1)',
|
|
144
|
+
}),
|
|
145
|
+
|
|
146
|
+
// ════════════════════════════════════════════
|
|
147
|
+
// 5. OCEAN — Teal/cyan
|
|
148
|
+
// ════════════════════════════════════════════
|
|
149
|
+
ocean: _t({
|
|
150
|
+
bg: '#f0fafa', sidebarBg: '#e8f6f6', border: 'rgba(0,150,136,0.15)',
|
|
151
|
+
text: '#1a3a3a', textSec: '#3a6a6a', textMuted: '#7a9a9a',
|
|
152
|
+
accent: '#00897b', accentDark: '#00796b',
|
|
153
|
+
}),
|
|
154
|
+
|
|
155
|
+
// ════════════════════════════════════════════
|
|
156
|
+
// 6. FOREST — Deep green
|
|
157
|
+
// ════════════════════════════════════════════
|
|
158
|
+
forest: _t({
|
|
159
|
+
bg: '#f2f7f2', sidebarBg: '#e8f0e8', border: 'rgba(46,125,50,0.15)',
|
|
160
|
+
text: '#1b3a1b', textSec: '#3a6a3a', textMuted: '#7a9a7a',
|
|
161
|
+
accent: '#2e7d32', accentDark: '#1b5e20',
|
|
162
|
+
}),
|
|
163
|
+
|
|
164
|
+
// ════════════════════════════════════════════
|
|
165
|
+
// 7. SUNSET — Warm orange/red
|
|
166
|
+
// ════════════════════════════════════════════
|
|
167
|
+
sunset: _t({
|
|
168
|
+
bg: '#fff8f0', sidebarBg: '#fff3e8', border: 'rgba(230,81,0,0.12)',
|
|
169
|
+
text: '#3a2010', textSec: '#6a4a30', textMuted: '#9a7a60',
|
|
170
|
+
accent: '#e65100', accentDark: '#bf360c',
|
|
171
|
+
online: '#66bb6a',
|
|
172
|
+
}),
|
|
173
|
+
|
|
174
|
+
// ════════════════════════════════════════════
|
|
175
|
+
// 8. ROSE — Pink/magenta
|
|
176
|
+
// ════════════════════════════════════════════
|
|
177
|
+
rose: _t({
|
|
178
|
+
bg: '#fff5f8', sidebarBg: '#ffeef3', border: 'rgba(194,24,91,0.12)',
|
|
179
|
+
text: '#3a1020', textSec: '#6a3050', textMuted: '#9a6080',
|
|
180
|
+
accent: '#c2185b', accentDark: '#ad1457',
|
|
181
|
+
}),
|
|
182
|
+
|
|
183
|
+
// ════════════════════════════════════════════
|
|
184
|
+
// 9. LAVENDER — Soft purple
|
|
185
|
+
// ════════════════════════════════════════════
|
|
186
|
+
lavender: _t({
|
|
187
|
+
bg: '#f8f5ff', sidebarBg: '#f0eaff', border: 'rgba(103,58,183,0.12)',
|
|
188
|
+
text: '#2a1a40', textSec: '#5a3a80', textMuted: '#8a6ab0',
|
|
189
|
+
accent: '#673ab7', accentDark: '#5e35b1',
|
|
190
|
+
}),
|
|
191
|
+
|
|
192
|
+
// ════════════════════════════════════════════
|
|
193
|
+
// 10. SLATE — Neutral gray
|
|
194
|
+
// ════════════════════════════════════════════
|
|
195
|
+
slate: _t({
|
|
196
|
+
bg: '#f8f9fa', sidebarBg: '#f1f3f5', border: 'rgba(0,0,0,0.1)',
|
|
197
|
+
text: '#212529', textSec: '#495057', textMuted: '#868e96',
|
|
198
|
+
accent: '#495057', accentDark: '#343a40',
|
|
199
|
+
}),
|
|
200
|
+
|
|
201
|
+
// ════════════════════════════════════════════
|
|
202
|
+
// 11. NORD — Nord color palette
|
|
203
|
+
// ════════════════════════════════════════════
|
|
204
|
+
nord: _t({
|
|
205
|
+
bg: '#2e3440', sidebarBg: '#282e3a', border: 'rgba(216,222,233,0.1)',
|
|
206
|
+
shadow: '0 2px 8px rgba(0,0,0,0.3)',
|
|
207
|
+
text: '#d8dee9', textSec: '#a0aec0', textMuted: '#616e88',
|
|
208
|
+
accent: '#88c0d0', accentDark: '#81a1c1',
|
|
209
|
+
ownBg: 'rgba(136,192,208,0.12)', ownBorder: 'rgba(136,192,208,0.2)', ownText: '#d8dee9',
|
|
210
|
+
otherBg: 'rgba(216,222,233,0.04)', otherBorder: 'rgba(216,222,233,0.08)', otherText: '#d8dee9',
|
|
211
|
+
dividerBg: 'rgba(216,222,233,0.04)', dividerBorder: 'rgba(216,222,233,0.08)',
|
|
212
|
+
offline: 'rgba(216,222,233,0.2)',
|
|
213
|
+
inputBg: 'rgba(216,222,233,0.05)', inputBorder: 'rgba(216,222,233,0.1)',
|
|
214
|
+
attachBtnBg: 'rgba(216,222,233,0.08)', attachBtnHover: 'rgba(216,222,233,0.12)',
|
|
215
|
+
tabBg: '#282e3a', tabActiveBg: '#2e3440',
|
|
216
|
+
modalBackdrop: 'rgba(0,0,0,0.7)', modalBg: '#2e3440', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
217
|
+
spinnerTrack: 'rgba(216,222,233,0.08)',
|
|
218
|
+
currentUserAvatar: '#a3be8c',
|
|
219
|
+
}),
|
|
220
|
+
|
|
221
|
+
// ════════════════════════════════════════════
|
|
222
|
+
// 12. DRACULA — Dracula color palette
|
|
223
|
+
// ════════════════════════════════════════════
|
|
224
|
+
dracula: _t({
|
|
225
|
+
bg: '#282a36', sidebarBg: '#21222c', border: 'rgba(248,248,242,0.08)',
|
|
226
|
+
shadow: '0 2px 8px rgba(0,0,0,0.3)',
|
|
227
|
+
text: '#f8f8f2', textSec: '#bfbfb8', textMuted: '#6272a4',
|
|
228
|
+
accent: '#bd93f9', accentDark: '#a87de8',
|
|
229
|
+
ownBg: 'rgba(189,147,249,0.12)', ownBorder: 'rgba(189,147,249,0.2)', ownText: '#f8f8f2',
|
|
230
|
+
otherBg: 'rgba(248,248,242,0.04)', otherBorder: 'rgba(248,248,242,0.08)', otherText: '#f8f8f2',
|
|
231
|
+
dividerBg: 'rgba(248,248,242,0.04)', dividerBorder: 'rgba(248,248,242,0.08)',
|
|
232
|
+
offline: 'rgba(248,248,242,0.2)',
|
|
233
|
+
inputBg: 'rgba(248,248,242,0.05)', inputBorder: 'rgba(248,248,242,0.1)',
|
|
234
|
+
attachBtnBg: 'rgba(248,248,242,0.08)', attachBtnHover: 'rgba(248,248,242,0.12)',
|
|
235
|
+
tabBg: '#21222c', tabActiveBg: '#282a36',
|
|
236
|
+
modalBackdrop: 'rgba(0,0,0,0.7)', modalBg: '#282a36', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
237
|
+
spinnerTrack: 'rgba(248,248,242,0.08)',
|
|
238
|
+
online: '#50fa7b', currentUserAvatar: '#50fa7b',
|
|
239
|
+
mentionSelfBg: 'rgba(255,184,108,0.25)', mentionSelfText: '#ffb86c',
|
|
240
|
+
}),
|
|
241
|
+
|
|
242
|
+
// ════════════════════════════════════════════
|
|
243
|
+
// 13. MONOKAI — Monokai-inspired
|
|
244
|
+
// ════════════════════════════════════════════
|
|
245
|
+
monokai: _t({
|
|
246
|
+
bg: '#272822', sidebarBg: '#1e1f1a', border: 'rgba(248,248,240,0.08)',
|
|
247
|
+
shadow: '0 2px 8px rgba(0,0,0,0.3)',
|
|
248
|
+
text: '#f8f8f0', textSec: '#b8b8a8', textMuted: '#75715e',
|
|
249
|
+
accent: '#a6e22e', accentDark: '#8cc220',
|
|
250
|
+
ownBg: 'rgba(166,226,46,0.1)', ownBorder: 'rgba(166,226,46,0.2)', ownText: '#f8f8f0',
|
|
251
|
+
otherBg: 'rgba(248,248,240,0.04)', otherBorder: 'rgba(248,248,240,0.08)', otherText: '#f8f8f0',
|
|
252
|
+
dividerBg: 'rgba(248,248,240,0.04)', dividerBorder: 'rgba(248,248,240,0.08)',
|
|
253
|
+
offline: 'rgba(248,248,240,0.2)',
|
|
254
|
+
inputBg: 'rgba(248,248,240,0.05)', inputBorder: 'rgba(248,248,240,0.1)',
|
|
255
|
+
attachBtnBg: 'rgba(248,248,240,0.08)', attachBtnHover: 'rgba(248,248,240,0.12)',
|
|
256
|
+
tabBg: '#1e1f1a', tabActiveBg: '#272822',
|
|
257
|
+
modalBackdrop: 'rgba(0,0,0,0.7)', modalBg: '#272822', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
258
|
+
spinnerTrack: 'rgba(248,248,240,0.08)',
|
|
259
|
+
online: '#a6e22e', currentUserAvatar: '#a6e22e',
|
|
260
|
+
linkColor: '#66d9ef',
|
|
261
|
+
}),
|
|
262
|
+
|
|
263
|
+
// ════════════════════════════════════════════
|
|
264
|
+
// 14. SOLARIZED LIGHT
|
|
265
|
+
// ════════════════════════════════════════════
|
|
266
|
+
'solarized-light': _t({
|
|
267
|
+
bg: '#fdf6e3', sidebarBg: '#eee8d5', border: 'rgba(88,110,117,0.15)',
|
|
268
|
+
text: '#586e75', textSec: '#657b83', textMuted: '#93a1a1',
|
|
269
|
+
accent: '#268bd2', accentDark: '#2176b8',
|
|
270
|
+
}),
|
|
271
|
+
|
|
272
|
+
// ════════════════════════════════════════════
|
|
273
|
+
// 15. SOLARIZED DARK
|
|
274
|
+
// ════════════════════════════════════════════
|
|
275
|
+
'solarized-dark': _t({
|
|
276
|
+
bg: '#002b36', sidebarBg: '#073642', border: 'rgba(147,161,161,0.12)',
|
|
277
|
+
shadow: '0 2px 8px rgba(0,0,0,0.4)',
|
|
278
|
+
text: '#839496', textSec: '#93a1a1', textMuted: '#586e75',
|
|
279
|
+
accent: '#268bd2', accentDark: '#2176b8',
|
|
280
|
+
ownBg: 'rgba(38,139,210,0.12)', ownBorder: 'rgba(38,139,210,0.2)', ownText: '#93a1a1',
|
|
281
|
+
otherBg: 'rgba(147,161,161,0.04)', otherBorder: 'rgba(147,161,161,0.08)', otherText: '#93a1a1',
|
|
282
|
+
dividerBg: 'rgba(147,161,161,0.04)', dividerBorder: 'rgba(147,161,161,0.08)',
|
|
283
|
+
offline: 'rgba(147,161,161,0.2)',
|
|
284
|
+
inputBg: 'rgba(147,161,161,0.05)', inputBorder: 'rgba(147,161,161,0.1)',
|
|
285
|
+
attachBtnBg: 'rgba(147,161,161,0.08)', attachBtnHover: 'rgba(147,161,161,0.12)',
|
|
286
|
+
tabBg: '#073642', tabActiveBg: '#002b36',
|
|
287
|
+
modalBackdrop: 'rgba(0,0,0,0.7)', modalBg: '#002b36', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
288
|
+
spinnerTrack: 'rgba(147,161,161,0.08)',
|
|
289
|
+
online: '#859900', currentUserAvatar: '#859900',
|
|
290
|
+
}),
|
|
291
|
+
|
|
292
|
+
// ════════════════════════════════════════════
|
|
293
|
+
// 16. CATPPUCCIN MOCHA
|
|
294
|
+
// ════════════════════════════════════════════
|
|
295
|
+
'catppuccin-mocha': _t({
|
|
296
|
+
bg: '#1e1e2e', sidebarBg: '#181825', border: 'rgba(205,214,244,0.08)',
|
|
297
|
+
shadow: '0 2px 8px rgba(0,0,0,0.3)',
|
|
298
|
+
text: '#cdd6f4', textSec: '#a6adc8', textMuted: '#585b70',
|
|
299
|
+
accent: '#cba6f7', accentDark: '#b490e0',
|
|
300
|
+
ownBg: 'rgba(203,166,247,0.1)', ownBorder: 'rgba(203,166,247,0.2)', ownText: '#cdd6f4',
|
|
301
|
+
otherBg: 'rgba(205,214,244,0.04)', otherBorder: 'rgba(205,214,244,0.08)', otherText: '#cdd6f4',
|
|
302
|
+
dividerBg: 'rgba(205,214,244,0.04)', dividerBorder: 'rgba(205,214,244,0.08)',
|
|
303
|
+
offline: 'rgba(205,214,244,0.2)',
|
|
304
|
+
inputBg: 'rgba(205,214,244,0.05)', inputBorder: 'rgba(205,214,244,0.1)',
|
|
305
|
+
attachBtnBg: 'rgba(205,214,244,0.08)', attachBtnHover: 'rgba(205,214,244,0.12)',
|
|
306
|
+
tabBg: '#181825', tabActiveBg: '#1e1e2e',
|
|
307
|
+
modalBackdrop: 'rgba(0,0,0,0.7)', modalBg: '#1e1e2e', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
308
|
+
spinnerTrack: 'rgba(205,214,244,0.08)',
|
|
309
|
+
online: '#a6e3a1', currentUserAvatar: '#a6e3a1',
|
|
310
|
+
}),
|
|
311
|
+
|
|
312
|
+
// ════════════════════════════════════════════
|
|
313
|
+
// 17. CATPPUCCIN LATTE
|
|
314
|
+
// ════════════════════════════════════════════
|
|
315
|
+
'catppuccin-latte': _t({
|
|
316
|
+
bg: '#eff1f5', sidebarBg: '#e6e9ef', border: 'rgba(76,79,105,0.12)',
|
|
317
|
+
text: '#4c4f69', textSec: '#6c6f85', textMuted: '#9ca0b0',
|
|
318
|
+
accent: '#8839ef', accentDark: '#7629d9',
|
|
319
|
+
}),
|
|
320
|
+
|
|
321
|
+
// ════════════════════════════════════════════
|
|
322
|
+
// 18. GITHUB LIGHT
|
|
323
|
+
// ════════════════════════════════════════════
|
|
324
|
+
'github-light': _t({
|
|
325
|
+
bg: '#ffffff', sidebarBg: '#f6f8fa', border: 'rgba(31,35,40,0.1)',
|
|
326
|
+
text: '#1f2328', textSec: '#59636e', textMuted: '#8b949e',
|
|
327
|
+
accent: '#0969da', accentDark: '#0550ae',
|
|
328
|
+
}),
|
|
329
|
+
|
|
330
|
+
// ════════════════════════════════════════════
|
|
331
|
+
// 19. GITHUB DARK
|
|
332
|
+
// ════════════════════════════════════════════
|
|
333
|
+
'github-dark': _t({
|
|
334
|
+
bg: '#0d1117', sidebarBg: '#010409', border: 'rgba(139,148,158,0.12)',
|
|
335
|
+
shadow: '0 2px 8px rgba(0,0,0,0.4)',
|
|
336
|
+
text: '#e6edf3', textSec: '#8b949e', textMuted: '#484f58',
|
|
337
|
+
accent: '#58a6ff', accentDark: '#4090e0',
|
|
338
|
+
ownBg: 'rgba(88,166,255,0.1)', ownBorder: 'rgba(88,166,255,0.2)', ownText: '#e6edf3',
|
|
339
|
+
otherBg: 'rgba(139,148,158,0.04)', otherBorder: 'rgba(139,148,158,0.08)', otherText: '#e6edf3',
|
|
340
|
+
dividerBg: 'rgba(139,148,158,0.04)', dividerBorder: 'rgba(139,148,158,0.08)',
|
|
341
|
+
offline: 'rgba(139,148,158,0.2)',
|
|
342
|
+
inputBg: 'rgba(139,148,158,0.05)', inputBorder: 'rgba(139,148,158,0.1)',
|
|
343
|
+
attachBtnBg: 'rgba(139,148,158,0.08)', attachBtnHover: 'rgba(139,148,158,0.12)',
|
|
344
|
+
tabBg: '#010409', tabActiveBg: '#0d1117',
|
|
345
|
+
modalBackdrop: 'rgba(0,0,0,0.7)', modalBg: '#0d1117', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
346
|
+
spinnerTrack: 'rgba(139,148,158,0.08)',
|
|
347
|
+
online: '#3fb950', currentUserAvatar: '#3fb950',
|
|
348
|
+
}),
|
|
349
|
+
|
|
350
|
+
// ════════════════════════════════════════════
|
|
351
|
+
// 20. OFFICE-HQ GOLD — Tacel Office-HQ theme
|
|
352
|
+
// ════════════════════════════════════════════
|
|
353
|
+
'office-hq': _t({
|
|
354
|
+
bg: '#ffffff', sidebarBg: '#faf8f0', border: 'rgba(201,162,39,0.15)',
|
|
355
|
+
text: '#3d3520', textSec: '#6a5a30', textMuted: '#8a7d5a',
|
|
356
|
+
accent: '#c9a227', accentDark: '#b8922a',
|
|
357
|
+
}),
|
|
358
|
+
|
|
359
|
+
// ════════════════════════════════════════════
|
|
360
|
+
// 21. SHIPWORKS BLUE — Tacel ShipWorks theme
|
|
361
|
+
// ════════════════════════════════════════════
|
|
362
|
+
shipworks: _t({
|
|
363
|
+
bg: '#ffffff', sidebarBg: '#f0f5ff', border: 'rgba(25,118,210,0.12)',
|
|
364
|
+
text: '#1a2a40', textSec: '#3a5a80', textMuted: '#6a8ab0',
|
|
365
|
+
accent: '#1976d2', accentDark: '#1565c0',
|
|
366
|
+
}),
|
|
367
|
+
|
|
368
|
+
// ════════════════════════════════════════════
|
|
369
|
+
// 22. TECH-PORTAL — Tacel Tech-Portal dark theme
|
|
370
|
+
// ════════════════════════════════════════════
|
|
371
|
+
'tech-portal': _t({
|
|
372
|
+
bg: '#1a1a2e', sidebarBg: '#16213e', border: 'rgba(83,193,222,0.12)',
|
|
373
|
+
shadow: '0 2px 8px rgba(0,0,0,0.3)',
|
|
374
|
+
text: '#e0e0e0', textSec: '#a0a0a0', textMuted: '#606060',
|
|
375
|
+
accent: '#53c1de', accentDark: '#40a8c4',
|
|
376
|
+
ownBg: 'rgba(83,193,222,0.1)', ownBorder: 'rgba(83,193,222,0.2)', ownText: '#e0e0e0',
|
|
377
|
+
otherBg: 'rgba(255,255,255,0.04)', otherBorder: 'rgba(255,255,255,0.08)', otherText: '#e0e0e0',
|
|
378
|
+
dividerBg: 'rgba(255,255,255,0.04)', dividerBorder: 'rgba(255,255,255,0.08)',
|
|
379
|
+
offline: 'rgba(255,255,255,0.2)',
|
|
380
|
+
inputBg: 'rgba(255,255,255,0.05)', inputBorder: 'rgba(83,193,222,0.15)',
|
|
381
|
+
attachBtnBg: 'rgba(255,255,255,0.08)', attachBtnHover: 'rgba(255,255,255,0.12)',
|
|
382
|
+
tabBg: '#16213e', tabActiveBg: '#1a1a2e',
|
|
383
|
+
modalBackdrop: 'rgba(0,0,0,0.7)', modalBg: '#1a1a2e', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
384
|
+
spinnerTrack: 'rgba(255,255,255,0.08)',
|
|
385
|
+
online: '#4caf50', currentUserAvatar: '#4caf50',
|
|
386
|
+
}),
|
|
387
|
+
|
|
388
|
+
// ════════════════════════════════════════════
|
|
389
|
+
// 23. CORAL — Warm coral/salmon
|
|
390
|
+
// ════════════════════════════════════════════
|
|
391
|
+
coral: _t({
|
|
392
|
+
bg: '#fff5f3', sidebarBg: '#ffefeb', border: 'rgba(255,87,51,0.12)',
|
|
393
|
+
text: '#3a1a10', textSec: '#6a3a28', textMuted: '#9a6a58',
|
|
394
|
+
accent: '#ff5733', accentDark: '#e04828',
|
|
395
|
+
}),
|
|
396
|
+
|
|
397
|
+
// ════════════════════════════════════════════
|
|
398
|
+
// 24. MINT — Fresh mint green
|
|
399
|
+
// ════════════════════════════════════════════
|
|
400
|
+
mint: _t({
|
|
401
|
+
bg: '#f0fff4', sidebarBg: '#e0f8e8', border: 'rgba(0,200,83,0.12)',
|
|
402
|
+
text: '#1a3a20', textSec: '#3a6a40', textMuted: '#6a9a70',
|
|
403
|
+
accent: '#00c853', accentDark: '#00a844',
|
|
404
|
+
}),
|
|
405
|
+
|
|
406
|
+
// ════════════════════════════════════════════
|
|
407
|
+
// 25. AMBER — Warm amber/honey
|
|
408
|
+
// ════════════════════════════════════════════
|
|
409
|
+
amber: _t({
|
|
410
|
+
bg: '#fffbf0', sidebarBg: '#fff8e1', border: 'rgba(255,160,0,0.12)',
|
|
411
|
+
text: '#3a2800', textSec: '#6a4a10', textMuted: '#9a7a40',
|
|
412
|
+
accent: '#ffa000', accentDark: '#ff8f00',
|
|
413
|
+
unreadText: '#3a2800',
|
|
414
|
+
}),
|
|
415
|
+
|
|
416
|
+
// ════════════════════════════════════════════
|
|
417
|
+
// 26. INDIGO — Deep indigo
|
|
418
|
+
// ════════════════════════════════════════════
|
|
419
|
+
indigo: _t({
|
|
420
|
+
bg: '#f5f5ff', sidebarBg: '#ececff', border: 'rgba(48,63,159,0.12)',
|
|
421
|
+
text: '#1a1a40', textSec: '#3a3a70', textMuted: '#6a6aa0',
|
|
422
|
+
accent: '#303f9f', accentDark: '#283593',
|
|
423
|
+
}),
|
|
424
|
+
|
|
425
|
+
// ════════════════════════════════════════════
|
|
426
|
+
// 27. ABYSS — Very dark blue
|
|
427
|
+
// ════════════════════════════════════════════
|
|
428
|
+
abyss: _t({
|
|
429
|
+
bg: '#060818', sidebarBg: '#040610', border: 'rgba(80,100,180,0.12)',
|
|
430
|
+
shadow: '0 2px 8px rgba(0,0,0,0.5)',
|
|
431
|
+
text: '#b0b8d8', textSec: '#7880a0', textMuted: '#484e6a',
|
|
432
|
+
accent: '#4fc3f7', accentDark: '#39aee0',
|
|
433
|
+
ownBg: 'rgba(79,195,247,0.1)', ownBorder: 'rgba(79,195,247,0.2)', ownText: '#b0b8d8',
|
|
434
|
+
otherBg: 'rgba(80,100,180,0.05)', otherBorder: 'rgba(80,100,180,0.1)', otherText: '#b0b8d8',
|
|
435
|
+
dividerBg: 'rgba(80,100,180,0.05)', dividerBorder: 'rgba(80,100,180,0.1)',
|
|
436
|
+
offline: 'rgba(176,184,216,0.2)',
|
|
437
|
+
inputBg: 'rgba(80,100,180,0.06)', inputBorder: 'rgba(80,100,180,0.12)',
|
|
438
|
+
attachBtnBg: 'rgba(80,100,180,0.08)', attachBtnHover: 'rgba(80,100,180,0.14)',
|
|
439
|
+
tabBg: '#040610', tabActiveBg: '#060818',
|
|
440
|
+
modalBackdrop: 'rgba(0,0,0,0.8)', modalBg: '#060818', modalShadow: '0 8px 32px rgba(0,0,0,0.6)',
|
|
441
|
+
spinnerTrack: 'rgba(80,100,180,0.1)',
|
|
442
|
+
}),
|
|
443
|
+
|
|
444
|
+
// ════════════════════════════════════════════
|
|
445
|
+
// 28. CREAM — Warm off-white
|
|
446
|
+
// ════════════════════════════════════════════
|
|
447
|
+
cream: _t({
|
|
448
|
+
bg: '#fefcf3', sidebarBg: '#f8f4e8', border: 'rgba(139,119,80,0.15)',
|
|
449
|
+
text: '#3a3020', textSec: '#6a5a40', textMuted: '#9a8a6a',
|
|
450
|
+
accent: '#8b7750', accentDark: '#7a6840',
|
|
451
|
+
}),
|
|
452
|
+
|
|
453
|
+
// ════════════════════════════════════════════
|
|
454
|
+
// 29. NEON — Bright neon on dark
|
|
455
|
+
// ════════════════════════════════════════════
|
|
456
|
+
neon: _t({
|
|
457
|
+
bg: '#0a0a0a', sidebarBg: '#050505', border: 'rgba(0,255,136,0.12)',
|
|
458
|
+
shadow: '0 2px 8px rgba(0,255,136,0.08)',
|
|
459
|
+
text: '#e0ffe0', textSec: '#a0d0a0', textMuted: '#507050',
|
|
460
|
+
accent: '#00ff88', accentDark: '#00dd77',
|
|
461
|
+
ownBg: 'rgba(0,255,136,0.08)', ownBorder: 'rgba(0,255,136,0.2)', ownText: '#e0ffe0',
|
|
462
|
+
otherBg: 'rgba(0,255,136,0.03)', otherBorder: 'rgba(0,255,136,0.08)', otherText: '#e0ffe0',
|
|
463
|
+
dividerBg: 'rgba(0,255,136,0.04)', dividerBorder: 'rgba(0,255,136,0.08)',
|
|
464
|
+
offline: 'rgba(0,255,136,0.15)',
|
|
465
|
+
inputBg: 'rgba(0,255,136,0.04)', inputBorder: 'rgba(0,255,136,0.12)',
|
|
466
|
+
attachBtnBg: 'rgba(0,255,136,0.06)', attachBtnHover: 'rgba(0,255,136,0.12)',
|
|
467
|
+
tabBg: '#050505', tabActiveBg: '#0a0a0a',
|
|
468
|
+
modalBackdrop: 'rgba(0,0,0,0.8)', modalBg: '#0a0a0a', modalShadow: '0 4px 24px rgba(0,255,136,0.15)',
|
|
469
|
+
spinnerTrack: 'rgba(0,255,136,0.08)',
|
|
470
|
+
online: '#00ff88', currentUserAvatar: '#00ff88',
|
|
471
|
+
sendText: '#0a0a0a',
|
|
472
|
+
}),
|
|
473
|
+
|
|
474
|
+
// ════════════════════════════════════════════
|
|
475
|
+
// 30. CHERRY — Dark red/crimson
|
|
476
|
+
// ════════════════════════════════════════════
|
|
477
|
+
cherry: _t({
|
|
478
|
+
bg: '#1a0a0e', sidebarBg: '#140810', border: 'rgba(220,60,80,0.12)',
|
|
479
|
+
shadow: '0 2px 8px rgba(0,0,0,0.4)',
|
|
480
|
+
text: '#f0d0d5', textSec: '#b08088', textMuted: '#705058',
|
|
481
|
+
accent: '#dc3c50', accentDark: '#c03040',
|
|
482
|
+
ownBg: 'rgba(220,60,80,0.12)', ownBorder: 'rgba(220,60,80,0.2)', ownText: '#f0d0d5',
|
|
483
|
+
otherBg: 'rgba(220,60,80,0.04)', otherBorder: 'rgba(220,60,80,0.08)', otherText: '#f0d0d5',
|
|
484
|
+
dividerBg: 'rgba(220,60,80,0.04)', dividerBorder: 'rgba(220,60,80,0.08)',
|
|
485
|
+
offline: 'rgba(240,208,213,0.2)',
|
|
486
|
+
inputBg: 'rgba(220,60,80,0.05)', inputBorder: 'rgba(220,60,80,0.12)',
|
|
487
|
+
attachBtnBg: 'rgba(220,60,80,0.08)', attachBtnHover: 'rgba(220,60,80,0.14)',
|
|
488
|
+
tabBg: '#140810', tabActiveBg: '#1a0a0e',
|
|
489
|
+
modalBackdrop: 'rgba(0,0,0,0.75)', modalBg: '#1a0a0e', modalShadow: '0 8px 32px rgba(0,0,0,0.5)',
|
|
490
|
+
spinnerTrack: 'rgba(220,60,80,0.1)',
|
|
491
|
+
online: '#ff6b7a', currentUserAvatar: '#ff6b7a',
|
|
492
|
+
}),
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
module.exports = { THEMES };
|
package/utils/dom.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM utility helpers for tacel-chat
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Escape HTML special characters to prevent XSS
|
|
7
|
+
*/
|
|
8
|
+
function escapeHtml(text) {
|
|
9
|
+
if (!text) return '';
|
|
10
|
+
const div = document.createElement('div');
|
|
11
|
+
div.textContent = text;
|
|
12
|
+
return div.innerHTML;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create a DOM element with optional classes, attributes, and children
|
|
17
|
+
*/
|
|
18
|
+
function createElement(tag, options = {}) {
|
|
19
|
+
const el = document.createElement(tag);
|
|
20
|
+
if (options.className) el.className = options.className;
|
|
21
|
+
if (options.id) el.id = options.id;
|
|
22
|
+
if (options.innerHTML) el.innerHTML = options.innerHTML;
|
|
23
|
+
if (options.textContent) el.textContent = options.textContent;
|
|
24
|
+
if (options.style) Object.assign(el.style, options.style);
|
|
25
|
+
if (options.attrs) {
|
|
26
|
+
for (const [key, val] of Object.entries(options.attrs)) {
|
|
27
|
+
el.setAttribute(key, val);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (options.events) {
|
|
31
|
+
for (const [evt, handler] of Object.entries(options.events)) {
|
|
32
|
+
el.addEventListener(evt, handler);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (options.children) {
|
|
36
|
+
for (const child of options.children) {
|
|
37
|
+
if (typeof child === 'string') {
|
|
38
|
+
el.appendChild(document.createTextNode(child));
|
|
39
|
+
} else if (child) {
|
|
40
|
+
el.appendChild(child);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return el;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Check if an element is scrolled near the bottom
|
|
49
|
+
*/
|
|
50
|
+
function isNearBottom(el, threshold = 50) {
|
|
51
|
+
if (!el) return true;
|
|
52
|
+
return el.scrollHeight - el.scrollTop - el.clientHeight < threshold;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Scroll an element to the bottom
|
|
57
|
+
*/
|
|
58
|
+
function scrollToBottom(el) {
|
|
59
|
+
if (!el) return;
|
|
60
|
+
el.scrollTop = el.scrollHeight;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Generate initials from a username (first 1-2 chars)
|
|
65
|
+
*/
|
|
66
|
+
function getInitials(name) {
|
|
67
|
+
if (!name) return '?';
|
|
68
|
+
const parts = name.trim().split(/\s+/);
|
|
69
|
+
if (parts.length >= 2) {
|
|
70
|
+
return (parts[0][0] + parts[1][0]).toUpperCase();
|
|
71
|
+
}
|
|
72
|
+
return name.substring(0, 2).toUpperCase();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = { escapeHtml, createElement, isNearBottom, scrollToBottom, getInitials };
|